diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-01-10 22:59:41 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-01-10 23:01:35 +0200 |
| commit | 2d90cea9adb9a3f73cd5b211a4ed9508b505729f (patch) | |
| tree | 78f9cde6d162fbda9352d2c668ac00a298815b19 /src/scope.c | |
| parent | dbf3ed3db10f9fa9157d661704e16ba5b73b0e84 (diff) | |
| download | ek-2d90cea9adb9a3f73cd5b211a4ed9508b505729f.tar.gz ek-2d90cea9adb9a3f73cd5b211a4ed9508b505729f.zip | |
initial struct continuations implemented
Diffstat (limited to 'src/scope.c')
| -rw-r--r-- | src/scope.c | 164 |
1 files changed, 137 insertions, 27 deletions
diff --git a/src/scope.c b/src/scope.c index f17b8ed..448c883 100644 --- a/src/scope.c +++ b/src/scope.c @@ -200,6 +200,64 @@ int scope_add_type(struct scope *scope, char *id, struct ast *type) return 0; } +static struct visible *scope_find_visible(struct visible *v, char *id) +{ + if (!v) + return NULL; + + foreach_visible(n, v) { + struct ast *node = n->node; + if (same_id(node->s, id)) + return n; + } + + return NULL; +} + +static void insert_chain(struct scope *scope, char *id, struct ast *type) +{ + struct visible *v = scope_find_visible(scope->types, id); + assert(v); + + struct ast *n = v->node; + assert(n); + + if (ast_flags(n, AST_FLAG_PUBLIC) + || !ast_flags(type, AST_FLAG_PUBLIC)) { + type->chain = v->node; + v->node = type; + return; + } + + /* find first public continuation in chain and insert just before it */ + struct ast *next = n->chain; + while (next->k == AST_STRUCT_CONT_DEF && !ast_flags(next, + AST_FLAG_PUBLIC)) { + n = next; + next = n->chain; + } + + n->chain = type; + type->chain = next; +} + +int scope_add_chain(struct scope *scope, char *id, struct ast *type) +{ + struct ast *exists = file_scope_find_type(scope, id); + if (!exists) { + semantic_error(scope->fctx, type, "no previous definition"); + return -1; + } + + insert_chain(scope, id, type); + + if (scope->parent && + scope_flags(scope, SCOPE_FILE) && ast_flags(type, AST_FLAG_PUBLIC)) + return scope_add_chain(scope->parent, id, type); + + return 0; +} + int scope_add_macro(struct scope *scope, struct ast *macro) { assert(macro->k == AST_MACRO_DEF); @@ -262,6 +320,7 @@ int scope_add_expd_struct(struct scope *scope, struct ast *def, struct type *types, struct ast *expd) { assert(def->k == AST_STRUCT_DEF); + assert(expd->k == AST_STRUCT_DEF); assert(file_scope_find_expd_struct(scope, def, types) == NULL); create_expanded(scope, def, types, expd); @@ -272,40 +331,75 @@ int scope_add_expd_struct(struct scope *scope, struct ast *def, return 0; } -static struct ast *scope_find_visible(struct visible *v, char *id) +static struct expanded *scope_find_expanded(struct expanded *e, struct ast *def, + struct type *types) { - if (!v) + if (!e) return NULL; - foreach_visible(n, v) { - struct ast *node = n->node; - if (same_id(node->s, id)) - return node; + foreach_expanded(n, e) { + if (n->node != def) + continue; + + if (type_lists_match(n->types, types)) + return n; } return NULL; } -static struct ast *scope_find_expanded(struct expanded *e, struct ast *def, - struct type *types) +static void insert_expd_chain(struct scope *scope, struct ast *def, + struct type *types, struct ast *expd) { - if (!e) - return NULL; + struct expanded *e = scope_find_expanded(scope->expanded, def, types); + assert(e); - foreach_expanded(n, e) { - if (n->node != def) - continue; + struct ast *n = e->expd; + assert(n); - if (type_lists_match(n->types, types)) - return n->expd; + if (ast_flags(n, AST_FLAG_PUBLIC) + || !ast_flags(expd, AST_FLAG_PUBLIC)) { + expd->chain = e->expd; + e->expd = expd; + /* types should be identical, we checked that earlier */ + return; } - return NULL; + /* find first public continuation in chain and insert just before it */ + struct ast *next = n->chain; + while (next->k == AST_STRUCT_CONT_DEF && + !ast_flags(next, AST_FLAG_PUBLIC)) { + n = next; + next = n->chain; + } + + n->chain = expd; + expd->chain = next; +} + +int scope_add_expd_chain(struct scope *scope, struct ast *def, + struct type *types, struct ast *expd) +{ + assert(def->k == AST_STRUCT_DEF); + assert(expd->k == AST_STRUCT_CONT_DEF); + assert(file_scope_find_expd_struct(scope, def, types) != NULL); + + insert_expd_chain(scope, def, types, expd); + + if (scope->parent && + scope_flags(scope, SCOPE_FILE) && ast_flags(def, AST_FLAG_PUBLIC)) + return scope_add_expd_struct(scope->parent, def, types, expd); + + return 0; } struct ast *scope_find_type(struct scope *scope, char *id) { - return scope_find_visible(scope->types, id); + struct visible *v = scope_find_visible(scope->types, id); + if (!v) + return NULL; + + return v->node; } struct ast *file_scope_find_type(struct scope *scope, char *id) @@ -325,7 +419,11 @@ struct ast *file_scope_find_type(struct scope *scope, char *id) struct ast *scope_find_macro(struct scope *scope, char *id) { - return scope_find_visible(scope->macros, id); + struct visible *v = scope_find_visible(scope->macros, id); + if (!v) + return NULL; + + return v->node; } struct ast *file_scope_find_macro(struct scope *scope, char *id) @@ -345,10 +443,13 @@ struct ast *file_scope_find_macro(struct scope *scope, char *id) struct ast *scope_find_proc(struct scope *scope, char *id) { - struct ast *n = scope_find_visible(scope->symbols, id); - if (!n) + struct visible *v = scope_find_visible(scope->symbols, id); + if (!v) return NULL; + struct ast *n = v->node; + assert(n); + if (n->k != AST_PROC_DEF) return NULL; @@ -369,7 +470,11 @@ struct ast *file_scope_find_proc(struct scope *scope, char *id) struct ast *scope_find_symbol(struct scope *scope, char *id) { - return scope_find_visible(scope->symbols, id); + struct visible *v = scope_find_visible(scope->symbols, id); + if (!v) + return NULL; + + return v->node; } struct ast *file_scope_find_symbol(struct scope *scope, char *id) @@ -389,10 +494,13 @@ struct ast *file_scope_find_symbol(struct scope *scope, char *id) struct ast *scope_find_var(struct scope *scope, char *id) { - struct ast *n = scope_find_visible(scope->symbols, id); - if (!n) + struct visible *v = scope_find_visible(scope->symbols, id); + if (!v) return NULL; + struct ast *n = v->node; + assert(n); + if (n->k != AST_VAR_DEF) return NULL; @@ -418,18 +526,20 @@ struct ast *scope_find_expd_struct(struct scope *scope, struct ast *def, struct type *types) { assert(def->k == AST_STRUCT_DEF); - struct ast *exists = scope_find_expanded(scope->expanded, def, types); - if (!exists) + struct expanded *expd = scope_find_expanded(scope->expanded, def, + types); + if (!expd) return NULL; - assert(exists->k == AST_STRUCT_DEF); + struct ast *exists = expd->expd; + assert(exists->k == AST_STRUCT_DEF || exists->k == AST_STRUCT_CONT_DEF); return exists; } struct ast *file_scope_find_expd_struct(struct scope *scope, struct ast *def, struct type *types) { - assert(def->k == AST_STRUCT_DEF); + assert(def->k == AST_STRUCT_DEF || def->k == AST_STRUCT_CONT_DEF); struct ast *found = scope_find_expd_struct(scope, def, types); if (found) return found; |
