From cdc7045b67528fde6a25f89bda5fd5520535e584 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 5 May 2021 12:35:35 -0400 Subject: [PATCH] Added logic for parsing args and adding them to symbol table --- cerise/backend/c99/codegen.c | 10 +++--- cerise/backend/test/codegen.c | 4 +-- cerise/backend/x86_64/codegen.c | 9 +++-- cerise/inc/cerise.h | 3 +- cerise/src/grammar.c | 23 ++++++------ cerise/src/lex.c | 62 +++++++++++++++++++++++++++++++++ cerise/src/parse.c | 21 ++++++++++- cerise/src/sym.c | 36 +++++++++++++++++-- cerise/tests/Module.m | 3 +- 9 files changed, 141 insertions(+), 30 deletions(-) diff --git a/cerise/backend/c99/codegen.c b/cerise/backend/c99/codegen.c index 6f0918f..08e6f44 100644 --- a/cerise/backend/c99/codegen.c +++ b/cerise/backend/c99/codegen.c @@ -153,16 +153,16 @@ void codegen_main(Parser* p) printf("}\n"); } -void codegen_startproc(Parser* p, char* name, bool exported) +void codegen_startproc(Parser* p, Symbol* proc) { - char* export = (exported ? "" : "static"); - if (!name) + if (!proc) { - printf("\n%svoid %s(void) {\n", export, p->name); + printf("\nvoid %s(void) {\n", p->name); } else { - printf("\n%svoid %s_%s(void) {\n", export, p->name, name); + char* export = (proc->export ? "" : "static"); + printf("\n%svoid %s_%s(void) {\n", export, p->name, proc->name); } } diff --git a/cerise/backend/test/codegen.c b/cerise/backend/test/codegen.c index b25a13d..47a2a62 100644 --- a/cerise/backend/test/codegen.c +++ b/cerise/backend/test/codegen.c @@ -61,9 +61,9 @@ void codegen_main(Parser* p) (void)p; } -void codegen_startproc(Parser* p, char* name, bool exported) +void codegen_startproc(Parser* p, Symbol* proc) { - (void)p, (void)name, (void)exported; + (void)p, (void)proc; } void codegen_endproc(Parser* p) diff --git a/cerise/backend/x86_64/codegen.c b/cerise/backend/x86_64/codegen.c index b5752a7..4a4f0ee 100644 --- a/cerise/backend/x86_64/codegen.c +++ b/cerise/backend/x86_64/codegen.c @@ -236,14 +236,13 @@ void codegen_main(Parser* p) printf(" ret\n"); } -void codegen_startproc(Parser* p, char* name, bool exported) +void codegen_startproc(Parser* p, Symbol* proc) { - (void)exported; printf(" .text\n"); - if (name) + if (proc) { - printf(" .globl %s_%s\n", p->name, name); - printf("%s_%s:\n", p->name, name); + printf(" .globl %s_%s\n", p->name, proc->name); + printf("%s_%s:\n", p->name, proc->name); } else { diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 09f7012..b8db0ac 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -175,6 +175,7 @@ int consume(Parser* p); // src/sym.c Symbol* symbol_new(Parser* p, 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); @@ -208,7 +209,7 @@ void codegen_setstr(Item* item, char* val); void codegen_imports(Parser* p); void codegen_var(Parser* p, Symbol* sym); void codegen_main(Parser* p); -void codegen_startproc(Parser* p, char* name, bool exported); +void codegen_startproc(Parser* p, Symbol* func); void codegen_endproc(Parser* p); void codegen_unop(Parser* p, int op, Item* a); void codegen_binop(Parser* p, int op, Item* a, Item* b); diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 6cf40c5..3b23f08 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -450,11 +450,9 @@ RULE(proc_decl) expect(p, PROCEDURE); char* name = expect_text(p, IDENT); bool export = accept(p, '*'); - Symbol* sym = symbol_new(p, name, SYM_PROC, export); - Symbol** args = &(sym->desc); - symbol_openscope(p); - codegen_startproc(p, name, export); - (void)args; + Symbol* proc = symbol_new(p, name, SYM_PROC, export); +// Symbol** args = &(sym->desc); +// (void)args; /* construct the proc type */ expect(p, '('); @@ -463,17 +461,20 @@ RULE(proc_decl) char* name = expect_text(p, IDENT); expect(p, ':'); type(p, item); - sym->nargs++; - // TODO: Added argument symbol here... - (void)name; + proc->nargs++; + Symbol* arg = symbol_addfield(p, proc, name, SYM_VAR, false); + arg->type = item->type; } expect(p, ')'); if (accept(p, ':')) { type(p, item); - sym->type = item->type; + proc->type = item->type; } + codegen_startproc(p, proc); + symbol_openscope(p); + /* parse the declarations */ if (accept(p, CONST)) { @@ -507,11 +508,11 @@ RULE(proc_decl) expect(p, ';'); } expect(p, END); + symbol_closescope(p); codegen_endproc(p); } - RULE(import_list) { (void)item; @@ -575,7 +576,7 @@ RULE(module) proc_decl(p, item); } - codegen_startproc(p, NULL, true); + codegen_startproc(p, NULL); if (accept(p, BEGIN)) { codegen_imports(p); diff --git a/cerise/src/lex.c b/cerise/src/lex.c index 5c52bb9..72e87d5 100644 --- a/cerise/src/lex.c +++ b/cerise/src/lex.c @@ -346,6 +346,68 @@ void lexprintpos(Parser* p, FILE* file, Tok* tok) fprintf(file, "%s:%zu:%zu:", tok->file, line, col); } +char* TokTypes[] = { + ['"'] = "\"", + ['='] = "=", + ['.'] = ".", + ['<'] = "<", + ['>'] = ">", + ['!'] = "!", + ['('] = "(", + [')'] = ")", + ['['] = "[", + [']'] = "]", + ['{'] = "{", + ['}'] = "}", + [','] = ",", + [':'] = ":", + [';'] = ";", + ['^'] = "^", + ['+'] = "+", + ['-'] = "-", + ['*'] = "*", + ['/'] = "/", + ['|'] = "|", + ['%'] = "%", + [EQ] = "==", + [NEQ] = "!=", + [LTEQ] = "<=", + [GTEQ] = ">=", + [DOTDOT] = "..", + [AND] = "and", + [ARRAY] = "array", + [BEGIN] = "begin", + [BY] = "by", + [CASE] = "case", + [CONST] = "const", + [DIV] = "div", + [DO] = "do", + [ELSE] = "else", + [ELSIF] = "elsif", + [END] = "end", + [FOR] = "for", + [IF] = "if", + [IMPORT] = "import", + [IS] = "is", + [MOD] = "mod", + [MODULE] = "module", + [NIL] = "nil", + [NOT] = "not", + [OF] = "of", + [OR] = "or", + [POINTER] = "pointer", + [PROCEDURE] = "procedure", + [RECORD] = "record", + [REPEAT] = "repeat", + [RETURN] = "return", + [THEN] = "then", + [TO] = "to", + [TYPE] = "type", + [UNTIL] = "until", + [VAR] = "var", + [WHILE] = "while", +}; + #ifdef CERISE_TESTS #include "atf.h" diff --git a/cerise/src/parse.c b/cerise/src/parse.c index 29ed6e1..c4e5d06 100644 --- a/cerise/src/parse.c +++ b/cerise/src/parse.c @@ -1,5 +1,8 @@ #include "cerise.h" +/* for token mismatch errors */ +extern char* TokTypes[]; + Tok* peek(Parser* p) { if (NONE == p->tok.type) @@ -49,7 +52,23 @@ bool accept(Parser* p, TokType type) void expect(Parser* p, TokType type) { if (!accept(p, type)) - error(p, "Unexpected token"); + { + char* expect = TokTypes[type]; + char* recv = TokTypes[peek(p)->type]; + + if (expect && recv) + { + error(p, "expected '%s', recieved '%s'", expect, recv); + } + else if (expect) + { + error(p, "expected '%s'", expect); + } + else + { + error(p, "Unexpected token"); + } + } } Tok* expect_val(Parser* p, TokType type) diff --git a/cerise/src/sym.c b/cerise/src/sym.c index fde58ac..c127493 100644 --- a/cerise/src/sym.c +++ b/cerise/src/sym.c @@ -61,17 +61,47 @@ Symbol* symbol_new(Parser* p, char* name, int class, bool export) { p->scope->desc = sym; } -// p->scope->desc = sym; - assert(sym); return sym; } +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* symbol_get(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; diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 051012e..77d2f1a 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -18,13 +18,12 @@ type var a : Bool - z : Int b : Int c : Int procedure Foo*(e : Int) : Int const FOO = 2 -# type foo : Int + type foo = Int var z : Int begin c = b * b; -- 2.49.0