From 65bbc005c0e400729b9eb0db2cf34c1120455710 Mon Sep 17 00:00:00 2001 From: mike lowis Date: Mon, 3 May 2021 22:48:53 -0400 Subject: [PATCH] started parsing procedure declarations --- cerise/oberon0/OSP.Mod | 92 ++++++++++++++++----- cerise/src/grammar.c | 177 +++++++++++++++++++++++++---------------- cerise/tests/Module.m | 18 +++-- 3 files changed, 192 insertions(+), 95 deletions(-) diff --git a/cerise/oberon0/OSP.Mod b/cerise/oberon0/OSP.Mod index 2997d6a..9f37943 100644 --- a/cerise/oberon0/OSP.Mod +++ b/cerise/oberon0/OSP.Mod @@ -104,26 +104,35 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017 OSPX*) VAR x: OSG.Item; varpar: BOOLEAN; BEGIN expression(x); - IF par # NIL THEN + varpar := par.class = OSG.Par; IF CompTypes(par.type, x.type) THEN - IF ~varpar THEN OSG.ValueParam(x) - ELSE OSG.VarParam(x, par.type) + IF ~varpar THEN + OSG.ValueParam(x) + ELSE + OSG.VarParam(x, par.type) END + ELSIF (x.type.form = OSG.Array) & (par.type.form = OSG.Array) & (x.type.base.form = par.type.base.form) & (par.type.len < 0) THEN OSG.OpenArrayParam(x) - ELSE OSS.Mark("incompatible parameters") + + ELSE + OSS.Mark("incompatible parameters") END - END + END Parameter; PROCEDURE ParamList(VAR obj: OSG.Object); VAR n: INTEGER; par: OSG.Object; - BEGIN par := obj.dsc; n := 0; + BEGIN + par := obj.dsc; + n := 0; + IF sym # OSS.rparen THEN Parameter(par); n := 1; + WHILE sym <= OSS.comma DO Check(sym, "comma?"); IF par # NIL THEN @@ -132,10 +141,12 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017 OSPX*) INC(n); Parameter(par) END ; + Check(OSS.rparen, ") missing") ELSE OSS.Get(sym); END ; + IF n < obj.nofpar THEN OSS.Mark("too few params") ELSIF n > obj.nofpar THEN @@ -614,33 +625,70 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017 OSPX*) BEGIN (* ProcedureDecl *) OSS.Get(sym); IF sym = OSS.ident THEN - procid := OSS.id; NewObj(proc, OSG.Proc); OSS.Get(sym); parblksize := marksize; nofpar := 0; - (* Texts.Write(W, "%"); Texts.WriteInt(W, sym, 4); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); *) - OpenScope; INC(level); proc.val := -1; - IF sym = OSS.times THEN proc.comd := TRUE; OSS.Get(sym) ELSE proc.comd := FALSE END ; + procid := OSS.id; + NewObj(proc, OSG.Proc); + OSS.Get(sym); + parblksize := marksize; + nofpar := 0; + OpenScope; + INC(level); + proc.val := -1; + + IF sym = OSS.times THEN + proc.comd := TRUE; + OSS.Get(sym) + ELSE + proc.comd := FALSE + END ; + IF sym = OSS.lparen THEN OSS.Get(sym); - IF sym = OSS.rparen THEN OSS.Get(sym) - ELSE FPSection(parblksize, nofpar); - WHILE sym = OSS.semicolon DO OSS.Get(sym); FPSection(parblksize, nofpar) END ; - IF sym = OSS.rparen THEN OSS.Get(sym) ELSE OSS.Mark(")?") END ; - IF proc.comd THEN OSS.Mark("no params allowed") END + IF sym = OSS.rparen THEN + OSS.Get(sym) + ELSE + FPSection(parblksize, nofpar); + WHILE sym = OSS.semicolon DO + OSS.Get(sym); + FPSection(parblksize, nofpar) + END ; + IF sym = OSS.rparen THEN + OSS.Get(sym) + ELSE + OSS.Mark(")?") + END ; + IF proc.comd THEN + OSS.Mark("no params allowed") + END END END ; - locblksize := parblksize; proc.type := NIL; proc.dsc := topScope.next; proc.nofpar := nofpar; + + locblksize := parblksize; + proc.type := NIL; + proc.dsc := topScope.next; + proc.nofpar := nofpar; Check(OSS.semicolon, "; expected"); - Declarations(locblksize); proc.dsc := topScope.next; + Declarations(locblksize); + proc.dsc := topScope.next; WHILE sym = OSS.procedure DO - ProcedureDecl; Check(OSS.semicolon, "; expected") + ProcedureDecl; + Check(OSS.semicolon, "; expected") + END ; + proc.val := OSG.pc * 4; + OSG.Enter(parblksize, locblksize, proc.comd); + IF sym = OSS.begin THEN + OSS.Get(sym); + StatSequence END ; - proc.val := OSG.pc * 4; OSG.Enter(parblksize, locblksize, proc.comd); - IF sym = OSS.begin THEN OSS.Get(sym); StatSequence END ; Check(OSS.end, "no END"); IF sym = OSS.ident THEN - IF procid # OSS.id THEN OSS.Mark("no match") END ; + IF procid # OSS.id THEN + OSS.Mark("no match") + END ; OSS.Get(sym) END ; - OSG.Return(locblksize); DEC(level); CloseScope + OSG.Return(locblksize); + DEC(level); + CloseScope END END ProcedureDecl; diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 1d02b99..d0287d0 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -61,19 +61,31 @@ static void init_item(Item* item, Symbol* sym) *****************************************************************************/ static void expression(Parser* p, Item* item); -RULE(expr_list) +RULE(param) +{ + (void)item; + Item arg = {0}; + expression(p, &arg); + // if check_types() +// codegen_setarg(p, &arg); + // else check_array_type() +} + +RULE(param_list) { (void)item; int nargs = 0; Item arg = {0}; if (!matches(p, ')')) { - expression(p, &arg); + // arg = + param(p, &arg); nargs++; while (!matches(p, ')')) { expect(p, ','); - expression(p, &arg); + // arg = + param(p, &arg); nargs++; } } @@ -178,10 +190,9 @@ RULE(factor) designator(p, item); if (accept(p, '(')) { - //Item call = {0}; - // check item is a procedure - expr_list(p, item); - //codegen_call(p, &call); + // TODO: check item is a procedure + param_list(p, item); + //codegen_call(p, item); expect(p, ')'); } break; @@ -299,6 +310,93 @@ RULE(type) } } +RULE(statement_seq) +{ + do + { + if (matches(p, IDENT)) + { + Item right = { 0 }; + char* text = expect_text(p, IDENT); + if (accept(p, '=')) + { + Symbol* sym = symbol_get(p, SYM_VAR, text); + init_item(item, sym); + item->imm.s = sym->name; + + expression(p, &right); + check_types(p, item, &right); + codegen_store(p, item, &right); + } + else + { + /* TODO: add function calls and other complex stuff */ + error(p, "expected assignment"); + } + expect(p, ';'); + } + else if (matches(p, IF)) + { + expect(p, IF); + expression(p, item); + check_bool(p, item); + codegen_if(p, item); + expect(p, THEN); + statement_seq(p, &(Item){0}); + int elsifs = 0; + while (accept(p, ELSIF)) + { + elsifs++; + codegen_else(p, item); + expression(p, item); + check_bool(p, item); + codegen_if(p, item); + expect(p, THEN); + statement_seq(p, &(Item){0}); + } + if (accept(p, ELSE)) + { + codegen_else(p, item); + statement_seq(p, &(Item){0}); + } + codegen_endif(p, elsifs, item); + expect(p, END); + } + else + { + error(p, "expected a statement"); + } + } + while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN)); +} + +RULE(proc_decl) +{ + expect(p, PROCEDURE); + (void)expect_text(p, IDENT); + (void)accept(p, '*'); + expect(p, '('); + while (!matches(p, ')')) + { + (void)expect_text(p, IDENT); + expect(p, ':'); + type(p, item); + } + expect(p, ')'); + if (accept(p, ':')) + { + type(p, item); + } + expect(p, BEGIN); + statement_seq(p, item); + if (accept(p, RETURN)) + { + expression(p, item); + expect(p, ';'); + } + expect(p, END); +} + RULE(var_decl) { (void)item; @@ -373,66 +471,6 @@ RULE(const_decl) while (matches(p, IDENT)); } -RULE(statement_seq) -{ - do - { - if (matches(p, IDENT)) - { - Item right = { 0 }; - char* text = expect_text(p, IDENT); - if (accept(p, '=')) - { - Symbol* sym = symbol_get(p, SYM_VAR, text); - init_item(item, sym); - item->imm.s = sym->name; - - expression(p, &right); - check_types(p, item, &right); - codegen_store(p, item, &right); - } - else - { - /* TODO: add function calls and other complex stuff */ - error(p, "expected assignment"); - } - expect(p, ';'); - } - else if (matches(p, IF)) - { - expect(p, IF); - expression(p, item); - check_bool(p, item); - codegen_if(p, item); - expect(p, THEN); - statement_seq(p, &(Item){0}); - int elsifs = 0; - while (accept(p, ELSIF)) - { - elsifs++; - codegen_else(p, item); - expression(p, item); - check_bool(p, item); - codegen_if(p, item); - expect(p, THEN); - statement_seq(p, &(Item){0}); - } - if (accept(p, ELSE)) - { - codegen_else(p, item); - statement_seq(p, &(Item){0}); - } - codegen_endif(p, elsifs, item); - expect(p, END); - } - else - { - error(p, "expected a statement"); - } - } - while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF)); -} - RULE(import_list) { (void)item; @@ -489,6 +527,11 @@ RULE(module) var_decl(p, item); } + while (matches(p, PROCEDURE)) + { + proc_decl(p, item); + } + codegen_startproc(p, NULL, true); if (accept(p, BEGIN)) { diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 00e3193..2cd4eba 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -19,12 +19,18 @@ var b : Int c : Int +procedure Foo*(e : Int) begin -# a = true; -# a = A; -# b = 24; -# b = B; -# + c = b * b; + return c; +end + +begin + a = true; + a = A; + b = 24; + b = B; + # # Unary ops # b = +b; # b = -b; @@ -82,5 +88,5 @@ begin # c = 3; # end - c = c(1,2,3); +# c = c(1,2,3); end -- 2.49.0