X-Git-Url: https://ocean-lang.org/code/?p=ocean;a=blobdiff_plain;f=csrc%2Foceani.mdc;h=7e1f2ac788117dddae2f9e2529e3d34ec8389aac;hp=1be7c673c010a31c9737fcfb959abc4861afb956;hb=fdc93978981976920d369c57b80da002374090a5;hpb=8f1b75648081b69f4ff47263faea1843efdca6aa diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index 1be7c67..7e1f2ac 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -242,18 +242,19 @@ structures can be used. fprintf(stderr, "oceani: no main function found.\n"); context.parse_error = 1; } + if (context.prog && !context.parse_error) { + if (!analyse_prog(context.prog, &context)) { + fprintf(stderr, "oceani: type error in program - not running.\n"); + context.parse_error = 1; + } + } if (context.prog && doprint) { ## print const decls ## print type decls print_exec(context.prog, 0, brackets); } - if (context.prog && doexec && !context.parse_error) { - if (!analyse_prog(context.prog, &context)) { - fprintf(stderr, "oceani: type error in program - not running.\n"); - exit(1); - } + if (context.prog && doexec && !context.parse_error) interp_prog(&context, context.prog, argc - optind, argv+optind); - } free_exec(context.prog); while (s) { @@ -952,13 +953,13 @@ Each variable records a scope depth and is in one of four states: enclosed the declaration, and that has closed. - "conditionally in scope". The "in scope" block and all parallel - scopes have closed, and no further mention of the name has been - seen. This state includes a secondary nest depth which records the - outermost scope seen since the variable became conditionally in - scope. If a use of the name is found, the variable becomes "in - scope" and that secondary depth becomes the recorded scope depth. - If the name is declared as a new variable, the old variable becomes - "out of scope" and the recorded scope depth stays unchanged. + scopes have closed, and no further mention of the name has been seen. + This state includes a secondary nest depth (`min_depth`) which records + the outermost scope seen since the variable became conditionally in + scope. If a use of the name is found, the variable becomes "in scope" + and that secondary depth becomes the recorded scope depth. If the + name is declared as a new variable, the old variable becomes "out of + scope" and the recorded scope depth stays unchanged. - "out of scope". The variable is neither in scope nor conditionally in scope. It is permanently out of scope now and can be removed from @@ -1140,7 +1141,14 @@ all pending-scope variables become conditionally scoped. static void var_block_close(struct parse_context *c, enum closetype ct) { - /* Close off all variables that are in_scope */ + /* Close off all variables that are in_scope. + * Some variables in c->scope may already be not-in-scope, + * such as when a PendingScope variable is hidden by a new + * variable with the same name. + * So we check for v->name->var != v and drop them. + * If we choose to make a variable OutScope, we drop it + * immediately too. + */ struct variable *v, **vp, *v2; scope_pop(c); @@ -1149,12 +1157,12 @@ all pending-scope variables become conditionally scoped. (v->scope == OutScope || v->name->var != v) ? (*vp = v->in_scope, 0) : ( vp = &v->in_scope, 0)) { - if (v->name->var != v) { + v->min_depth = c->scope_depth; + if (v->name->var != v) /* This is still in scope, but we haven't just * closed the scope. */ continue; - } switch (ct) { case CloseElse: case CloseParallel: /* handle PendingScope */ @@ -1162,14 +1170,15 @@ all pending-scope variables become conditionally scoped. case InScope: case CondScope: if (c->scope_stack->child_count == 1) + /* first among parallel branches */ v->scope = PendingScope; else if (v->previous && v->previous->scope == PendingScope) + /* all previous branches used name */ v->scope = PendingScope; else if (v->type == Tlabel) // UNTESTED + /* Labels remain pending even when not used */ v->scope = PendingScope; // UNTESTED - else if (v->name->var == v) // UNTESTED - v->scope = OutScope; // UNTESTED if (ct == CloseElse) { /* All Pending variables with this name * are now Conditional */ @@ -1180,13 +1189,16 @@ all pending-scope variables become conditionally scoped. } break; case PendingScope: - for (v2 = v; - v2 && v2->scope == PendingScope; - v2 = v2->previous) - if (v2->type != Tlabel) - v2->scope = OutScope; - break; - case OutScope: break; // UNTESTED + /* Not possible as it would require + * parallel scope to be nested immediately + * in a parallel scope, and that never + * happens. + */ + case OutScope: + /* Not possible as we already tested for + * OutScope + */ + abort(); // NOTEST } break; case CloseSequential: @@ -1207,7 +1219,6 @@ all pending-scope variables become conditionally scoped. v2 = v2->previous) if (v2->type == Tlabel) { v2->scope = CondScope; - v2->min_depth = c->scope_depth; } else v2->scope = OutScope; break; @@ -3582,19 +3593,17 @@ it is declared, and error will be raised as the name is created as do_indent(indent, ""); print_exec(b->left, indent, bracket); if (cast(var, b->left)->var->constant) { + printf("::"); if (v->where_decl == v->where_set) { - printf("::"); type_print(v->type, stdout); printf(" "); - } else - printf(" ::"); + } } else { + printf(":"); if (v->where_decl == v->where_set) { - printf(":"); type_print(v->type, stdout); printf(" "); - } else - printf(" :"); + } } if (b->right) { printf("= "); @@ -4503,13 +4512,16 @@ analysis is a bit more interesting at this level. } al = cast(binode, al->right); } - v = interp_exec(c, p->right, &vtype); + v = interp_exec(c, p, &vtype); free_value(vtype, &v); } ###### interp binode cases - case List: - case Func: abort(); // NOTEST + case List: abort(); // NOTEST + + case Func: + rv = interp_exec(c, b->right, &rvtype); + break; ## And now to test it out.