From b5118330ab3e8d5eaaeca4087f2e2e92380678dd Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sun, 12 May 2019 15:03:27 +1000 Subject: [PATCH] oceani: allow list of declarations as top level structure We can have constants, types, etc at top level, as well a program Signed-off-by: NeilBrown --- csrc/oceani-tests.mdc | 1 + csrc/oceani.mdc | 75 +++++++++++++++++++++++++++++++++---------- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/csrc/oceani-tests.mdc b/csrc/oceani-tests.mdc index 9850f25..a41b199 100644 --- a/csrc/oceani-tests.mdc +++ b/csrc/oceani-tests.mdc @@ -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: diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index de899a2..48ce058 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -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 ${ -- 2.43.0