diff options
Diffstat (limited to 'src/scope.c')
-rw-r--r-- | src/scope.c | 87 |
1 files changed, 46 insertions, 41 deletions
diff --git a/src/scope.c b/src/scope.c index 485b3a6..e49b828 100644 --- a/src/scope.c +++ b/src/scope.c @@ -30,8 +30,9 @@ struct scope *create_scope() scope->number = counter++; scope->symbols = visible_create(16); /* arbitrary number */ - scope->traits = visible_create(1); - scope->types = visible_create(1); + scope->templates = visible_create(0); + scope->traits = visible_create(0); + scope->types = visible_create(0); scope->mods = mod_vec_create(0); return scope; } @@ -47,12 +48,13 @@ void destroy_scope(struct scope *scope) } foreach(mod_vec, m, &scope->mods) { - dlclose(m); + dlclose(*m); } mod_vec_destroy(&scope->mods); visible_destroy(&scope->symbols); + visible_destroy(&scope->templates); visible_destroy(&scope->traits); visible_destroy(&scope->types); @@ -108,7 +110,7 @@ struct ast *file_scope_find_symbol(struct scope *scope, char *id) int scope_add_type(struct scope *scope, struct ast *type) { assert(type->k == AST_STRUCT_DEF); - struct ast **exists = visible_insert(&scope->symbols, type->s, type); + struct ast **exists = visible_insert(&scope->types, type->s, type); if (!exists) { internal_error("failed inserting type into scope"); return -1; @@ -123,42 +125,6 @@ int scope_add_type(struct scope *scope, struct ast *type) return 0; } -int scope_add_chain(struct scope *scope, struct ast *type) -{ - assert(type->k == AST_STRUCT_CONT); - struct ast *exists = file_scope_find_type(scope, type->s); - if (!exists) { - semantic_error(scope, type, "no previous definition"); - return -1; - } - - assert(exists->k == AST_STRUCT_DEF || exists->k == AST_STRUCT_CONT); - if (ast_flags(exists, AST_FLAG_PUBLIC) || !ast_flags(type, AST_FLAG_PUBLIC)) { - type->chain = exists; - struct ast **v = visible_insert(&scope->types, type->s, type); - if (!v) { - internal_error("failed inserting type into chain"); - return -1; - } - - /* overwrite root */ - if (*v != type) - *v = type; - - return 0; - } - - struct ast *next = exists->chain; - while (next->k == AST_STRUCT_CONT && !ast_flags(next, AST_FLAG_PUBLIC)) { - exists = next; - next = next->chain; - } - - exists->chain = type; - type->chain = exists; - return 0; -} - struct ast *scope_find_type(struct scope *scope, char *id) { struct ast **v = visible_find(&scope->types, id); @@ -183,7 +149,7 @@ struct ast *file_scope_find_type(struct scope *scope, char *id) int scope_add_trait(struct scope *scope, struct ast *trait) { assert(trait->k == AST_TRAIT_DEF); - struct ast **exists = visible_insert(&scope->symbols, trait->s, trait); + struct ast **exists = visible_insert(&scope->traits, trait->s, trait); if (!exists) { internal_error("failed inserting trait into scope"); return -1; @@ -197,6 +163,7 @@ int scope_add_trait(struct scope *scope, struct ast *trait) return 0; } + struct ast *scope_find_trait(struct scope *scope, char *id) { struct ast **v = visible_find(&scope->traits, id); @@ -218,6 +185,44 @@ struct ast *file_scope_find_trait(struct scope *scope, char *id) return file_scope_find_trait(scope->parent, id); } +int scope_add_template(struct scope *scope, struct ast *template) +{ + struct ast **exists = visible_insert(&scope->templates, template->s, template); + if (!exists) { + internal_error("failed inserting template into scope"); + return -1; + } + + if (*exists != template) { + semantic_error(scope, template, "template redefined"); + semantic_info(scope, *exists, "previously here"); + return -1; + } + + return 0; +} + +struct ast *scope_find_template(struct scope *scope, char *id) +{ + struct ast **v = visible_find(&scope->templates, id); + if (!v) + return NULL; + + return *v; +} + +struct ast *file_scope_find_template(struct scope *scope, char *id) +{ + if (!scope) + return NULL; + + struct ast *found = scope_find_template(scope, id); + if (found) + return found; + + return file_scope_find_template(scope->parent, id); +} + void scope_add_scope(struct scope *parent, struct scope *child) { assert(parent); |