]> ocean-lang.org Git - ocean/blobdiff - csrc/oceani.mdc
oceani: don't let error in one statement hides errors in next.
[ocean] / csrc / oceani.mdc
index e16d56fdc80e5444b518cf6b847af34aa30d97dd..f97652d025ca4c90ef8e183ac45bea0eed41a677 100644 (file)
@@ -37,9 +37,9 @@ boolean operators.
 
 Some operators that have only recently been added, and so have not
 generated all that much experience yet are "and then" and "or else" as
-short-circuit Boolean operators, and the "if ... else" trinary
-operator which can select between two expressions based on a third
-(which appears syntactically in the middle).
+short-circuit Boolean operators (which have since been remove), and the
+"if ...  else" trinary operator which can select between two expressions
+based on a third (which appears syntactically in the middle).
 
 The "func" clause currently only allows a "main" function to be
 declared.  That will be extended when proper function support is added.
@@ -1157,7 +1157,7 @@ A separate function encoding these cases will simplify some code later.
        {
                int cmp;
                if (tl != tr)
-                       return tl - tr; // NOTEST
+                       return tl - tr;
                switch (tl->vtype) {
                case Vlabel: cmp = left->label == right->label ? 0 : 1; break;
                case Vnum: cmp = mpq_cmp(left->num, right->num); break;
@@ -2096,7 +2096,7 @@ stack.
                        if (v->merged != v)
                                continue;
                        if (!t)
-                               continue;
+                               continue;       // NOTEST
                        if (v->frame_pos >= 0)
                                continue;
                        while (done && done->scope_end < v->scope_start)
@@ -3552,6 +3552,7 @@ further detailed when Expression Lists are introduced.
 
        static void function_print(struct type *type, struct value *val, FILE *f)
        {
+               fprintf(f, "\n");
                print_exec(val->function, 1, 0);
        }
 
@@ -3585,7 +3586,6 @@ further detailed when Expression Lists are introduced.
                        } else
                                type_print(type->function.return_type, f);
                }
-               fprintf(f, "\n");
        }
 
        static void function_free_type(struct type *t)
@@ -3932,15 +3932,12 @@ lists.  In that case a separate function is used to print them.
 ### Expressions: Boolean
 
 The next class of expressions to use the `binode` will be Boolean
-expressions.  "`and then`" and "`or else`" are similar to `and` and `or`
-have same corresponding precendence.  The difference is that they don't
+expressions.  `and` and `or` are short-circuit operators that don't
 evaluate the second expression if not necessary.
 
 ###### Binode types
        And,
-       AndThen,
        Or,
-       OrElse,
        Not,
 
 ###### declare terminals
@@ -3956,14 +3953,6 @@ evaluate the second expression if not necessary.
                b->right = $<3;
                $0 = b;
        } }$
-       | Expression or else Expression ${ {
-               struct binode *b = new(binode);
-               b->op = OrElse;
-               b->left = $<1;
-               b->right = $<4;
-               $0 = b;
-       } }$
-
        | Expression and Expression ${ {
                struct binode *b = new(binode);
                b->op = And;
@@ -3971,14 +3960,6 @@ evaluate the second expression if not necessary.
                b->right = $<3;
                $0 = b;
        } }$
