]> ocean-lang.org Git - ocean/blobdiff - csrc/oceani.mdc
oceani/parsergen: assorted text improvements.
[ocean] / csrc / oceani.mdc
index bd2c41afc02a1daa34ed6921fb60ba12e6ea4638..a9046750e5b658a0f26a3423bb2b396bd773d60a 100644 (file)
@@ -89,7 +89,7 @@ that.
        myLDLIBS:= libparser.o libscanner.o libmdcode.o -licuuc
        LDLIBS := $(filter-out $(myLDLIBS),$(LDLIBS)) $(myLDLIBS)
        ## libs
-       all :: oceani
+       all :: $(LDLIBS) oceani
        oceani.c oceani.h : oceani.mdc parsergen
                ./parsergen -o oceani --LALR --tag Parser oceani.mdc
        oceani.mk: oceani.mdc md2c
@@ -395,6 +395,7 @@ when no longer needed.
        static int parse_value(struct value *vl, char *arg)
        {
                struct text tx;
+               int neg = 0;
                switch(vl->vtype) {
                case Vunknown:
                case Vnone:
@@ -405,9 +406,15 @@ when no longer needed.
                        memcpy(vl->str.txt, arg, vl->str.len);
                        break;
                case Vnum:
+                       if (*arg == '-') {
+                               neg = 1;
+                               arg++;
+                       }
                        tx.txt = arg; tx.len = strlen(tx.txt);
                        if (number_parse(vl->num, vl->tail, tx) == 0)
                                mpq_init(vl->num);
+                       else if (neg)
+                               mpq_neg(vl->num, vl->num);
                        break;
                case Vbool:
                        if (strcasecmp(arg, "true") == 0 ||
@@ -524,12 +531,12 @@ subclasses, and to access these we need to be able to `cast` the
 Each different type of `exec` node needs a number of functions
 defined, a bit like methods.  We must be able to be able to free it,
 print it, analyse it and execute it.  Once we have specific `exec`
-types we will need to parse them to.  Let's take this a bit more
+types we will need to parse them too.  Let's take this a bit more
 slowly.
 
 #### Freeing
 
-The parser generator requires as `free_foo` function for each struct
+The parser generator requires a `free_foo` function for each struct
 that stores attributes and they will be `exec`s of subtypes there-of.
 So we need `free_exec` which can handle all the subtypes, and we need
 `free_binode`.
@@ -601,10 +608,10 @@ also want to know what sort of bracketing to use.
 
 #### Analysing
 
-As discusses, analysis involves propagating type requirements around
+As discussed, analysis involves propagating type requirements around
 the program and looking for errors.
 
-So propagate_types is passed a type that the `exec` is expected to return,
+So `propagate_types` is passed a type that the `exec` is expected to return,
 and returns the type that it does return, either of which can be `Vunknown`.
 An `ok` flag is passed by reference. It is set to `0` when an error is
 found, and `2` when any change is made.  If it remains unchanged at
@@ -617,11 +624,8 @@ found, and `2` when any change is made.  If it remains unchanged at
        {
                enum vtype t;
 
-               if (!prog) {
-                       if (type != Vunknown && type != Vnone)
-                               *ok = 0;
+               if (!prog)
                        return Vnone;
-               }
 
                switch (prog->type) {
                case Xbinode:
@@ -719,6 +723,11 @@ an executable.
                        $0->val.vtype = Vstr;
                        string_parse(&$1, '\\', &$0->val.str, $0->val.tail);
                        }$
+               | MULTI_STRING ${
+                       $0 = new(val);
+                       $0->val.vtype = Vstr;
+                       string_parse(&$1, '\\', &$0->val.str, $0->val.tail);
+                       }$
 
 ###### print exec cases
        case Xval:
@@ -849,7 +858,7 @@ Our first user of the `binode` will be expressions, and particularly
 Boolean expressions.  As I haven't implemented precedence in the
 parser generator yet, we need different names from each precedence
 level used by expressions.  The outer most or lowest level precedence
-are Boolean `or` `and`, and `not` which form and `Expression` our of `BTerm`s
+are Boolean `or` `and`, and `not` which form an `Expression` out of `BTerm`s
 and `BFact`s.
 
 ###### Binode types
@@ -963,7 +972,7 @@ expression operator.
                        $0->left = $<1;
                        $0->right = $<3;
                }$
-               | Expr ${ $0 = $<1; }$
+       | Expr ${ $0 = $<1; }$
 
 ###### Grammar
 
@@ -1273,7 +1282,9 @@ list.
        Close -> }
                | NEWLINE }
        Block -> Open Statementlist Close ${ $0 = $<2; }$
+               | Open Newlines Statementlist Close ${ $0 = $<3; }$
                | Open SimpleStatements } ${ $0 = reorder_bilist($<2); }$
+               | Open Newlines SimpleStatements } ${ $0 = reorder_bilist($<3); }$
                | : Statementlist ${ $0 = $<2; }$
                | : SimpleStatements ${ $0 = reorder_bilist($<2); }$
 
@@ -1562,7 +1573,7 @@ function.
 ### The Conditional Statement
 
 This is the biggy and currently the only complex statement.
-This subsumes `if`, `while`, `do/while`, `switch`, and some part of
+This subsumes `if`, `while`, `do/while`, `switch`, and some parts of
 `for`.  It is comprised of a number of parts, all of which are
 optional though set combinations apply.
 
@@ -1573,7 +1584,7 @@ value.  `condpart` can fail to return any value if it simply executes
 to completion.  This is treated the same as returning True.
 
 If there is a `thenpart` it will be executed whenever the `condpart`
-or `cond` returns True (or does not return), but this will happen
+or `cond` returns True (or does not return any value), but this will happen
 *after* `dopart` (when present).
 
 If `elsepart` is present it will be executed at most once when the
@@ -1583,7 +1594,7 @@ executed when the condition returns a matching value.
 The particular sorts of values allowed in case parts has not yet been
 determined in the language design.
 
-The cond_statement cannot fit into a `binode` so a new `exec` is
+The `cond_statement` cannot fit into a `binode` so a new `exec` is
 defined.
 
 ###### exec type
@@ -1814,13 +1825,18 @@ defined.
                            cast(binode, cs->condpart)->op == Block) {
                                printf(":\n");
                                print_exec(cs->condpart, indent+1, bracket);
-                               do_indent(indent, "then:\n");
-                               print_exec(cs->thenpart, indent+1, bracket);
+                               if (cs->thenpart) {
+                                       do_indent(indent, "then:\n");
+                                       print_exec(cs->thenpart, indent+1, bracket);
+                               }
                        } else {
                                printf(" ");
                                print_exec(cs->condpart, 0, bracket);
-                               printf(":\n");
-                               print_exec(cs->thenpart, indent+1, bracket);
+                               if (cs->thenpart) {
+                                       printf(":\n");
+                                       print_exec(cs->thenpart, indent+1, bracket);
+                               } else
+                                       printf("\n");
                        }
                }
                for (cp = cs->casepart; cp; cp = cp->next) {
@@ -1933,7 +1949,7 @@ defined.
 ### Finally the whole program.
 
 Somewhat reminiscent of Pascal a (current) Ocean program starts with
-the keyword "program" and list of variable names which are assigned
+the keyword "program" and list of variable names which are assigned
 values from command line arguments.  Following this is a `block` which
 is the code to execute.