X-Git-Url: https://ocean-lang.org/code/?p=ocean;a=blobdiff_plain;f=csrc%2Foceani.mdc;h=f97652d025ca4c90ef8e183ac45bea0eed41a677;hp=ca59924a22b9365e94a47c7d014c21528684aff8;hb=d58f04dc62ec58ed72c00db43b80122fbdfc0925;hpb=096d061b99078b3a89181d6841f0c01a1eec0017 diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index ca59924..f97652d 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -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 = $ OpenScope { IN OptNL Statementlist OUT OptNL } ${ $0 = $ { OpenScope IN OptNL Statementlist OUT OptNL } ${ $0 = $ { IN OpenScope OptNL Statementlist OUT OptNL } ${ $0 = $ ComplexStatements ComplexStatement ${ if ($2 == NULL) { - $0 = $<1; + $0 = $<1; // NOTEST - impossible } else { $0 = new(binode); $0->op = Block; @@ -4586,7 +4543,7 @@ the common header for all reductions to use. }$ | ComplexStatement ${ if ($1 == NULL) { - $0 = NULL; + $0 = NULL; // NOTEST - impossible } else { $0 = new(binode); $0->op = Block; @@ -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, <ype); - 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