]> ocean-lang.org Git - ocean/blobdiff - csrc/oceani.mdc
oceani: improve reporting of variables being freed at end of block.
[ocean] / csrc / oceani.mdc
index 821775c6c0dec0e11106dc1205462fbeccbf6286..76c8c9b4efd96414511685e620c4d7b7e849acbd 100644 (file)
@@ -236,6 +236,11 @@ structures can be used.
                        }
                } else
                        ss = s;                         // NOTEST
+               if (!ss->code) {
+                       fprintf(stderr, "oceani: no code found in requested section\n");        // NOTEST
+                       exit(1);                        // NOTEST
+               }
+
                parse_oceani(ss->code, &context.config, dotrace ? stderr : NULL);
 
                if (!context.prog) {
@@ -1148,6 +1153,7 @@ all pending-scope variables become conditionally scoped.
                v->scope = InScope;
                v->in_scope = c->in_scope;
                c->in_scope = v;
+               ## variable init
                return v;
        }
 
@@ -1294,9 +1300,15 @@ the frame needs to be reallocated as it grows so it can store those
 values.  The local frame doesn't get values until the interpreted phase
 is started, so there is no need to allocate until the size is known.
 
+We initialize the `frame_pos` to an impossible value, so that we can
+tell if it was set or not later.
+
 ###### variable fields
-               short frame_pos;
-               short global;
+       short frame_pos;
+       short global;
+
+###### variable init
+       v->frame_pos = -1;
 
 ###### parse context
 
@@ -1524,7 +1536,7 @@ also want to know what sort of bracketing to use.
        static void print_exec(struct exec *e, int indent, int bracket)
        {
                if (!e)
-                       return;         // NOTEST
+                       return;
                switch (e->type) {
                case Xbinode:
                        print_binode(cast(binode, e), indent, bracket); break;
@@ -1533,10 +1545,12 @@ also want to know what sort of bracketing to use.
                if (e->to_free) {
                        struct variable *v;
                        do_indent(indent, "/* FREE");
-                       for (v = e->to_free; v; v = v->next_free)
-                               printf(" %.*s(%c%d+%d)", v->name->name.len, v->name->name.txt,
-                                      v->global ? 'G':'L',
-                                      v->frame_pos, v->type ? v->type->size:0);
+                       for (v = e->to_free; v; v = v->next_free) {
+                               printf(" %.*s", v->name->name.len, v->name->name.txt);
+                               if (v->frame_pos >= 0)
+                                       printf("(%d+%d)", v->frame_pos,
+                                              v->type ? v->type->size:0);
+                       }
                        printf(" */\n");
                }
        }
@@ -2343,6 +2357,9 @@ or as an indented list of one parameter per line
        do
                code block
 
+For constructing these lists we use a `List` binode, which will be
+further detailed when Expression Lists are introduced.
+
 ###### Binode types
        Func, List,
 
@@ -2806,6 +2823,57 @@ there.
                }
                break;
 
+### Expression list
+
+We take a brief detour, now that we have expressions, to describe lists
+of expressions.  These will be needed for function parameters and
+possibly other situations.  They seem generic enough to introduce here
+to be used elsewhere.
+
+And ExpressionList will use the `List` type of `binode`, building up at
+the end.  And place where they are used will probably call
+`reorder_bilist()` to get a more normal first/next arrangement.
+
+###### declare terminals
+       $TERM ,
+
+`List` execs have no implicit semantics, so they are never propagated or
+interpreted.  The can be printed as a comma separate list, which is how
+they are parsed.  Note they are also used for function formal parameter
+lists.  In that case a separate function is used to print them.
+
+###### print binode cases
+       case List:
+               while (b) {
+                       printf(" ");
+                       print_exec(b->left, -1, bracket);
+                       if (b->right)
+                               printf(",");
+                       b = cast(binode, b->right);
+               }
+               break;
+
+###### propagate binode cases
+       case List: abort(); // NOTEST
+###### interp binode cases
+       case List: abort(); // NOTEST
+
+###### Grammar
+
+       $*binode
+       ExpressionList -> ExpressionList , Expression ${
+                       $0 = new(binode);
+                       $0->op = List;
+                       $0->left = $<1;
+                       $0->right = $<3;
+               }$
+               | Expression ${
+                       $0 = new(binode);
+                       $0->op = List;
+                       $0->left = NULL;
+                       $0->right = $<1;
+               }$
+
 ### Expressions: Boolean
 
 The next class of expressions to use the `binode` will be Boolean