-       | Expression and then Expression ${ {
-               struct binode *b = new(binode);
-               b->op = AndThen;
-               b->left = $<1;
-               b->right = $<4;
-               $0 = b;
-       } }$
-
        | not Expression ${ {
                struct binode *b = new(binode);
                b->op = Not;
@@ -3994,13 +3975,6 @@ evaluate the second expression if not necessary.
                print_exec(b->right, -1, bracket);
                if (bracket) printf(")");
                break;
-       case AndThen:
-               if (bracket) printf("(");
-               print_exec(b->left, -1, bracket);
-               printf(" and then ");
-               print_exec(b->right, -1, bracket);
-               if (bracket) printf(")");
-               break;
        case Or:
                if (bracket) printf("(");
                print_exec(b->left, -1, bracket);
@@ -4008,13 +3982,6 @@ evaluate the second expression if not necessary.
                print_exec(b->right, -1, bracket);
                if (bracket) printf(")");
                break;
-       case OrElse:
-               if (bracket) printf("(");
-               print_exec(b->left, -1, bracket);
-               printf(" or else ");
-               print_exec(b->right, -1, bracket);
-               if (bracket) printf(")");
-               break;
        case Not:
                if (bracket) printf("(");
                printf("not ");
@@ -4024,9 +3991,7 @@ evaluate the second expression if not necessary.
 
 ###### propagate binode cases
        case And:
-       case AndThen:
        case Or:
-       case OrElse:
        case Not:
                /* both must be Tbool, result is Tbool */
                propagate_types(b->left, c, perr, Tbool, 0);
@@ -4039,21 +4004,11 @@ evaluate the second expression if not necessary.
 
 ###### interp binode cases
        case And:
-               rv = interp_exec(c, b->left, &rvtype);
-               right = interp_exec(c, b->right, &rtype);
-               rv.bool = rv.bool && right.bool;
-               break;
-       case AndThen:
                rv = interp_exec(c, b->left, &rvtype);
                if (rv.bool)
                        rv = interp_exec(c, b->right, NULL);
                break;
        case Or:
-               rv = interp_exec(c, b->left, &rvtype);
-               right = interp_exec(c, b->right, &rtype);
-               rv.bool = rv.bool || right.bool;
-               break;
-       case OrElse:
                rv = interp_exec(c, b->left, &rvtype);
                if (!rv.bool)
                        rv = interp_exec(c, b->right, NULL);
@@ -4313,9 +4268,10 @@ parentheses around an expression converts it into a Term,
                if (bracket) printf(")");
                break;
        case Bracket:
-               printf("(");
+               /* Avoid double brackets... */
+               if (!bracket) printf("(");
                print_exec(b->right, indent, bracket);
-               printf(")");
+               if (!bracket) printf(")");
                break;
 
 ###### propagate binode cases
@@ -4553,7 +4509,8 @@ the common header for all reductions to use.
        Block -> { IN OptNL Statementlist OUT OptNL } ${ $0 = $<Sl; }$
        |        { SimpleStatements } ${ $0 = reorder_bilist($<SS); }$
        |        SimpleStatements ; ${ $0 = reorder_bilist($<SS); }$
-       |        SimpleStatements EOL ${ $0 = reorder_bilist($<SS); }$
+       |        SimpleStatements EOL ${ $0 = reorder_bilist($<SS); 
+               }$
        |        IN OptNL Statementlist OUT ${ $0 = $<Sl; }$
 
        OpenBlock -> OpenScope { IN OptNL Statementlist OUT OptNL } ${ $0 = $<Sl; }$
@@ -4562,7 +4519,7 @@ the common header for all reductions to use.
        |        OpenScope SimpleStatements EOL ${ $0 = reorder_bilist($<SS); }$
        |        IN OpenScope OptNL Statementlist OUT ${ $0 = $<Sl; }$
 
-       UseBlock -> { OpenScope IN OptNL Statementlist OUT OptNL } ${ $0 = $<Sl; }$
+       UseBlock -> { IN OpenScope OptNL Statementlist OUT OptNL } ${ $0 = $<Sl; }$
        |        { OpenScope SimpleStatements } ${ $0 = reorder_bilist($<SS); }$
        |        IN OpenScope OptNL Statementlist OUT ${ $0 = $<Sl; }$
 
@@ -4648,7 +4605,9 @@ the common header for all reductions to use.
                struct binode *e;
 
                for (e = b; e; e = cast(binode, e->right)) {
-                       t = propagate_types(e->left, c, perr, NULL, rules);
+                       *perr |= *perr_local;
+                       *perr_local = 0;
+                       t = propagate_types(e->left, c, perr_local, NULL, rules);
                        if ((rules & Rboolok) && (t == Tbool || t == Tnone))
                                t = NULL;
                        if (t == Tnone && e->right)
@@ -4773,8 +4732,8 @@ it is declared, it is assumed to be a global constant which are allowed to
 be declared at any time.
 
 ###### Binode types
-       Assign, AssignRef,
-       Declare, DeclareRef,
+       Assign,
+       Declare,
 
 ###### declare terminals
        $TERM =
@@ -4810,7 +4769,6 @@ be declared at any time.
 ###### print binode cases
 
        case Assign:
-       case AssignRef:
                do_indent(indent, "");
                print_exec(b->left, -1, bracket);
                printf(" = ");
@@ -4820,7 +4778,6 @@ be declared at any time.
                break;
 
        case Declare:
-       case DeclareRef:
                {
                struct variable *v = cast(var, b->left)->var;
                do_indent(indent, "");
@@ -4850,9 +4807,7 @@ be declared at any time.
 ###### propagate binode cases
 
        case Assign:
-       case AssignRef:
        case Declare:
-       case DeclareRef:
                /* Both must match, or left may be ref and right an lval
                 * Type must support 'dup',
                 * For Assign, left must not be constant.
@@ -4870,12 +4825,8 @@ be declared at any time.
                                ; // No more effort needed
                        else if (t->free == reference_free &&
                                 t->reference.referent == t2 &&
-                                !(*perr_local & Erval)) {
-                               if (b->op == Assign)
-                                       b->op = AssignRef;
-                               if (b->op == Declare)
-                                       b->op = DeclareRef;
-                       }
+                                !(*perr_local & Erval))
+                               b->right = take_addr(b->right);
                        else if (t->free == reference_free &&
                                 t->reference.referent == t2 &&
                                 (*perr_local & Erval))
@@ -4889,7 +4840,7 @@ be declared at any time.
                if (*perr & Erval)
                        type_err(c, "error: cannot assign to an rval", b,
                                 NULL, 0, NULL);
-               else if ((b->op == Assign || b->op == AssignRef) && (*perr & Econst)) {
+               else if (b->op == Assign && (*perr & Econst)) {
                        type_err(c, "error: Cannot assign to a constant: %v",
                                 b->left, NULL, 0, NULL);
                        if (b->left->type == Xvar) {
@@ -4911,21 +4862,13 @@ be declared at any time.
 ###### interp binode cases
 
        case Assign:
-       case AssignRef:
                lleft = linterp_exec(c, b->left, &ltype);
-               if (!lleft)
-                       // FIXME lleft==NULL probably means illegal array ref
-                       // should that cause a runtime error
-                       ;
-               else if (b->op == AssignRef)
-                       lleft->ref = linterp_exec(c, b->right, &rtype);
-               else
+               if (lleft)
                        dinterp_exec(c, b->right, lleft, ltype, 1);
                ltype = Tnone;
                break;
 
        case Declare:
-       case DeclareRef:
        {
                struct variable *v = cast(var, b->left)->var;
                struct value *val;
@@ -4935,8 +4878,6 @@ be declared at any time.
                        v->type->prepare_type(c, v->type, 0);
                if (!b->right)
                        val_init(v->type, val);
-               else if (b->op == DeclareRef)
-                       val->ref = linterp_exec(c, b->right, &rtype);
                else
                        dinterp_exec(c, b->right, val, v->type, 0);
                break;
@@ -5819,10 +5760,13 @@ is a bit more interesting at this level.
                                struct value *val = var_value(&context, v);
                                printf("func %.*s", v->name->name.len, v->name->name.txt);
                                v->type->print_type_decl(v->type, stdout);
-                               if (brackets)
-                                       print_exec(val->function, 0, brackets);
-                               else
+                               if (brackets) {
+                                       printf(" {\n");
+                                       print_exec(val->function, 1, brackets);
+                                       printf("}\n");
+                               } else {
                                        print_value(v->type, val, stdout);
+                               }
                                printf("/* frame size %d */\n", v->type->function.local_size);
                                target -= 1;
                        }
@@ -6011,7 +5955,7 @@ things which will likely grow as the languages grows.
                a : number
                a = A;
                b:number = B
-               if a > 0 and then b > 0:
+               if a > 0 and b > 0:
                        while a != b:
                                if a < b:
                                        b = b - a