}
printf("}\n");
}
+
+void codegen_prepcall(Parser* p, Item* item)
+{
+// printf(" const %s _T%d = %lld;\n",
+// TypeNames[item->type->form], p->curr_reg, item->imm.i);
+// item->reg = p->curr_reg;
+// p->curr_reg++;
+// printf(" const long _T%d = %s(", p->curr_reg, item->imm.s);
+// item->reg = p->curr_reg;
+// p->curr_reg++;
+}
+
+void codegen_call(Parser* p, Item* item)
+{
+ (void)p, (void)item;
+
+ printf(" const long _T%d = %s(", p->curr_reg, item->imm.s);
+ item->reg = p->curr_reg;
+ p->curr_reg++;
+ printf(");\n");
+}
+
+void codegen_setarg(Parser* p, Item* item, bool firstarg)
+{
+ load_var(p, item);
+// (void)p, (void)item;
+// if (item->mode == ITEM_CONST)
+// {
+// printf("%s%lld", (!firstarg ? ", " : ""), item->imm.i);
+// }
+// else
+// {
+// printf("%s_T%ld", (!firstarg ? ", " : ""), item->reg);
+// }
+}
*****************************************************************************/
static void expression(Parser* p, Item* item);
-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};
+ Item argdef = {0};
if (!matches(p, ')'))
{
- // arg = <get from item>
- param(p, &arg);
+ Item arg = {0};
+ expression(p, &arg);
+ // if check_types()
+ codegen_setarg(p, &arg, true);
+ // else check_array_type()
nargs++;
+
while (!matches(p, ')'))
{
expect(p, ',');
- // arg = <get from item>
- param(p, &arg);
+ expression(p, &arg);
+ // if check_types()
+ codegen_setarg(p, &arg, false);
+ // else check_array_type()
nargs++;
}
}
if (accept(p, '('))
{
// TODO: check item is a procedure
+ codegen_prepcall(p, item);
param_list(p, item);
- //codegen_call(p, item);
+ codegen_call(p, item);
expect(p, ')');
}
break;
}
else if (accept(p, RECORD))
{
+ expect(p, END);
}
else
{
RULE(proc_decl)
{
expect(p, PROCEDURE);
- (void)expect_text(p, IDENT);
- (void)accept(p, '*');
+ char* name = expect_text(p, IDENT);
+ bool export = accept(p, '*');
+ Symbol* sym = symbol_new(p, name, SYM_PROC, export);
+ Symbol** args = &(sym->desc);
/* construct the proc type */
expect(p, '(');
while (!matches(p, ')'))
{
- (void)expect_text(p, IDENT);
+ char* name = expect_text(p, IDENT);
expect(p, ':');
type(p, item);
+ sym->nargs++;
+ // TODO: Added argument symbol here...
}
expect(p, ')');
if (accept(p, ':'))
{
type(p, item);
+ sym->type = item->type;
}
/* parse the declarations */
/* parse the body of the procedure */
expect(p, BEGIN);
- statement_seq(p, item);
+ if (!matches(p, RETURN) && !matches(p, END))
+ {
+ statement_seq(p, item);
+ }
if (accept(p, RETURN))
{
expression(p, item);
parse_rule(const_decl, 0, "FOO = 5, BAR = FOO - 3");
}
- TEST(Should module level variable declarations)
+ TEST(Should parse module level type declarations)
+ {
+ parse_rule(type_decl, 0, "a = Int");
+ parse_rule(type_decl, 0, "a = Real");
+ parse_rule(type_decl, 0, "a = Bool");
+ parse_rule(type_decl, 0, "a = array 42 of Int");
+ parse_rule(type_decl, 0, "a = array 42 of array 42 of Int");
+ parse_rule(type_decl, 0, "a = record end");
+ }
+
+ TEST(Should parse module level variable declarations)
{
parse_rule(var_decl, 0, "i : Int");
parse_rule(var_decl, 0, "i : Real");
parse_rule(var_decl, 0, "i : Bool");
parse_rule(var_decl, 0, "x,y,z : Int");
}
+
+ TEST(Should parse module level procedure declarations)
+ {
+ parse_rule(proc_decl, 0,
+ "procedure Foo*() : Int\n"
+ "begin\n"
+ " return 1;\n"
+ "end"
+ );
+ }
+
}
#endif