X-Git-Url: https://ocean-lang.org/code/?p=ocean;a=blobdiff_plain;f=csrc%2Foceani.mdc;h=97c195382cd8955c4e0c16e154125e5d7fa2e93b;hp=af7768dd1d763638d5142987c895d108d2a9f0a1;hb=1dd9f61bbc7e8890b5407ba084793817e55fe502;hpb=cbbbc8ec0230cf82765da33ecff7be9824006519 diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index af7768d..97c1953 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -151,8 +151,8 @@ structures can be used. ## core functions #include - static char Usage[] = "Usage: oceani --trace --print --noexec --brackets" - "--section=SectionName prog.ocn\n"; + static char Usage[] = + "Usage: oceani --trace --print --noexec --brackets --section=SectionName prog.ocn\n"; static const struct option long_options[] = { {"trace", 0, NULL, 't'}, {"print", 0, NULL, 'p'}, @@ -171,9 +171,7 @@ structures can be used. char *section = NULL; struct parse_context context = { .config = { - .ignored = (1 << TK_line_comment) - | (1 << TK_block_comment) - | (1 << TK_mark), + .ignored = (1 << TK_mark), .number_chars = ".,_+- ", .word_start = "_", .word_cont = "_", @@ -633,8 +631,8 @@ there are errors. ###### includes #include - #include "string.h" - #include "number.h" + #include "parse_string.h" + #include "parse_number.h" ###### libs myLDLIBS := libnumber.o libstring.o -lgmp @@ -1006,6 +1004,7 @@ like "if" and the code following it. $void OpenScope -> ${ scope_push(c); }$ + ClosePara -> ${ var_block_close(c, CloseParallel); }$ Each variable records a scope depth and is in one of four states: @@ -2000,50 +1999,47 @@ function will be needed. } ###### top level grammar - DeclareStruct -> struct IDENTIFIER FieldBlock ${ { - struct type *t = - add_type(c, $2.txt, &structure_prototype); - int cnt = 0; - struct fieldlist *f; - - for (f = $3; f; f=f->prev) - cnt += 1; - - t->structure.nfields = cnt; - t->structure.fields = calloc(cnt, sizeof(struct field)); - f = $3; - while (cnt > 0) { - cnt -= 1; - t->structure.fields[cnt] = f->f; - f->f.init = val_prepare(Tnone); - f = f->prev; - } - } }$ + DeclareStruct -> struct IDENTIFIER FieldBlock Newlines ${ { + struct type *t = + add_type(c, $2.txt, &structure_prototype); + int cnt = 0; + struct fieldlist *f; + + for (f = $3; f; f=f->prev) + cnt += 1; + + t->structure.nfields = cnt; + t->structure.fields = calloc(cnt, sizeof(struct field)); + f = $3; + while (cnt > 0) { + cnt -= 1; + t->structure.fields[cnt] = f->f; + f->f.init = val_prepare(Tnone); + f = f->prev; + } + } }$ - $void - Open -> { - | NEWLINE Open - Close -> } - | NEWLINE Close $*fieldlist - FieldBlock -> Open FieldList Close ${ $0 = $<2; }$ - | Open SimpleFieldList } ${ $0 = $<2; }$ - | : FieldList ${ $0 = $<2; }$ - - FieldList -> SimpleFieldList NEWLINE ${ $0 = $<1; }$ - | FieldList SimpleFieldList NEWLINE ${ - $2->prev = $<1; - $0 = $<2; + FieldBlock -> { IN OptNL FieldLines OUT OptNL } ${ $0 = $ SimpleFieldList Newlines ${ $0 = $prev = $ Field ${ $0 = $<1; }$ + SimpleFieldList -> Field ${ $0 = $prev = $<1; - $0 = $<3; + $F->prev = $ IDENTIFIER : Type = Expression ${ { int ok; @@ -2067,7 +2063,6 @@ function will be needed. $0->f.type = $<3; $0->f.init = val_init($3); }$ - | ERROR ${ tok_err(c, "Syntax error in struct field", &$1); }$ ###### forward decls static void structure_print_type(struct type *t, FILE *f); @@ -2077,7 +2072,7 @@ function will be needed. { int i; - fprintf(f, "struct %.*s:\n", t->name.len, t->name.txt); + fprintf(f, "struct %.*s\n", t->name.len, t->name.txt); for (i = 0; i < t->structure.nfields; i++) { struct field *fl = t->structure.fields + i; @@ -2810,6 +2805,7 @@ precedence is handled better I might be able to discard this. $LEFT + - Eop $LEFT * / % ++ Top $LEFT Uop + $TERM ( ) ###### expression grammar | Expression Eop Expression ${ { @@ -3046,16 +3042,35 @@ is in-place. ###### Binode types Block, +###### expr precedence + $TERM pass + ###### Grammar $*binode - Block -> Open Statementlist Close ${ $0 = $<2; }$ - | Open SimpleStatements } ${ $0 = reorder_bilist($<2); }$ - | : SimpleStatements $$NEWLINE ${ $0 = reorder_bilist($<2); }$ - | : Statementlist $$NEWLINE ${ $0 = $<2; }$ - - Statementlist -> ComplexStatements ${ $0 = reorder_bilist($<1); }$ - | NEWLINE Statementlist ${ $0 = $<2; }$ + Block -> { IN OptNL Statementlist OUT OptNL } ${ $0 = $ OpenScope { IN OptNL Statementlist OUT OptNL } ${ $0 = $ { OpenScope IN OptNL Statementlist OUT OptNL } ${ $0 = $ { IN OptNL Statementlist OUT OptNL } ${ $0 = $ ComplexStatements ${ $0 = reorder_bilist($ ComplexStatements ComplexStatement ${ if ($2 == NULL) { @@ -3079,10 +3094,12 @@ is in-place. }$ $*exec - ComplexStatement -> SimpleStatementLine ${ - $0 = reorder_bilist($<1); + ComplexStatement -> SimpleStatements Newlines ${ + $0 = reorder_bilist($left = NULL; $0->right = $<1; }$ - | SimpleStatements ; ${ $0 = $<1; }$ - - SimpleStatementLine -> SimpleStatements NEWLINE ${ $0 = $<1; }$ - | SimpleStatementLine NEWLINE ${ $0 = $<1; }$ SimpleStatement -> pass ${ $0 = NULL; }$ | ERROR ${ tok_err(c, "Syntax error in statement", &$1); }$ @@ -3179,6 +3192,9 @@ same solution. ###### Binode types Print, +##### expr precedence + $TERM print , + ###### SimpleStatement Grammar | print ExpressionList ${ @@ -3411,6 +3427,9 @@ function. ###### Binode types Use, +###### expr precedence + $TERM use + ###### SimpleStatement Grammar | use Expression ${ $0 = new_pos(binode, $1); @@ -3559,42 +3578,59 @@ defined. ###### ComplexStatement Grammar | CondStatement ${ $0 = $<1; }$ +###### expr precedence + $TERM for then while do + $TERM else + $TERM switch case + ###### Grammar $*cond_statement - // both ForThen and Whilepart open scopes, and CondSuffix only + // A CondStatement must end with EOL, as does CondSuffix and + // IfSuffix. + // ForPart, ThenPart, SwitchPart, CasePart are non-empty and + // may or may not end with EOL + // WhilePart and IfPart include an appropriate Suffix + + + // Both ForPart and Whilepart open scopes, and CondSuffix only // closes one - so in the first branch here we have another to close. - CondStatement -> ForPart ThenPart WhilePart CondSuffix ${ - $0 = $<4; - $0->forpart = $<1; - $0->thenpart = $<2; - $0->condpart = $3.condpart; $3.condpart = NULL; - $0->dopart = $3.dopart; $3.dopart = NULL; + CondStatement -> ForPart OptNL ThenPart OptNL WhilePart CondSuffix ${ + $0 = $forpart = $thenpart = $condpart = $WP.condpart; $WP.condpart = NULL; + $0->dopart = $WP.dopart; $WP.dopart = NULL; var_block_close(c, CloseSequential); }$ - | ForPart WhilePart CondSuffix ${ - $0 = $<3; - $0->forpart = $<1; - $0->thenpart = NULL; - $0->condpart = $2.condpart; $2.condpart = NULL; - $0->dopart = $2.dopart; $2.dopart = NULL; + | ForPart OptNL WhilePart CondSuffix ${ + $0 = $forpart = $condpart = $WP.condpart; $WP.condpart = NULL; + $0->dopart = $WP.dopart; $WP.dopart = NULL; var_block_close(c, CloseSequential); }$ | WhilePart CondSuffix ${ - $0 = $<2; - $0->condpart = $1.condpart; $1.condpart = NULL; - $0->dopart = $1.dopart; $1.dopart = NULL; + $0 = $condpart = $WP.condpart; $WP.condpart = NULL; + $0->dopart = $WP.dopart; $WP.dopart = NULL; + }$ + | SwitchPart OptNL CasePart CondSuffix ${ + $0 = $condpart = $next = $0->casepart; + $0->casepart = $condpart = $<1; - $2->next = $0->casepart; - $0->casepart = $<2; + | SwitchPart : IN OptNL CasePart CondSuffix OUT Newlines ${ + $0 = $condpart = $next = $0->casepart; + $0->casepart = $condpart = $1.condpart; $1.condpart = NULL; - $0->thenpart = $1.thenpart; $1.thenpart = NULL; + $0 = $condpart = $IP.condpart; $IP.condpart = NULL; + $0->thenpart = $IP.thenpart; $IP.thenpart = NULL; // This is where we close an "if" statement var_block_close(c, CloseSequential); }$ @@ -3605,96 +3641,83 @@ defined. // "for" or "while" statement var_block_close(c, CloseSequential); }$ + | Newlines CasePart CondSuffix ${ + $0 = $next = $0->casepart; + $0->casepart = $next = $0->casepart; - $0->casepart = $<1; + $0 = $next = $0->casepart; + $0->casepart = $ case Expression OpenScope Block ${ - $0 = calloc(1,sizeof(struct casepart)); - $0->value = $<2; - $0->action = $<4; - var_block_close(c, CloseParallel); - }$ - | CasePart NEWLINE ${ $0 = $<1; }$ + IfSuffix -> Newlines ${ $0 = new(cond_statement); }$ + | Newlines ElsePart ${ $0 = $ ${ $0 = new(cond_statement); }$ - | IfSuffix NEWLINE ${ $0 = $<1; }$ - | else OpenScope Block ${ + ElsePart -> else OpenBlock Newlines ${ $0 = new(cond_statement); - $0->elsepart = $<3; + $0->elsepart = $elsepart = $<3; + $0->elsepart = $ case Expression OpenScope ColonBlock ${ + $0 = calloc(1,sizeof(struct casepart)); + $0->value = $action = $ for OpenScope SimpleStatements ${ - $0 = reorder_bilist($<3); - }$ - | for OpenScope Block ${ - $0 = $<3; + ForPart -> for OpenBlock ${ + $0 = $ then OpenScope SimpleStatements ${ - $0 = reorder_bilist($<3); - var_block_close(c, CloseSequential); - }$ - | then OpenScope Block ${ - $0 = $<3; + ThenPart -> then OpenBlock ${ + $0 = $ while OpenScope Block ${ $0 = $<3; }$ - | WhileHead NEWLINE ${ $0 = $<1; }$ $cond_statement // This scope is closed in CondSuffix - WhilePart -> while OpenScope Expression Block ${ - $0.type = Xcond_statement; - $0.condpart = $<3; - $0.dopart = $<4; + WhilePart -> while UseBlock OptNL do Block ${ + $0.condpart = $ if OpenScope Expression OpenScope Block ${ - $0.type = Xcond_statement; - $0.condpart = $<3; - $0.thenpart = $<5; - var_block_close(c, CloseParallel); + IfPart -> if UseBlock OptNL then OpenBlock ClosePara ${ + $0.condpart = $ switch OpenScope Expression ${ - $0 = $<3; + $0 = $forpart) { do_indent(indent, "for"); - if (bracket) printf(" {\n"); else printf(":\n"); + if (bracket) printf(" {\n"); else printf("\n"); print_exec(cs->forpart, indent+1, bracket); if (cs->thenpart) { if (bracket) do_indent(indent, "} then {\n"); else - do_indent(indent, "then:\n"); + do_indent(indent, "then\n"); print_exec(cs->thenpart, indent+1, bracket); } if (bracket) do_indent(indent, "}\n"); @@ -3722,12 +3745,12 @@ defined. if (bracket) do_indent(indent, "while {\n"); else - do_indent(indent, "while:\n"); + do_indent(indent, "while\n"); print_exec(cs->condpart, indent+1, bracket); if (bracket) do_indent(indent, "} do {\n"); else - do_indent(indent, "do:\n"); + do_indent(indent, "do\n"); print_exec(cs->dopart, indent+1, bracket); if (bracket) do_indent(indent, "}\n"); @@ -3792,7 +3815,7 @@ defined. if (bracket) printf(" {\n"); else - printf(":\n"); + printf("\n"); print_exec(cs->elsepart, indent+1, bracket); if (bracket) do_indent(indent, "}\n"); @@ -3931,19 +3954,23 @@ various declarations in the parse context. ###### Parser: grammar $void - Ocean -> DeclarationList + Ocean -> OptNL DeclarationList + + OptNL -> + | OptNL NEWLINE + Newlines -> NEWLINE + | Newlines NEWLINE DeclarationList -> Declaration | DeclarationList Declaration - Declaration -> DeclareConstant - | DeclareProgram - | DeclareStruct - | NEWLINE - | ERROR NEWLINE ${ + Declaration -> ERROR Newlines ${ tok_err(c, "error: unhandled parse error", &$1); }$ + | DeclareConstant + | DeclareProgram + | DeclareStruct ## top level grammar @@ -3972,19 +3999,18 @@ searching through for the Nth constant for decreasing N. ###### top level grammar - DeclareConstant -> const Open ConstList Close - | const Open SimpleConstList } - | const : ConstList - | const SimpleConstList NEWLINE + DeclareConstant -> const { IN OptNL ConstList OUT OptNL } Newlines + | const { SimpleConstList } Newlines + | const IN OptNL ConstList OUT Newlines + | const SimpleConstList Newlines - ConstList -> ComplexConsts - | NEWLINE ConstList - ComplexConsts -> ComplexConst ComplexConsts - | ComplexConst - ComplexConst -> SimpleConstList NEWLINE + ConstList -> ConstList SimpleConstLine + | SimpleConstLine SimpleConstList -> SimpleConstList ; Const | Const | SimpleConstList ; + SimpleConstLine -> SimpleConstList Newlines + | ERROR Newlines ${ tok_err(c, "Syntax error in constant", &$1); }$ $*type CType -> Type ${ $0 = $<1; }$ @@ -4017,7 +4043,6 @@ searching through for the Nth constant for decreasing N. v->val = interp_exec($5); } } }$ - | ERROR NEWLINE ${ tok_err(c, "Syntax error in constant", &$1); }$ ###### print const decls { @@ -4035,7 +4060,7 @@ searching through for the Nth constant for decreasing N. if (target == -1) { if (i) - printf("const:\n"); + printf("const\n"); target = i; } else { printf(" %.*s :: ", v->name->name.len, v->name->name.txt); @@ -4080,11 +4105,11 @@ analysis is a bit more interesting at this level. } }$ $*binode - Program -> program OpenScope Varlist Block ${ + Program -> program OpenScope Varlist ColonBlock Newlines ${ $0 = new(binode); $0->op = Program; - $0->left = reorder_bilist($<3); - $0->right = $<4; + $0->left = reorder_bilist($right = $scope_stack && !c->parse_error) abort(); }$ @@ -4208,14 +4233,14 @@ things which will likely grow as the languages grows. ###### demo: hello - const: + const pi ::= 3.141_592_6 four ::= 2 + 2 ; five ::= 10/2 const pie ::= "I like Pie"; cake ::= "The cake is" ++ " a lie" - struct fred: + struct fred size:[four]number name:string alive:Boolean @@ -4230,7 +4255,7 @@ things which will likely grow as the languages grows. */ if A > B: bigger := "yes" - else: + else bigger := "no" print "Is", A, "bigger than", B,"? ", bigger /* If a variable is not used after the 'if', no @@ -4239,7 +4264,7 @@ things which will likely grow as the languages grows. if A > B * 2: double:string = "yes" print A, "is more than twice", B, "?", double - else: + else double := B*2 print "double", B, "is", double @@ -4250,15 +4275,15 @@ things which will likely grow as the languages grows. while a != b: if a < b: b = b - a - else: + else a = a - b print "GCD of", A, "and", B,"is", a else if a <= 0: print a, "is not positive, cannot calculate GCD" - else: + else print b, "is not positive, cannot calculate GCD" - for: + for togo := 10 f1 := 1; f2 := 1 print "Fibonacci:", f1,f2, @@ -4271,21 +4296,21 @@ things which will likely grow as the languages grows. print "" /* Binary search... */ - for: + for lo:= 0; hi := 100 target := 77 - while: + while mid := (lo + hi) / 2 if mid == target: use Found if mid < target: lo = mid - else: + else hi = mid if hi - lo < 1: use GiveUp use True - do: pass + do pass case Found: print "Yay, I found", target case GiveUp: @@ -4316,6 +4341,8 @@ things which will likely grow as the languages grows. print "", list[i], print + if 1 == 2 then print "yes"; else print "no" + bob:fred bob.name = "Hello" bob.alive = (bob.name == "Hello")