]> ocean-lang.org Git - ocean/blobdiff - csrc/oceani.mdc
oceani: move comment printing from print_exec() to where later
[ocean] / csrc / oceani.mdc
index f97652d025ca4c90ef8e183ac45bea0eed41a677..c687fddca5ea7a17521fe730c81d8381d61bbb6e 100644 (file)
@@ -425,10 +425,12 @@ executables.  This allows for expressions and lists etc.  Other times an
 executable is something quite specific like a constant or variable name.
 So we define a `struct exec` to be a general executable with a type, and
 a `struct binode` which is a subclass of `exec`, forms a node in a
-binary tree, and holds an operation.  There will be other subclasses,
-and to access these we need to be able to `cast` the `exec` into the
-various other types.  The first field in any `struct exec` is the type
-from the `exec_types` enum.
+binary tree, and holds an operation.  The simplest operation is "List"
+which can be used to combine several execs together.
+
+There will be other subclasses, and to access these we need to be able
+to `cast` the `exec` into the various other types.  The first field in
+any `struct exec` is the type from the `exec_types` enum.
 
 ###### macros
        #define cast(structname, pointer) ({            \
@@ -461,6 +463,7 @@ from the `exec_types` enum.
        struct binode {
                struct exec;
                enum Btype {
+                       List,
                        ## Binode types
                } op;
                struct exec *left, *right;
@@ -531,7 +534,9 @@ and we need `free_binode`.
 
 Printing an `exec` requires that we know the current indent level for
 printing line-oriented components.  As will become clear later, we
-also want to know what sort of bracketing to use.
+also want to know what sort of bracketing to use.  It will also be used
+to sometime print comments after an exec to explain some of the results
+of analysis.
 
 ###### ast functions
 
@@ -547,6 +552,7 @@ also want to know what sort of bracketing to use.
        {
                struct binode *b2;
                switch(b->op) {
+               case List: abort(); // must be handled by parent NOTEST
                ## print binode cases
                }
        }
@@ -554,24 +560,13 @@ also want to know what sort of bracketing to use.
        static void print_exec(struct exec *e, int indent, int bracket)
        {
                if (!e)
-                       return;
+                       return; // NOTEST
                switch (e->type) {
                case Xbinode:
                        print_binode(cast(binode, e), indent, bracket); break;
                ## print exec cases
                }
-               if (e->to_free) {
-                       struct variable *v;
-                       do_indent(indent, "/* FREE");
-                       for (v = e->to_free; v; v = v->next_free) {
-                               printf(" %.*s", v->name->name.len, v->name->name.txt);
-                               printf("[%d,%d]", v->scope_start, v->scope_end);
-                               if (v->frame_pos >= 0)
-                                       printf("(%d+%d)", v->frame_pos,
-                                              v->type ? v->type->size:0);
-                       }
-                       printf(" */\n");
-               }
+               ## print exec extras
        }
 
 ###### forward decls
@@ -621,6 +616,7 @@ the value can only be assigned once, when the variable is declared.
                {
                        struct binode *b = cast(binode, prog);
                        switch (b->op) {
+                       case List: abort(); // NOTEST
                        ## propagate binode cases
                        }
                        break;
@@ -740,6 +736,7 @@ in `rval`.
                        struct type *ltype, *rtype;
                        ltype = rtype = Tnone;
                        switch (b->op) {
+                       case List: abort();     // NOTEST
                        ## interp binode cases
                        }
                        free_value(ltype, &left);
@@ -1516,7 +1513,9 @@ cannot nest, so a declaration while a name is in-scope is an error.
 
 When a scope closes, the values of the variables might need to be freed.
 This happens in the context of some `struct exec` and each `exec` will
-need to know which variables need to be freed when it completes.
+need to know which variables need to be freed when it completes.  To
+improve visibility, we add a comment when printing any `exec` that
+embodies a scope to list the variables that must be freed when it ends.
 
 ####### exec fields
        struct variable *to_free;
@@ -1534,6 +1533,20 @@ need to know which variables need to be freed when it completes.
                }
        }
 
+###### print exec extras
+       if (e->to_free) {
+               struct variable *v;
+               do_indent(indent, "/* FREE");
+               for (v = e->to_free; v; v = v->next_free) {
+                       printf(" %.*s", v->name->name.len, v->name->name.txt);
+                       printf("[%d,%d]", v->scope_start, v->scope_end);
+                       if (v->frame_pos >= 0)
+                               printf("(%d+%d)", v->frame_pos,
+                                      v->type ? v->type->size:0);
+               }
+               printf(" */\n");
+       }
+
 ###### ast functions
        static void variable_unlink_exec(struct variable *v)
        {
@@ -2328,21 +2341,42 @@ different phases of parse, analyse, print, interpret.
 Being "complex" the language will naturally have syntax to access
 specifics of objects of these types.  These will fit into the grammar as
 "Terms" which are the things that are combined with various operators to
-form "Expression".  Where a Term is formed by some operation on another
+form an "Expression".  Where a Term is formed by some operation on another
 Term, the subordinate Term will always come first, so for example a
 member of an array will be expressed as the Term for the array followed
 by an index in square brackets.  The strict rule of using postfix
 operations makes precedence irrelevant within terms.  To provide a place
-to put the grammar for each terms of each type, we will start out by
+to put the grammar for terms of each type, we will start out by
 introducing the "Term" grammar production, with contains at least a
 simple "Value" (to be explained later).
 
+We also take this opportunity to introduce the "ExpressionsList" which
+is a simple comma-separated list of expressions - it may be used in
+various places.
+
+###### declare terminals
+       $TERM ,
+
 ###### Grammar
        $*exec
        Term ->  Value ${ $0 = $<1; }$
        | Variable ${ $0 = $<1; }$
        ## term 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;
+       }$
+
 Thus far the complex types we have are arrays and structs.
 
 #### Arrays
@@ -3608,9 +3642,6 @@ further detailed when Expression Lists are introduced.
 
        $TERM func
 
-###### Binode types
-       List,
-
 ###### Grammar
 
        $*variable
@@ -3878,57 +3909,6 @@ 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
@@ -4678,11 +4658,16 @@ printed.
 
        case Print:
                do_indent(indent, "print");
-               if (b->right) {
-                       print_exec(b->right, -1, bracket);
+               b2 = cast(binode, b->left ?: b->right);
+               while (b2) {
+                       printf(" ");
+                       print_exec(b2->left, -1, bracket);
+                       if (b2->right)
+                               printf(",");
+                       b2 = cast(binode, b2->right);
+               }
+               if (b->right)
                        printf(",");
-               } else
-                       print_exec(b->left, -1, bracket);
                if (indent >= 0)
                        printf("\n");
                break;