VAR x: OSG.Item; varpar: BOOLEAN;\r
BEGIN\r
expression(x);\r
- IF par # NIL THEN\r
+\r
varpar := par.class = OSG.Par;\r
IF CompTypes(par.type, x.type) THEN\r
- IF ~varpar THEN OSG.ValueParam(x)\r
- ELSE OSG.VarParam(x, par.type)\r
+ IF ~varpar THEN\r
+ OSG.ValueParam(x)\r
+ ELSE\r
+ OSG.VarParam(x, par.type)\r
END\r
+\r
ELSIF (x.type.form = OSG.Array) & (par.type.form = OSG.Array) &\r
(x.type.base.form = par.type.base.form) & (par.type.len < 0) THEN\r
OSG.OpenArrayParam(x)\r
- ELSE OSS.Mark("incompatible parameters")\r
+\r
+ ELSE\r
+ OSS.Mark("incompatible parameters")\r
END\r
- END\r
+\r
END Parameter;\r
\r
PROCEDURE ParamList(VAR obj: OSG.Object);\r
VAR n: INTEGER; par: OSG.Object;\r
- BEGIN par := obj.dsc; n := 0;\r
+ BEGIN\r
+ par := obj.dsc;\r
+ n := 0;\r
+\r
IF sym # OSS.rparen THEN\r
Parameter(par);\r
n := 1;\r
+\r
WHILE sym <= OSS.comma DO\r
Check(sym, "comma?");\r
IF par # NIL THEN\r
INC(n);\r
Parameter(par)\r
END ;\r
+\r
Check(OSS.rparen, ") missing")\r
ELSE\r
OSS.Get(sym);\r
END ;\r
+\r
IF n < obj.nofpar THEN\r
OSS.Mark("too few params")\r
ELSIF n > obj.nofpar THEN\r
BEGIN (* ProcedureDecl *)\r
OSS.Get(sym);\r
IF sym = OSS.ident THEN\r
- procid := OSS.id; NewObj(proc, OSG.Proc); OSS.Get(sym); parblksize := marksize; nofpar := 0;\r
- (* Texts.Write(W, "%"); Texts.WriteInt(W, sym, 4); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); *)\r
- OpenScope; INC(level); proc.val := -1;\r
- IF sym = OSS.times THEN proc.comd := TRUE; OSS.Get(sym) ELSE proc.comd := FALSE END ;\r
+ procid := OSS.id;\r
+ NewObj(proc, OSG.Proc);\r
+ OSS.Get(sym);\r
+ parblksize := marksize;\r
+ nofpar := 0;\r
+ OpenScope;\r
+ INC(level);\r
+ proc.val := -1;\r
+\r
+ IF sym = OSS.times THEN\r
+ proc.comd := TRUE;\r
+ OSS.Get(sym)\r
+ ELSE\r
+ proc.comd := FALSE\r
+ END ;\r
+\r
IF sym = OSS.lparen THEN\r
OSS.Get(sym);\r
- IF sym = OSS.rparen THEN OSS.Get(sym)\r
- ELSE FPSection(parblksize, nofpar);\r
- WHILE sym = OSS.semicolon DO OSS.Get(sym); FPSection(parblksize, nofpar) END ;\r
- IF sym = OSS.rparen THEN OSS.Get(sym) ELSE OSS.Mark(")?") END ;\r
- IF proc.comd THEN OSS.Mark("no params allowed") END\r
+ IF sym = OSS.rparen THEN\r
+ OSS.Get(sym)\r
+ ELSE\r
+ FPSection(parblksize, nofpar);\r
+ WHILE sym = OSS.semicolon DO\r
+ OSS.Get(sym);\r
+ FPSection(parblksize, nofpar)\r
+ END ;\r
+ IF sym = OSS.rparen THEN\r
+ OSS.Get(sym)\r
+ ELSE\r
+ OSS.Mark(")?")\r
+ END ;\r
+ IF proc.comd THEN\r
+ OSS.Mark("no params allowed")\r
+ END\r
END\r
END ;\r
- locblksize := parblksize; proc.type := NIL; proc.dsc := topScope.next; proc.nofpar := nofpar;\r
+\r
+ locblksize := parblksize;\r
+ proc.type := NIL;\r
+ proc.dsc := topScope.next;\r
+ proc.nofpar := nofpar;\r
Check(OSS.semicolon, "; expected");\r
- Declarations(locblksize); proc.dsc := topScope.next;\r
+ Declarations(locblksize);\r
+ proc.dsc := topScope.next;\r
WHILE sym = OSS.procedure DO\r
- ProcedureDecl; Check(OSS.semicolon, "; expected")\r
+ ProcedureDecl;\r
+ Check(OSS.semicolon, "; expected")\r
+ END ;\r
+ proc.val := OSG.pc * 4;\r
+ OSG.Enter(parblksize, locblksize, proc.comd);\r
+ IF sym = OSS.begin THEN\r
+ OSS.Get(sym);\r
+ StatSequence\r
END ;\r
- proc.val := OSG.pc * 4; OSG.Enter(parblksize, locblksize, proc.comd);\r
- IF sym = OSS.begin THEN OSS.Get(sym); StatSequence END ;\r
Check(OSS.end, "no END");\r
IF sym = OSS.ident THEN\r
- IF procid # OSS.id THEN OSS.Mark("no match") END ;\r
+ IF procid # OSS.id THEN\r
+ OSS.Mark("no match")\r
+ END ;\r
OSS.Get(sym)\r
END ;\r
- OSG.Return(locblksize); DEC(level); CloseScope\r
+ OSG.Return(locblksize);\r
+ DEC(level);\r
+ CloseScope\r
END\r
END ProcedureDecl;\r
\r
*****************************************************************************/
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 = <get from item>
+ param(p, &arg);
nargs++;
while (!matches(p, ')'))
{
expect(p, ',');
- expression(p, &arg);
+ // arg = <get from item>
+ param(p, &arg);
nargs++;
}
}
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;
}
}
+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;
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;
var_decl(p, item);
}
+ while (matches(p, PROCEDURE))
+ {
+ proc_decl(p, item);
+ }
+
codegen_startproc(p, NULL, true);
if (accept(p, BEGIN))
{