void name##_actual(Parser* p, Item* item); \
void name(Parser* p, Item* item) { \
printf("%*c-> %s\n", ++Indent * 2, ' ', __func__); \
- name##_actual(p); \
+ name##_actual(p, item); \
Indent--; } \
void name##_actual(Parser* p, Item* item)
#else
RULE(var_decl)
{
- (void)p, (void)item;
+ (void)item;
+ int nsyms = 0;
+ Symbol* sym = NULL;
+ Symbol* type = NULL;
+ char* name = NULL;
+ bool export = false;
+
+ while (1)
+ {
+ name = expect_text(p, IDENT);
+ export = accept(p, '*');
+ sym = symbol_new(p, name, SYM_CONST, export);
+ nsyms++;
+
+ if (!accept(p, ','))
+ {
+ break;
+ }
+ }
+
+ expect(p, ':');
+ name = expect_text(p, IDENT);
+ type = symbol_get(p, name);
+ if (!type)
+ {
+ error(p, "unknown type identifier '%'\n", name);
+ }
+ if (type->class != SYM_TYPE)
+ {
+ error(p, "'%' is not a type identifier\n", name);
+ }
+
+ /* apply the type to the newly created symbols */
+ for (int i = 0; i < nsyms; i++)
+ {
+ sym->type = type->type;
+ sym = sym->next;
+ }
}
RULE(type_decl)
RULE(const_decl)
{
+ char* name = NULL;
+ bool export = false;
+ Symbol* sym = NULL;
+
while (1)
{
- char* name = NULL;
- bool export = false;
- Symbol* sym = NULL;
-
name = expect_text(p, IDENT);
export = accept(p, '*');
sym = symbol_new(p, name, SYM_CONST, export);
}
if (accept(p, TYPE))
{
-// type_decl(p, item);
+ type_decl(p, item);
expect(p, ';');
}
if (accept(p, VAR))
{
-// var_decl(p, item);
+ var_decl(p, item);
expect(p, ';');
}
}
char* sname = expect_text(p, IDENT);
/* TODO: Check that it matches filename here */
expect(p, ';');
+
if (matches(p, IMPORT))
{
import_list(p, item);
}
+
declaration_seq(p, item);
+
if (accept(p, BEGIN))
{
codegen_startproc(0);
statement_seq(p, item);
codegen_endproc();
}
+
expect(p, END);
char* ename = expect_text(p, IDENT);
if (strcmp(sname, ename))
{
parse_module("Empty", "module Empty; end Empty;");
parse_module("ModA", "module ModA; import ModB; end ModA;");
+ parse_module("ModA", "module ModA; const FOO = 42; end ModA;");
+ parse_module("ModA", "module ModA; var foo : Int; end ModA;");
}
TEST(Should parse imports)
parse_rule(const_decl, 0, "FOO = 5 >= 3");
parse_rule(const_decl, 0, "FOO = 5, BAR = FOO - 3");
}
+
+ TEST(Should 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");
+ }
}
#endif