]> ocean-lang.org Git - ocean/blobdiff - csrc/oceani.mdc
oceani: fix up the while/do scope
[ocean] / csrc / oceani.mdc
index 1dd320f1b5f1a03bfa3196d96b59ca6d62760846..2a40ff203efa442fa148610521cb016070c13974 100644 (file)
@@ -1002,14 +1002,12 @@ need to be freed.  For this we need to be able to find it, so assume that
        {
                struct variable *v;
 
-               if (primary->merged)
-                       // shouldn't happen
-                       primary = primary->merged;      // NOTEST
+               primary = primary->merged;
 
                for (v = primary->previous; v; v=v->previous)
                        if (v == secondary || v == secondary->merged ||
                            v->merged == secondary ||
-                           (v->merged && v->merged == secondary->merged)) {
+                           v->merged == secondary->merged) {
                                v->scope = OutScope;
                                v->merged = primary;
                        }
@@ -1105,6 +1103,7 @@ all pending-scope variables become conditionally scoped.
                v->previous = b->var;
                b->var = v;
                v->name = b;
+               v->merged = v;
                v->min_depth = v->depth = c->scope_depth;
                v->scope = InScope;
                v->in_scope = c->in_scope;
@@ -1147,9 +1146,17 @@ all pending-scope variables become conditionally scoped.
 
                scope_pop(c);
                for (vp = &c->in_scope;
-                    v = *vp, v && v->depth > c->scope_depth && v->min_depth > c->scope_depth;
-                    ) {
-                       if (v->name->var == v) switch (ct) {
+                    (v = *vp) && v->min_depth > c->scope_depth;
+                    (v->scope == OutScope || v->name->var != v)
+                    ? (*vp =  v->in_scope, 0)
+                    : ( vp = &v->in_scope, 0)) {
+                       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 */
                                switch(v->scope) {
@@ -1210,10 +1217,6 @@ all pending-scope variables become conditionally scoped.
                                }
                                break;
                        }
-                       if (v->scope == OutScope || v->name->var != v)
-                               *vp = v->in_scope;
-                       else
-                               vp = &v->in_scope;
                }
        }
 
@@ -1306,7 +1309,7 @@ For this we have `scope_finalize()`.
                        struct variable *v;
                        for (v = b->var; v; v = v->previous) {
                                struct type *t = v->type;
-                               if (v->merged && v->merged != v)
+                               if (v->merged != v)
                                        continue;
                                if (v->global)
                                        continue;
@@ -2604,8 +2607,7 @@ link to find the primary instance.
                        type_err(c, "%d:BUG: no variable!!", prog, NULL, 0, NULL); // NOTEST
                        return Tnone;                                   // NOTEST
                }
-               if (v->merged)
-                       v = v->merged;
+               v = v->merged;
                if (v->constant && (rules & Rnoconstant)) {
                        type_err(c, "error: Cannot assign to a constant: %v",
                                 prog, NULL, 0, NULL);
@@ -2641,8 +2643,7 @@ link to find the primary instance.
                struct var *var = cast(var, e);
                struct variable *v = var->var;
 
-               if (v->merged)
-                       v = v->merged;  // UNTESTED
+               v = v->merged;
                lrv = var_value(c, v);
                rvtype = v->type;
                break;
@@ -3652,8 +3653,7 @@ it is declared, and error will be raised as the name is created as
        {
                struct variable *v = cast(var, b->left)->var;
                struct value *val;
-               if (v->merged)
-                       v = v->merged;
+               v = v->merged;
                val = var_value(c, v);
                free_value(v->type, val);
                if (v->type->prepare_type)
@@ -3873,12 +3873,14 @@ defined.
                        $0->condpart = $<SP;
                        $CP->next = $0->casepart;
                        $0->casepart = $<CP;
+                       var_block_close(c, CloseSequential);
                        }$
                | SwitchPart : IN OptNL CasePart CondSuffix OUT Newlines ${
                        $0 = $<CS;
                        $0->condpart = $<SP;
                        $CP->next = $0->casepart;
                        $0->casepart = $<CP;
+                       var_block_close(c, CloseSequential);
                        }$
                | IfPart IfSuffix ${
                        $0 = $<IS;
@@ -3890,9 +3892,6 @@ defined.
 
        CondSuffix -> IfSuffix ${
                        $0 = $<1;
-                       // This is where we close scope of the whole
-                       // "for" or "while" statement
-                       var_block_close(c, CloseSequential);
                }$
                | Newlines CasePart CondSuffix ${
                        $0 = $<CS;
@@ -3929,7 +3928,7 @@ defined.
                }$
 
        $*exec
-       // These scopes are closed in CondSuffix
+       // These scopes are closed in CondStatement
        ForPart -> for OpenBlock ${
                        $0 = $<Bl;
                }$
@@ -3940,14 +3939,16 @@ defined.
                }$
 
        $cond_statement
-       // This scope is closed in CondSuffix
+       // This scope is closed in CondStatement
        WhilePart -> while UseBlock OptNL do Block ${
                        $0.condpart = $<UB;
                        $0.dopart = $<Bl;
+                       var_block_close(c, CloseSequential);
                }$
                | while OpenScope Expression ColonBlock ${
                        $0.condpart = $<Exp;
                        $0.dopart = $<Bl;
+                       var_block_close(c, CloseSequential);
                }$
 
        IfPart -> if UseBlock OptNL then OpenBlock ClosePara ${
@@ -3964,7 +3965,7 @@ defined.
                }$
 
        $*exec
-       // This scope is closed in CondSuffix
+       // This scope is closed in CondStatement
        SwitchPart -> switch OpenScope Expression ${
                        $0 = $<Ex;
                }$
@@ -4574,13 +4575,14 @@ things which will likely grow as the languages grows.
                        else
                                hi = mid
                        if hi - lo < 1:
+                               lo = mid
                                use GiveUp
                        use True
                do pass
                case Found:
                        print "Yay, I found", target
                case GiveUp:
-                       print "Closest I found was", mid
+                       print "Closest I found was", lo
 
                size::= 10
                list:[size]number