From 569c56bf91772a579745af82fc5c8e70fe62cc53 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 5 May 2021 10:03:58 -0400 Subject: [PATCH] mostly fixed symbol table. Need to fix the procedure code generation --- cerise/backend/c99/codegen.c | 39 +++++++++++++--------- cerise/backend/test/codegen.c | 2 +- cerise/backend/x86_64/codegen.c | 2 +- cerise/inc/cerise.h | 3 +- cerise/src/grammar.c | 22 ++++++++---- cerise/src/sym.c | 59 ++++++++++++++++++++++----------- cerise/tests/Module.m | 1 + 7 files changed, 83 insertions(+), 45 deletions(-) diff --git a/cerise/backend/c99/codegen.c b/cerise/backend/c99/codegen.c index 54a4873..6f0918f 100644 --- a/cerise/backend/c99/codegen.c +++ b/cerise/backend/c99/codegen.c @@ -131,10 +131,17 @@ void codegen_imports(Parser* p) (void)p; } -void codegen_global(Parser* p, Symbol* sym) +void codegen_var(Parser* p, Symbol* sym) { - printf("%s%s %s_%s;\n", - (sym->export ? "" : "static "), TypeNames[sym->type->form], p->name, sym->name); + if (sym->global) + { + printf("%s%s %s_%s;\n", + (sym->export ? "" : "static "), TypeNames[sym->type->form], p->name, sym->name); + } + else + { + printf(" %s %s;\n", TypeNames[sym->type->form], sym->name); + } } void codegen_main(Parser* p) @@ -155,7 +162,7 @@ void codegen_startproc(Parser* p, char* name, bool exported) } else { - assert(!"not implemented"); + printf("\n%svoid %s_%s(void) {\n", export, p->name, name); } } @@ -237,9 +244,9 @@ void codegen_prepcall(Parser* p, Item* item) // 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++; + 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) @@ -255,13 +262,13 @@ void codegen_call(Parser* p, Item* item) 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); -// } + (void)p, (void)item; + if (item->mode == ITEM_CONST) + { + printf("%s%lld", (!firstarg ? ", " : ""), item->imm.i); + } + else + { + printf("%s_T%d", (!firstarg ? ", " : ""), item->reg); + } } diff --git a/cerise/backend/test/codegen.c b/cerise/backend/test/codegen.c index 5de6cf1..b25a13d 100644 --- a/cerise/backend/test/codegen.c +++ b/cerise/backend/test/codegen.c @@ -51,7 +51,7 @@ void codegen_imports(Parser* p) (void)p; } -void codegen_global(Parser* p, Symbol* sym) +void codegen_var(Parser* p, Symbol* sym) { (void)p, (void)sym; } diff --git a/cerise/backend/x86_64/codegen.c b/cerise/backend/x86_64/codegen.c index c8b06d1..b5752a7 100644 --- a/cerise/backend/x86_64/codegen.c +++ b/cerise/backend/x86_64/codegen.c @@ -216,7 +216,7 @@ void codegen_imports(Parser* p) } } -void codegen_global(Parser* p, Symbol* sym) +void codegen_var(Parser* p, Symbol* sym) { printf(" .data\n"); printf("%s_%s:\n", p->name, sym->name); diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 37feb3e..09f7012 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -129,6 +129,7 @@ typedef struct { Symbol* scope; char* name; int curr_reg; + int level; } Parser; static inline void item_dump(Item* a) @@ -205,7 +206,7 @@ void codegen_setint(Item* item, Type* type, long long val); void codegen_setreal(Item* item, double val); void codegen_setstr(Item* item, char* val); void codegen_imports(Parser* p); -void codegen_global(Parser* p, Symbol* sym); +void codegen_var(Parser* p, Symbol* sym); void codegen_main(Parser* p); void codegen_startproc(Parser* p, char* name, bool exported); void codegen_endproc(Parser* p); diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 7ff70b7..6cf40c5 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -66,6 +66,7 @@ RULE(param_list) (void)item; int nargs = 0; Item argdef = {0}; + (void)argdef; if (!matches(p, ')')) { Item arg = {0}; @@ -374,6 +375,7 @@ RULE(var_decl) do { int nsyms = 0; + Symbol* first = NULL; Symbol* sym = NULL; Symbol* type = NULL; char* name = NULL; @@ -384,7 +386,8 @@ RULE(var_decl) name = expect_text(p, IDENT); export = accept(p, '*'); sym = symbol_new(p, name, SYM_VAR, export); - sym->global = 1; + first = (nsyms == 0 ? sym : first); + sym->global = (p->level <= 1 ? 1 : 0); nsyms++; } while (accept(p, ',')); @@ -396,9 +399,9 @@ RULE(var_decl) /* apply the type to the newly created symbols */ for (int i = 0; i < nsyms; i++) { - sym->type = type->type; - codegen_global(p, sym); - sym = sym->next; + first->type = type->type; + codegen_var(p, first); + sym = first->next; } } while (matches(p, IDENT)); @@ -450,6 +453,8 @@ RULE(proc_decl) Symbol* sym = symbol_new(p, name, SYM_PROC, export); Symbol** args = &(sym->desc); symbol_openscope(p); + codegen_startproc(p, name, export); + (void)args; /* construct the proc type */ expect(p, '('); @@ -460,6 +465,7 @@ RULE(proc_decl) type(p, item); sym->nargs++; // TODO: Added argument symbol here... + (void)name; } expect(p, ')'); if (accept(p, ':')) @@ -502,6 +508,7 @@ RULE(proc_decl) } expect(p, END); symbol_closescope(p); + codegen_endproc(p); } @@ -630,15 +637,15 @@ void compile(char* fname) Parser Ctx = {0}; static Symbol InitialScope = { - .next = &IntSym, + .next = &RealSym, .class = SYM_SCOPE, }; - static void parse_init(char* fname, char* string) { memset(&Ctx, 0, sizeof(Ctx)); Ctx.scope = &InitialScope; + InitialScope.desc = NULL; LexFile* file = calloc(sizeof(LexFile), 1u); file->path = strdup(fname); file->fbeg = file->fpos = strdup(string); @@ -648,6 +655,8 @@ static void parse_init(char* fname, char* string) static void parse_rule(void (*rule)(Parser*, Item*), Item* item, char* string) { + puts(""); + printf("%s\n", string); parse_init("test_input", string); rule(&Ctx, (item ? item : &(Item){0})); } @@ -735,6 +744,5 @@ TEST_SUITE(Grammar) "end" ); } - } #endif diff --git a/cerise/src/sym.c b/cerise/src/sym.c index 2797ccc..fde58ac 100644 --- a/cerise/src/sym.c +++ b/cerise/src/sym.c @@ -34,31 +34,43 @@ static int sym_matches(Parser* p, int class, char* name, Symbol* sym) Symbol* symbol_new(Parser* p, char* name, int class, bool export) { -// Symbol* scope = p->scope; -// while () -// { -// } + Symbol* prev = NULL; + Symbol* curr = p->scope->desc; + +// printf("\nsymbol_new(%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; - sym->next = p->scope; - p->scope = sym; + if (prev) + { + prev->next = sym; + } + else + { + p->scope->desc = sym; + } +// p->scope->desc = sym; + assert(sym); return sym; } Symbol* symbol_get(Parser* p, int class, char* name) { - Symbol* scope = p->scope; - Symbol* sym = NULL; - for (Symbol* scope = p->scope; scope; scope = scope->next) { - if (scope) - { - printf("SCOPE:\n"); - } +// printf("SCOPE(n: %p):\n", scope->next); if (sym_matches(p, class, name, scope)) { @@ -67,15 +79,13 @@ Symbol* symbol_get(Parser* p, int class, char* name) for (Symbol* sym = scope->desc; sym; sym = sym->next) { - printf(" %s == %s %d\n", name, sym->name, sym_matches(p, class, name, scope)); - +// 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); return NULL; } @@ -84,12 +94,23 @@ void symbol_openscope(Parser* p) { Symbol* scope = calloc(1, sizeof(Symbol)); scope->class = SYM_SCOPE; - scope->desc = p->scope; - scope->next = NULL; + scope->desc = NULL; + scope->next = p->scope; p->scope = scope; + p->level++; } void symbol_closescope(Parser* p) { - p->scope = p->scope->desc; + p->scope = p->scope->next; + p->level--; } + +/* Symbol Table Unit Tests + *****************************************************************************/ +#ifdef CERISE_TESTS +#include "atf.h" + + + +#endif \ No newline at end of file diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 74a7835..051012e 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -18,6 +18,7 @@ type var a : Bool + z : Int b : Int c : Int -- 2.49.0