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 */
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))
{
#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)
{
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;
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;
}
/* 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);
}
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;
}
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++;
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