struct Symbol;
+typedef struct Field {
+ struct Field* next;
+ char* name;
+ Type* type;
+ long offset;
+} Field;
+
typedef struct Type {
enum {
FORM_BOOL, FORM_INT, FORM_REAL, FORM_ARRAY, FORM_STRING,
typedef struct Symbol {
struct Symbol* next;
enum{
- SYM_SCOPE, SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC
+ SYM_SCOPE, SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC, SYM_FIELD
} class;
char* name;
Type* type;
{
item->type = calloc(1, sizeof(Type));
item->type->form = FORM_RECORD;
-// Symbol **fields = &(item->type->fields);
-// while (peek(p)->type != END)
-// {
-// do
-// {
-// char* name = expect_text(p, IDENT);
-// bool export = accept(p, '*');
-// *prev = symbol_new(p, name, SYM_VAR, export);
-// nsyms++;
-// }
-// while (accept(p, ','));
-//
-//
-//// int nsyms = 0;
-//// Symbol head = {0};
-//// Symbol **prev = &(head.next);
-////
-//// Item base_type = {0};
-//// expect(p, ':');
-//// type(p, &base_type);
-//
-//// /* apply the type to the newly created symbols */
-//// for (int i = 0; i < nsyms; i++)
-//// {
-//// first->type = base_type.type;
-//// codegen_var(p, first);
-//// sym = first->next;
-//// }
-// }
+ Symbol head = {0};
+ int nfields = 0;
+
+ while (peek(p)->type != END)
+ {
+ do
+ {
+ char* name = expect_text(p, IDENT);
+ bool export = accept(p, '*');
+ (void)symbol_addfield(p, &head, name, SYM_FIELD, export);
+ nfields++;
+ }
+ while (accept(p, ','));
+
+ Item field_type = {0};
+ expect(p, ':');
+ type(p, &field_type);
+
+ /* apply the type to the newly created symbols */
+ Symbol* field = head.desc;
+ for (int i = 0; i < nfields; i++)
+ {
+ field->type = field_type.type;
+ field = field->next;
+ }
+ item->type->fields = head.desc;
+ }
expect(p, END);
}
var_decl(p, item);
}
+// /* TODO: Support nested procedures */
// while (matches(p, PROCEDURE))
// {
// proc_decl(p, item);
return 0;
}
+static Symbol* lookup(Parser* p, int class, char* name)
+{
+ for (Symbol* scope = p->scope; scope; scope = scope->next)
+ {
+// printf("SCOPE(n: %p):\n", scope->next);
+ if (sym_matches(p, class, name, scope))
+ {
+ return scope;
+ }
+
+ for (Symbol* sym = scope->desc; sym; sym = sym->next)
+ {
+// printf(" %s == %s %d\n", name, sym->name, sym_matches(p, class, name, scope));
+ if (sym_matches(p, class, name, sym))
+ {
+ return sym;
+ }
+ }
+ }
+ return NULL;
+}
+
+
Symbol* symbol_new(Parser* p, char* name, int class, bool export)
{
Symbol* prev = NULL;
curr = curr->next;
}
+// Symbol* existing = lookup(p, SYM_VAR, name);
+// printf("%s : %p\n", name, existing);
+// if ((class == SYM_VAR) && existing && !existing->global)
+// {
+// error(p, "local definition '%s' makes procedure argument inaccessible", name);
+// }
+
Symbol* sym = calloc(1, sizeof(Symbol));
sym->name = name;
sym->class = class;
Symbol* symbol_get(Parser* p, int class, char* name)
{
- for (Symbol* scope = p->scope; scope; scope = scope->next)
+ Symbol* sym = lookup(p, class, name);
+ if (!sym)
{
-// printf("SCOPE(n: %p):\n", scope->next);
- if (sym_matches(p, class, name, scope))
- {
- return scope;
- }
-
- for (Symbol* sym = scope->desc; sym; sym = sym->next)
- {
-// printf(" %s == %s %d\n", name, sym->name, sym_matches(p, class, name, scope));
- if (sym_matches(p, class, name, sym))
- {
- return sym;
- }
- }
+ error(p, "unknown identifier '%s'", name);
}
- error(p, "unknown identifier '%s'", name);
- return NULL;
+ return sym;
}
void symbol_openscope(Parser* p)