char* export = (proc->export ? "" : "static ");
printf("\n%s%s %s_%s(",
export,
- (proc->type ? TypeNames[proc->type->form] : "void"),
+ (proc->type ? TypeNames[proc->type->base->form] : "void"),
p->name,
proc->name);
- for (Symbol* arg = proc->desc; arg; arg = arg->next)
+
+ for (Field* arg = proc->type->fields; arg; arg = arg->next)
{
- make_var(p, arg, false);
+ Symbol sym = { .type = arg->type, .name = arg->name };
+ make_var(p, &sym, false);
if (arg->next)
{
printf(", ");
typedef struct Type {
enum {
FORM_BOOL, FORM_INT, FORM_REAL, FORM_ARRAY, FORM_STRING,
- FORM_RECORD,
+ FORM_RECORD, FORM_PROC,
FORM_COUNT
} form;
struct Field* fields;
// src/sym.c
Symbol* symbol_new(Parser* p, size_t scope, char* name, int class, bool export);
-Symbol* symbol_addfield(Parser* p, Symbol* parent, char* name, int class, bool export);
Symbol* symbol_get(Parser* p, char* name, int class);
size_t symbol_openscope(Parser* p);
void symbol_closescope(Parser* p, size_t scope);
char* name = expect_text(p, IDENT);
bool export = accept(p, '*');
Symbol* proc = symbol_new(p, 0, name, SYM_PROC, export);
+ Type* proctype = calloc(1, sizeof(Type));
+ proctype->form = FORM_PROC;
+ proc->type = proctype;
+ size_t scope = symbol_openscope(p);
/* construct the proc type */
expect(p, '(');
expect(p, ':');
type(p, item);
proc->nargs++;
- Symbol* arg = symbol_addfield(p, proc, name, SYM_VAR, false);
- arg->type = item->type;
+ add_field(p, proctype, name, false)->type = item->type;
+ symbol_new(p, scope, name, SYM_VAR, export)->type = item->type;
if (!matches(p, ')'))
{
expect(p, ',');
if (accept(p, ':'))
{
type(p, item);
- proc->type = item->type;
+ proctype->base = item->type;
}
codegen_startproc(p, proc);
- size_t scope = symbol_openscope(p);
/* parse the declarations */
if (accept(p, CONST))
var_decl(p, item);
}
-// /* TODO: Support nested procedures */
-// while (matches(p, PROCEDURE))
-// {
-// proc_decl(p, item);
-// }
-
/* parse the body of the procedure */
expect(p, BEGIN);
if (!matches(p, RETURN) && !matches(p, END))
static int sym_matches(Parser* p, int class, char* name, Symbol* sym)
{
-// printf("%s == %s\n", name, sym->name);
+// printf("[%s] == %s\n", name, sym->name);
if (name && sym->name && !strcmp(sym->name, name))
{
if (class >= 0 && (int)sym->class != class)
{
error(p, "symbol '%s' is multiply defined in the current scope", name);
}
+// puts("");
/* insert */
p->syms[p->nsyms].name = name;
p->nsyms = scope;
}
-Symbol* symbol_addfield(Parser* p, Symbol* parent, char* name, int class, bool export)
-{
- Symbol* prev = NULL;
- Symbol* curr = parent->desc;
-
-// printf("\nsymbol_addfield(%s)\n", name);
- while (curr)
- {
-// printf(" %s <- %s\n", curr->name, name);
- if (curr->name && !strcmp(curr->name, name))
- {
- error(p, "multiple definitions of '%s' in scope", name);
- }
- prev = curr;
- curr = curr->next;
- }
-
- Symbol* sym = calloc(1, sizeof(Symbol));
- sym->name = name;
- sym->class = class;
- sym->export = export;
- if (prev)
- {
- prev->next = sym;
- }
- else
- {
- parent->desc = sym;
- }
- return sym;
-}
-
/* Symbol Table Unit Tests
*****************************************************************************/
#ifdef CERISE_TESTS
const FOO = 2
type foo = Int
var
- z : Int
+ z1 : Int
q : array 5 of array 10 of Int
begin
# e = q;
c = 1;
- z = 2;
- return z;
+ z1 = 2;
+ return z1;
end
begin