From a2d0d951eaeb44b5979199decf9f231a6842be23 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Thu, 15 Jul 2021 16:07:07 -0400 Subject: [PATCH] implemented first pass at module coped identifiers. Still need to add symbol file genration and loading --- cerise/inc/cerise.h | 4 ++-- cerise/src/grammar.c | 13 ++++-------- cerise/src/sym.c | 49 ++++++++++++++++++++++++++++--------------- cerise/tests/Module.m | 10 +++++---- 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 9b4673c..1ec2c56 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -159,8 +159,8 @@ int consume(Parser* p); // src/sym.c Symbol* symbol_new(Parser* p, size_t scope, char* name, int class, bool export); -Symbol* symbol_get(Parser* p, char* name, int class); -size_t symbol_getid(Parser* p, char* name, int class); +Symbol* symbol_get(Parser* p, size_t module, char* name, int class); +size_t symbol_getid(Parser* p, size_t module, 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); diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index f3a6478..305318b 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -60,20 +60,15 @@ static AstNode* qualident(Parser* p) AstNode* expr; char* name = expect_text(p, IDENT); - size_t symid = symbol_getid(p, name, -1); + size_t symid = symbol_getid(p, 0, name, -1); Symbol* sym = symbol_getbyid(p, symid); + /* if symbol is a module, we must access something in it */ 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 */ + symid = symbol_getid(p, symid, name, -1); } /* make the identifier with the final index */ @@ -330,7 +325,7 @@ static Type* type(Parser* p) if (matches(p, IDENT)) { char* text = expect_text(p, IDENT); - ret = symbol_get(p, text, SYM_TYPE)->type; + ret = symbol_get(p, 0, text, SYM_TYPE)->type; } else if (accept(p, ARRAY)) { diff --git a/cerise/src/sym.c b/cerise/src/sym.c index 56d9969..daa55f2 100644 --- a/cerise/src/sym.c +++ b/cerise/src/sym.c @@ -2,9 +2,14 @@ #define NIL_SYMBOL ((size_t)-1) -static int sym_matches(Parser* p, int class, char* name, Symbol* sym) +/* TODO: module names should be shadowable but are not */ + +static int sym_matches(Parser* p, int class, size_t module, char* name, Symbol* sym) { - if (name && sym->name && !strcmp(sym->name, name)) + int mod_match = (sym->module == module); + int sym_ismod = (!module && (sym->class == SYM_MODULE)); + + if ((mod_match || sym_ismod) && name && sym->name && !strcmp(sym->name, name)) { if (class >= 0 && (int)sym->class != class) { @@ -36,7 +41,7 @@ static int sym_matches(Parser* p, int class, char* name, Symbol* sym) return 0; } -static size_t lookup(Parser* p, size_t scope, char* name, int class) +static size_t lookup(Parser* p, size_t scope, size_t module, char* name, int class) { size_t ret = NIL_SYMBOL; size_t count = p->nsyms - scope; @@ -44,7 +49,7 @@ static size_t lookup(Parser* p, size_t scope, char* name, int class) for (size_t i = 0; i < count; i++, curr--) { - if (sym_matches(p, class, name, &p->syms[curr])) + if (sym_matches(p, class, module, name, &p->syms[curr])) { ret = curr; break; @@ -63,7 +68,7 @@ Symbol* symbol_new(Parser* p, size_t scope, char* name, int class, bool export) } /* verify we're not redefining it in the current scope */ - if (NIL_SYMBOL != lookup(p, scope, name, class)) + if (NIL_SYMBOL != lookup(p, scope, 0, name, class)) { error(p, "symbol '%s' is multiply defined in the current scope", name); } @@ -79,15 +84,28 @@ Symbol* symbol_new(Parser* p, size_t scope, char* name, int class, bool export) return &(p->syms[p->nsyms-1]); } -size_t symbol_getid(Parser* p, char* name, int class) +Symbol* symbol_get(Parser* p, size_t module, char* name, int class) { - size_t index = lookup(p, 0, name, class); + size_t id = symbol_getid(p, module, name, class); + return symbol_getbyid(p, id); +} + +size_t symbol_getid(Parser* p, size_t module, char* name, int class) +{ + size_t index = lookup(p, 0, module, name, class); if (NIL_SYMBOL == index) { error(p, "unknown symbol '%s'", name); } + /* if symbol is a module, we must access something in it */ + Symbol* sym = symbol_getbyid(p, index); + if ((sym->class == SYM_MODULE) && (sym->module > 0)) + { + index = sym->module; + } + return index; } @@ -96,12 +114,6 @@ Symbol* symbol_getbyid(Parser* p, size_t id) return &(p->syms[id]); } -Symbol* symbol_get(Parser* p, char* name, int class) -{ - size_t id = symbol_getid(p, name, class); - return symbol_getbyid(p, id); -} - size_t symbol_openscope(Parser* p) { p->scope++; @@ -117,16 +129,19 @@ void symbol_closescope(Parser* p, size_t 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. + size_t modid = symbol_getid(p, 0, mod->name, SYM_MODULE); if (alias) { Symbol* modalias = symbol_new(p, 0, alias, SYM_MODULE, false); - modalias->module = modid; // This one is reall an alias + modalias->module = modid; // Points to the aliased module } - /* TODO: read symbols from symbol file */ + /* TODO: read symbols from real symbol file */ // All of these should set ->module = modid + + Symbol* sym = symbol_new(p, 0, "testint", SYM_CONST, false); + sym->module = modid; + sym->value = ast_int(42); } /* Symbol Table Unit Tests diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 836fe83..c12e223 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -1,8 +1,8 @@ module Module -#import -# A = Foo -# B = Bar +import + Foo + Bar3 = Bar2 const A = true @@ -152,5 +152,7 @@ begin # c = 42; # c = 24; - Bar(42); + Bar(Foo.testint); + Bar(Bar2.testint); + Bar(Bar3.testint); end -- 2.49.0