]> ocean-lang.org Git - ocean/commitdiff
oceani: Make 'List' separate from Print
authorNeilBrown <neil@brown.name>
Tue, 9 Nov 2021 02:44:27 +0000 (13:44 +1100)
committerNeilBrown <neil@brown.name>
Tue, 9 Nov 2021 04:46:45 +0000 (15:46 +1100)
Create a stand-alone ExpressionList which uses the List binode rather
than the Print binode.

The Print statement no longer uses a NULL entry on the end of the list
to denode a trailing comma.  Rather ->left is used for a normal print
list and ->right is used for a print list that has a trailing comma.

Signed-off-by: NeilBrown <neil@brown.name>
csrc/oceani.mdc

index 821775c6c0dec0e11106dc1205462fbeccbf6286..0eaa9c8952623a0364d61689d423dce1a7b560c4 100644 (file)
@@ -1524,7 +1524,7 @@ also want to know what sort of bracketing to use.
        static void print_exec(struct exec *e, int indent, int bracket)
        {
                if (!e)
        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;
                switch (e->type) {
                case Xbinode:
                        print_binode(cast(binode, e), indent, bracket); break;
@@ -2343,6 +2343,9 @@ or as an indented list of one parameter per line
        do
                code block
 
        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,
 
 ###### Binode types
        Func, List,
 
@@ -2806,6 +2809,57 @@ there.
                }
                break;
 
                }
                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
 ### Expressions: Boolean
 
 The next class of expressions to use the `binode` will be Boolean
@@ -3503,62 +3557,47 @@ is in-place.
 expressions and prints the values separated by spaces and terminated
 by a newline.  No control of formatting is possible.
 
 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
 
 ###### Binode types
        Print,
 
 ##### expr precedence
-       $TERM print ,
+       $TERM print
 
 ###### SimpleStatement Grammar
 
        | print ExpressionList ${
 
 ###### SimpleStatement Grammar
 
        | print ExpressionList ${
-               $0 = reorder_bilist($<2);
-       }$
-       | print ExpressionList , ${
                $0 = new(binode);
                $0->op = Print;
                $0->right = NULL;
                $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;
        | print ${
                $0 = new(binode);
                $0->op = Print;
+               $0->left = NULL;
                $0->right = 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");
 ###### 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;
                if (indent >= 0)
                        printf("\n");
                break;
@@ -3567,30 +3606,33 @@ same solution.
 
        case Print:
                /* don't care but all must be consistent */
 
        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:
        {
                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");
                        printf("\n");
+               ltype = Tnone;
                break;
        }
 
                break;
        }
 
@@ -4466,7 +4508,6 @@ analysis is a bit more interesting at this level.
 
 ###### print binode cases
        case Func:
 
 ###### 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;
                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 +4526,6 @@ analysis is a bit more interesting at this level.
                break;
 
 ###### propagate binode cases
                break;
 
 ###### propagate binode cases
-       case List:
        case Func: abort();             // NOTEST
 
 ###### core functions
        case Func: abort();             // NOTEST
 
 ###### core functions
@@ -4578,8 +4618,6 @@ analysis is a bit more interesting at this level.
        }
 
 ###### interp binode cases
        }
 
 ###### interp binode cases
-       case List: abort();     // NOTEST
-
        case Func:
                rv = interp_exec(c, b->right, &rvtype);
                break;
        case Func:
                rv = interp_exec(c, b->right, &rvtype);
                break;