From 6db09a318b4fb84c17e7d2a226606fbffd04737d Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 14 Jul 2021 16:47:50 -0400 Subject: [PATCH] sketched out strategy for module importing and aliasing as well as symbol resolution --- cerise/inc/cerise.h | 12 +++--------- cerise/src/grammar.c | 45 +++++++++++++++++++++++--------------------- cerise/src/sym.c | 17 +++++++++++++++-- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 779737f..9b4673c 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -113,29 +113,22 @@ typedef struct AstNode { typedef struct Symbol { enum{ - SYM_SCOPE, SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC, SYM_FIELD + SYM_MODULE, SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC } class; char* name; Type* type; struct Symbol* desc; AstNode* value; long nargs; + size_t module; int export : 1; int global : 1; } Symbol; -typedef struct Module { - struct Module* next; - Symbol* symbols; - char* name; - char* alias; -} Module; - typedef struct { LexFile* done; LexFile* file; Tok tok; - Module* imports; char* name; long curr_reg; size_t msyms; @@ -171,6 +164,7 @@ size_t symbol_getid(Parser* p, char* name, int class); Symbol* symbol_getbyid(Parser* p, size_t id); size_t symbol_openscope(Parser* p); void symbol_closescope(Parser* p, size_t scope); +void symbol_import(Parser* p, char* name, char* alias); // src/type_checks.c void check_int(Parser* p, AstNode* a); diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 125ffc7..f3a6478 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -58,13 +58,26 @@ static AstNode* qualident(Parser* p) { ENTER_RULE(); + AstNode* expr; char* name = expect_text(p, IDENT); - AstNode* expr = ast_ident(p, symbol_getid(p, name, -1)); + size_t symid = symbol_getid(p, name, -1); + Symbol* sym = symbol_getbyid(p, symid); -// if (accept(p, '.')) -// { -// expect(p, IDENT); -// } + if (sym->class == SYM_MODULE) + { + /* resolve the module aliasing */ + sym = symbol_getbyid(p, sym->module); + + /* now find the identifier we *really* care about */ + assert(!"module scoped identifiers not supported yet"); + expect(p, '.'); + char* name = expect_text(p, IDENT); + (void)name; + /* TODO: implement module ident access */ + } + + /* make the identifier with the final index */ + expr = ast_ident(p, symid); EXIT_RULE(); return expr; @@ -554,31 +567,21 @@ void proc_decl(Parser* p) static void import_list(Parser* p) { ENTER_RULE(); + expect(p, IMPORT); do { - Module* m = calloc(1, sizeof(Module)); - m->name = expect_text(p, IDENT); + char* name = expect_text(p, IDENT); + char* alias = NULL; if (accept(p, '=')) { - m->alias = m->name; - m->name = expect_text(p, IDENT); - m->next = p->imports; - p->imports = m; + alias = name; + name = expect_text(p, IDENT); } + symbol_import(p, name, alias); } while (matches(p, IDENT)); - /* reverse the list so when we init it happens in the right order */ - Module* imports = p->imports; - p->imports = NULL; - while (imports) - { - Module* m = imports; - imports = m->next; - m->next = p->imports; - p->imports = m; - } EXIT_RULE(); } diff --git a/cerise/src/sym.c b/cerise/src/sym.c index 2f6e5e0..56d9969 100644 --- a/cerise/src/sym.c +++ b/cerise/src/sym.c @@ -4,7 +4,6 @@ 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) @@ -68,7 +67,6 @@ Symbol* symbol_new(Parser* p, size_t scope, char* name, int class, bool export) { error(p, "symbol '%s' is multiply defined in the current scope", name); } -// puts(""); /* insert */ memset(&p->syms[p->nsyms], 0, sizeof(Symbol)); @@ -116,6 +114,21 @@ void symbol_closescope(Parser* p, size_t scope) p->nsyms = scope; } +void symbol_import(Parser* p, char* name, char* alias) +{ + Symbol* mod = symbol_new(p, 0, name, SYM_MODULE, false); + size_t modid = symbol_getid(p, mod->name, SYM_MODULE); + mod->module = modid; // Modules alias themselves...weird but works. + if (alias) + { + Symbol* modalias = symbol_new(p, 0, alias, SYM_MODULE, false); + modalias->module = modid; // This one is reall an alias + } + + /* TODO: read symbols from symbol file */ + // All of these should set ->module = modid +} + /* Symbol Table Unit Tests *****************************************************************************/ #ifdef CERISE_TESTS -- 2.49.0