From e49b8c9295ce261db570ea62025b5dfa2a697b2b Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 9 Nov 2021 13:44:27 +1100 Subject: [PATCH] oceani: Make 'List' separate from Print 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 --- csrc/oceani.mdc | 148 ++++++++++++++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 55 deletions(-) diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index 821775c..0eaa9c8 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -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) - return; // NOTEST + return; 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 +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 +2809,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 +3557,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($op = Print; + $0->right = reorder_bilist($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 +3606,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, <ype); - 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, <ype); + print_value(ltype, &left); + free_value(ltype, &left); + if (b2->right) + putchar(' '); + } + if (b->right == NULL) printf("\n"); + ltype = Tnone; break; } @@ -4466,7 +4508,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 +4526,6 @@ analysis is a bit more interesting at this level. break; ###### propagate binode cases - case List: case Func: abort(); // NOTEST ###### core functions @@ -4578,8 +4618,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; -- 2.43.0