@@ -3503,62 +3571,47 @@ is in-place.
 expressions and prints the values separated by spaces and terminated
 by a newline.  No control of formatting is possible.
 
-`print` faces the same list-ordering issue as blocks, and uses the
-same solution.
+`print` uses `ExpressionList` to collect the expressions and stores them
+on the left side of a `Print` binode unlessthere is a trailing comma
+when the list is stored on the `right` side and no trailing newline is
+printed.
 
 ###### Binode types
        Print,
 
 ##### expr precedence
-       $TERM print ,
+       $TERM print
 
 ###### SimpleStatement Grammar
 
        | print ExpressionList ${
-               $0 = reorder_bilist($<2);
-       }$
-       | print ExpressionList , ${
                $0 = new(binode);
                $0->op = Print;
                $0->right = NULL;
-               $0->left = $<2;
-               $0 = reorder_bilist($0);
+               $0->left = reorder_bilist($<EL);
        }$
+       | print ExpressionList , ${ {
+               $0 = new(binode);
+               $0->op = Print;
+               $0->right = reorder_bilist($<EL);
+               $0->left = NULL;
+       } }$
        | print ${
                $0 = new(binode);
                $0->op = Print;
+               $0->left = NULL;
                $0->right = NULL;
        }$
 
-###### Grammar
-
-       $*binode
-       ExpressionList -> ExpressionList , Expression ${
-               $0 = new(binode);
-               $0->op = Print;
-               $0->left = $<1;
-               $0->right = $<3;
-               }$
-               | Expression ${
-                       $0 = new(binode);
-                       $0->op = Print;
-                       $0->left = NULL;
-                       $0->right = $<1;
-               }$
-
 ###### print binode cases
 
        case Print:
                do_indent(indent, "print");
-               while (b) {
-                       if (b->left) {
-                               printf(" ");
-                               print_exec(b->left, -1, bracket);
-                               if (b->right)
-                                       printf(",");
-                       }
-                       b = cast(binode, b->right);
-               }
+               if (b->right) {
+                       print_exec(b->right, -1, bracket);
+                       printf(",");
+               } else
+                       print_exec(b->left, -1, bracket);
                if (indent >= 0)
                        printf("\n");
                break;
@@ -3567,30 +3620,33 @@ same solution.
 
        case Print:
                /* don't care but all must be consistent */
-               propagate_types(b->left, c, ok, NULL, Rnolabel);
-               propagate_types(b->right, c, ok, NULL, Rnolabel);
+               if (b->left)
+                       b = cast(binode, b->left);
+               else
+                       b = cast(binode, b->right);
+               while (b) {
+                       propagate_types(b->left, c, ok, NULL, Rnolabel);
+                       b = cast(binode, b->right);
+               }
                break;
 
 ###### interp binode cases
 
        case Print:
        {
-               char sep = 0;
-               int eol = 1;
-               for ( ; b; b = cast(binode, b->right))
-                       if (b->left) {
-                               if (sep)
-                                       putchar(sep);
-                               left = interp_exec(c, b->left, &ltype);
-                               print_value(ltype, &left);
-                               free_value(ltype, &left);
-                               if (b->right)
-                                       sep = ' ';
-                       } else if (sep)
-                               eol = 0;
-               ltype = Tnone;
-               if (eol)
+               struct binode *b2 = cast(binode, b->left);
+               if (!b2)
+                       b2 = cast(binode, b->right);
+               for (; b2; b2 = cast(binode, b2->right)) {
+                       left = interp_exec(c, b2->left, &ltype);
+                       print_value(ltype, &left);
+                       free_value(ltype, &left);
+                       if (b2->right)
+                               putchar(' ');
+               }
+               if (b->right == NULL)
                        printf("\n");
+               ltype = Tnone;
                break;
        }
 
@@ -4466,7 +4522,6 @@ analysis is a bit more interesting at this level.
 
 ###### print binode cases
        case Func:
-       case List:
                do_indent(indent, "func main(");
                for (b2 = cast(binode, b->left); b2; b2 = cast(binode, b2->right)) {
                        struct variable *v = cast(var, b2->left)->var;
@@ -4485,7 +4540,6 @@ analysis is a bit more interesting at this level.
                break;
 
 ###### propagate binode cases
-       case List:
        case Func: abort();             // NOTEST
 
 ###### core functions
@@ -4578,8 +4632,6 @@ analysis is a bit more interesting at this level.
        }
 
 ###### interp binode cases
-       case List: abort();     // NOTEST
-
        case Func:
                rv = interp_exec(c, b->right, &rvtype);
                break;