aboutsummaryrefslogtreecommitdiff
path: root/src/scope.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scope.c')
-rw-r--r--src/scope.c87
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);