From: Michael D. Lowis Date: Sat, 5 Jun 2021 01:53:56 +0000 (-0400) Subject: reworking symbol table...very broken X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=4036dc5b0968a8b4f21a2ee5f05300420ac834d4;p=proto%2Fobnc.git reworking symbol table...very broken --- diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index bf5d62a..ebf6fe7 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -141,10 +141,11 @@ typedef struct { LexFile* file; Tok tok; Module* imports; - Symbol* scope; char* name; int curr_reg; - int level; + size_t msyms; + size_t nsyms; + Symbol* syms; } Parser; // src/stdlib.c @@ -168,11 +169,11 @@ char* expect_text(Parser* p, TokType type); int consume(Parser* p); // src/sym.c -Symbol* symbol_new(Parser* p, char* name, int class, bool export); +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, int class, char* name); -void symbol_openscope(Parser* p); -void symbol_closescope(Parser* p); +Symbol* symbol_get(Parser* p, char* name, int class); +size_t symbol_openscope(Parser* p); +void symbol_closescope(Parser* p, size_t scope); // src/type_checks.c void check_int(Parser* p, Item* item); diff --git a/cerise/ir.md b/cerise/ir.md new file mode 100644 index 0000000..4306f7b --- /dev/null +++ b/cerise/ir.md @@ -0,0 +1,38 @@ +Entry/Exit: + code Op code + mode Always "control" + next Link to next node + +Op: + code Op code + mode Vars, ImmFloat, ImmInt, Control + dest Var + arg[2] Var, Float, or Int + next Link to next node + +If: + code Op code + mode Always "control" + arg Var = conditional value + br_if Path for true + br_then Path for false + +Jump: + code Op code + mode Always "control" + arg Var = Destination address + next Link to next node + +Return: + code Op code + mode Always "control" + val Var + next Link to next node + +Call: + code Op code + mode Always "control" + dest Var + nargs Number of args + args Array of args + next Link to next node diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index d82edbb..4c3357a 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -100,7 +100,7 @@ static void expression(Parser* p, Item* item); RULE(qualident) { char* name = expect_text(p, IDENT); - Symbol* sym = symbol_get(p, -1, name); + Symbol* sym = symbol_get(p, name, -1); init_item(item, sym); // if (accept(p, '.')) @@ -211,7 +211,7 @@ RULE(factor) designator(p, item); if (accept(p, '(')) { - Symbol* proc = symbol_get(p, SYM_PROC, item->imm.s); + Symbol* proc = symbol_get(p, item->imm.s, SYM_PROC); Symbol* args = proc->desc; Item arglist = {0}; Item** currarg = &(arglist.next); @@ -342,7 +342,7 @@ RULE(type) if (matches(p, IDENT)) { char* text = expect_text(p, IDENT); - Symbol* sym = symbol_get(p, SYM_TYPE, text); + Symbol* sym = symbol_get(p, text, SYM_TYPE); item->type = sym->type; } else if (accept(p, ARRAY)) @@ -471,7 +471,7 @@ RULE(var_decl) { name = expect_text(p, IDENT); export = accept(p, '*'); - sym = symbol_new(p, name, SYM_VAR, export); + sym = symbol_new(p, 0, name, SYM_VAR, export); first = (nsyms == 0 ? sym : first); sym->global = (p->level <= 1 ? 1 : 0); nsyms++; @@ -503,7 +503,7 @@ RULE(type_decl) { name = expect_text(p, IDENT); export = accept(p, '*'); - sym = symbol_new(p, name, SYM_TYPE, export); + sym = symbol_new(p, 0, name, SYM_TYPE, export); expect(p, '='); type(p, item); sym->type = item->type; @@ -521,7 +521,7 @@ RULE(const_decl) { name = expect_text(p, IDENT); export = accept(p, '*'); - sym = symbol_new(p, name, SYM_CONST, export); + sym = symbol_new(p, 0, name, SYM_CONST, export); expect(p, '='); expression(p, item); @@ -536,7 +536,7 @@ RULE(proc_decl) expect(p, PROCEDURE); char* name = expect_text(p, IDENT); bool export = accept(p, '*'); - Symbol* proc = symbol_new(p, name, SYM_PROC, export); + Symbol* proc = symbol_new(p, 0, name, SYM_PROC, export); /* construct the proc type */ expect(p, '('); @@ -561,7 +561,7 @@ RULE(proc_decl) } codegen_startproc(p, proc); - symbol_openscope(p); + size_t scope = symbol_openscope(p); /* parse the declarations */ if (accept(p, CONST)) @@ -604,7 +604,7 @@ RULE(proc_decl) expect(p, END); codegen_endproc(p); - symbol_closescope(p); + symbol_closescope(p, scope); } RULE(import_list) @@ -639,7 +639,7 @@ RULE(import_list) RULE(module) { - symbol_openscope(p); + size_t scope = symbol_openscope(p); expect(p, MODULE); p->name = expect_text(p, IDENT); @@ -684,7 +684,7 @@ RULE(module) error(p, "expected end of file"); } - symbol_closescope(p); + symbol_closescope(p, scope); } static inline char* file_load(char* path) diff --git a/cerise/src/sym.c b/cerise/src/sym.c index 97a021a..2f83d71 100644 --- a/cerise/src/sym.c +++ b/cerise/src/sym.c @@ -1,9 +1,9 @@ #include "cerise.h" +#define NIL_SYMBOL ((size_t)-1) + static int sym_matches(Parser* p, int class, char* name, Symbol* sym) { -// printf(" %s == %s\n", name, sym->name); - if (name && sym->name && !strcmp(sym->name, name)) { if (class >= 0 && (int)sym->class != class) @@ -36,68 +36,74 @@ static int sym_matches(Parser* p, int class, char* name, Symbol* sym) return 0; } -static Symbol* lookup(Parser* p, int class, char* name) +static size_t lookup(Parser* p, size_t scope, char* name, int class) { - for (Symbol* scope = p->scope; scope; scope = scope->next) + size_t ret = NIL_SYMBOL; + size_t count = p->nsyms - scope; + size_t curr = p->nsyms - 1u; + + for (size_t i = 0; i < count; i++, curr--) { -// printf("SCOPE(n: %p):\n", scope->next); - if (sym_matches(p, class, name, scope)) + if (sym_matches(p, class, name, &p->syms[curr])) { - 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; - } + ret = curr; + break; } } - return NULL; -} + return ret; +} -Symbol* symbol_new(Parser* p, char* name, int class, bool export) +Symbol* symbol_new(Parser* p, size_t scope, char* name, int class, bool export) { - Symbol* prev = NULL; - Symbol* curr = p->scope->desc; + if (p->nsyms == p->msyms) + { + p->msyms = (p->msyms ? (p->msyms << 1) : 512u); + p->syms = realloc(p->syms, p->msyms * sizeof(Symbol)); + } -// printf("\nsymbol_new(%s)\n", name); - while (curr) + /* verify we're not redefining it in the current scope */ + if (NIL_SYMBOL != lookup(p, scope, name, class)) { -// 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; + error(p, "symbol '%s' is multiply defined in the current scope", name); } -// 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); -// } + /* insert */ + p->syms[p->nsyms].name = name; + p->syms[p->nsyms].class = class; + p->syms[p->nsyms].export = export; + p->nsyms++; - Symbol* sym = calloc(1, sizeof(Symbol)); - sym->name = name; - sym->class = class; - sym->export = export; - if (prev) + return &(p->syms[p->nsyms-1]); +} + +Symbol* symbol_get(Parser* p, char* name, int class) +{ + Symbol* sym = NULL; + size_t index = lookup(p, 0, name, class); + + if (NIL_SYMBOL != index) { - prev->next = sym; + error(p, "unknown symbol '%s'", name); } else { - p->scope->desc = sym; + sym = &(p->syms[index]); } + return sym; } +size_t symbol_openscope(Parser* p) +{ + return p->nsyms; +} + +void symbol_closescope(Parser* p, size_t scope) +{ + p->nsyms = scope; +} + Symbol* symbol_addfield(Parser* p, Symbol* parent, char* name, int class, bool export) { Symbol* prev = NULL; @@ -130,32 +136,6 @@ Symbol* symbol_addfield(Parser* p, Symbol* parent, char* name, int class, bool e return sym; } -Symbol* symbol_get(Parser* p, int class, char* name) -{ - Symbol* sym = lookup(p, class, name); - if (!sym) - { - error(p, "unknown identifier '%s'", name); - } - return sym; -} - -void symbol_openscope(Parser* p) -{ - Symbol* scope = calloc(1, sizeof(Symbol)); - scope->class = SYM_SCOPE; - scope->desc = NULL; - scope->next = p->scope; - p->scope = scope; - p->level++; -} - -void symbol_closescope(Parser* p) -{ - p->scope = p->scope->next; - p->level--; -} - /* Symbol Table Unit Tests *****************************************************************************/ #ifdef CERISE_TESTS