]> ocean-lang.org Git - ocean/commitdiff
oceani: allow list of declarations as top level structure
authorNeilBrown <neil@brown.name>
Sun, 12 May 2019 05:03:27 +0000 (15:03 +1000)
committerNeilBrown <neil@brown.name>
Mon, 13 May 2019 05:53:19 +0000 (15:53 +1000)
We can have constants, types, etc at top level, as well
a program

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

index 9850f2563d611b17cf4856bbe052385c44d5f452..a41b199d0cb6e14e2d839b821714f8325c45e88f 100644 (file)
@@ -487,6 +487,7 @@ separate file first, then run from there.
 
 ###### output: syn1
        .tmp.code:3:11: error: unhandled parse error: then
+       oceani: no program found.
 
 ###### test: tokerr
        program:
index de899a2524d91d79f740bd2582874aa5fe7a018d..48ce0587b4491fa2adc4e7f054d13a9cce6bc745 100644 (file)
@@ -114,6 +114,7 @@ structures can be used.
                struct token_config config;
                char *file_name;
                int parse_error;
+               struct exec *prog;
                ## parse context
        };
 
@@ -179,7 +180,6 @@ structures can be used.
                        },
                };
                int doprint=0, dotrace=0, doexec=1, brackets=0;
-               struct exec **prog;
                int opt;
                while ((opt = getopt_long(argc, argv, options, long_options, NULL))
                       != -1) {
@@ -223,32 +223,31 @@ structures can be used.
                                        break;
                        }
                        if (ss)
-                               prog = parse_oceani(ss->code, &context.config,
-                                                   dotrace ? stderr : NULL);
+                               parse_oceani(ss->code, &context.config,
+                                            dotrace ? stderr : NULL);
                        else {
                                fprintf(stderr, "oceani: cannot find section %s\n",
                                        section);
                                exit(1);
                        }
                } else
-                       prog = parse_oceani(s->code, &context.config,
-                                   dotrace ? stderr : NULL);
-               if (!prog) {
-                       fprintf(stderr, "oceani: fatal parser error.\n");
+                       parse_oceani(s->code, &context.config,
+                                    dotrace ? stderr : NULL);
+               if (!context.prog) {
+                       fprintf(stderr, "oceani: no program found.\n");
                        context.parse_error = 1;
                }
-               if (prog && doprint)
-                       print_exec(*prog, 0, brackets);
-               if (prog && doexec && !context.parse_error) {
-                       if (!analyse_prog(*prog, &context)) {
+               if (context.prog && doprint)
+                       print_exec(context.prog, 0, brackets);
+               if (context.prog && doexec && !context.parse_error) {
+                       if (!analyse_prog(context.prog, &context)) {
                                fprintf(stderr, "oceani: type error in program - not running.\n");
                                exit(1);
                        }
-                       interp_prog(*prog, argv+optind+1);
+                       interp_prog(context.prog, argv+optind+1);
                }
-               if (prog) {
-                       free_exec(*prog);
-                       free(prog);
+               if (context.prog) {
+                       free_exec(context.prog);
                }
                while (s) {
                        struct section *t = s->next;
@@ -3544,12 +3543,44 @@ defined.
                break;
        }
 
+### Top level structure
+
+All the language elements so far can be used in various places.  Now
+it is time to clarify what those places are.
+
+At the top level of a file there will be a number of declarations.
+Many of the things that can be declared haven't been described yet,
+such as functions, procedures, imports, named types, and probably
+more.
+For now there are two sorts of things that can appear at the top
+level.  They are predefined constants and the main program.  While the
+syntax will allow the main program to appear multiple times, that will
+trigger an error if it is actually attempted.
+
+The various declarations do not return anything.  They store the
+various declarations in the parse context.
+
+###### Parser: grammar
+
+       $void
+       Ocean -> DeclarationList
+
+       DeclarationList -> Declaration
+               | DeclarationList Declaration
+
+       Declaration -> DeclareConstant
+               | DeclareProgram
+               | NEWLINE
+
+       ## top level grammar
+
 ### Finally the whole program.
 
 Somewhat reminiscent of Pascal a (current) Ocean program starts with
 the keyword "program" and a list of variable names which are assigned
 values from command line arguments.  Following this is a `block` which
-is the code to execute.
+is the code to execute.  Unlike Pascal, constants and other
+declarations come *before* the program.
 
 As this is the top level, several things are handled a bit
 differently.
@@ -3560,7 +3591,17 @@ analysis is a bit more interesting at this level.
 ###### Binode types
        Program,
 
-###### Parser: grammar
+###### top level grammar
+
+       DeclareProgram -> Program ${ {
+               struct parse_context *c = config2context(config);
+               if (c->prog)
+                       type_err(c, "Program defined a second time",
+                                $1, NULL, 0, NULL);
+               else
+                       c->prog = $<1;
+       } }$
+
 
        $*binode
        Program -> program OpenScope Varlist Block OptNL ${