X-Git-Url: https://ocean-lang.org/code/?p=ocean;a=blobdiff_plain;f=csrc%2Foceani.mdc;h=48ce0587b4491fa2adc4e7f054d13a9cce6bc745;hp=de899a2524d91d79f740bd2582874aa5fe7a018d;hb=b5118330ab3e8d5eaaeca4087f2e2e92380678dd;hpb=abf0b309f6ee22d82ae0989fb78970afc4a105bc 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 ${