diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-01-11 16:30:39 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-01-11 16:30:39 +0200 |
| commit | 45b3531e29c1b596f1be123de94b7c618c92bf8a (patch) | |
| tree | 6fe6c326df6d8c8875a3ece1db17e9766030d579 /src | |
| parent | 47f1d503ec663f967302b3071177c40c431b3fdb (diff) | |
| download | ek-45b3531e29c1b596f1be123de94b7c618c92bf8a.tar.gz ek-45b3531e29c1b596f1be123de94b7c618c92bf8a.zip | |
multiple import stuff
Diffstat (limited to 'src')
| -rw-r--r-- | src/actualize.c | 32 | ||||
| -rw-r--r-- | src/ast.c | 2 | ||||
| -rw-r--r-- | src/scope.c | 58 |
3 files changed, 69 insertions, 23 deletions
diff --git a/src/actualize.c b/src/actualize.c index 7f590c3..e17305c 100644 --- a/src/actualize.c +++ b/src/actualize.c @@ -343,9 +343,17 @@ static int analyze_visibility(struct scope *scope, struct ast *node) case AST_IMPORT: { const char *file = import_file(node); - return process_file(&scope, + int ret = process_file(&scope, (int)ast_flags(node, AST_FLAG_PUBLIC), file); + + if (ret == 0) + return 0; + + /** @todo should maybe make this some other type of error, kind + * of too busy atm */ + semantic_info(scope->fctx, node, "imported here"); + return ret; } case AST_IF: { @@ -823,6 +831,26 @@ static int expand_chain(struct ast *expd, struct ast *params, return expand_type(expd, params, types); } +static struct ast *chain_graft(struct ast *exists, struct ast *def, + struct ast *params, struct type *types) +{ + if (same_src(exists, def)) + return exists; + + assert(def->chain); + struct ast *graft = chain_graft(exists, def->chain, params, types); + if (!graft) + return NULL; + + struct ast *new = clone_ast(def); + new->chain = graft; + + if (expand_type(new, params, types)) + return NULL; + + return new; +} + static struct ast *maybe_expand_struct_cont(struct scope *scope, struct ast *def, struct src_loc loc, @@ -842,7 +870,7 @@ static struct ast *maybe_expand_struct_cont(struct scope *scope, struct ast *exists = file_scope_find_expd_struct(scope, base, args); if (exists) - return exists; + return chain_graft(exists, def, struct_params(base), args); if (!should_implement_list(scope, struct_params(base), loc, args)) return NULL; @@ -150,7 +150,7 @@ void ast_clear_flags(struct ast *node, enum ast_flags flags) unsigned ast_flags(struct ast *node, enum ast_flags flags) { - return node->f & flags; + return (node->f & flags) == flags; } void ast_append(struct ast **list, struct ast *elem) diff --git a/src/scope.c b/src/scope.c index 198e2c0..6687d98 100644 --- a/src/scope.c +++ b/src/scope.c @@ -17,6 +17,12 @@ #include <ek/scope.h> #include <ek/actualize.h> +static bool same_src_scope(struct scope *a, struct scope *b) +{ + /** @todo a bit ridiculous, is there a less hacky way? */ + return a->fctx.fbuf == b->fctx.fbuf; +} + struct scope *create_scope() { /* if I ever try making the parser multithreaded, this should be atomic. */ @@ -87,7 +93,7 @@ void scope_set_flags(struct scope *scope, enum scope_flags flags) unsigned scope_flags(struct scope *scope, enum scope_flags flags) { assert(scope); - return scope->flags & flags; + return (scope->flags & flags) == flags; } static struct visible *create_visible(char *id, struct ast *node) @@ -166,6 +172,20 @@ struct visible *create_proc(struct scope *scope, char *id, struct ast *proc) return n; } +static bool scope_add_recurse(struct scope *scope, struct ast *node) +{ + if (!scope->parent) + return false; + + if (!ast_flags(node, AST_FLAG_PUBLIC)) + return false; + + if (same_src_scope(scope, node->scope)) + return true; + + return scope_flags(scope, SCOPE_PUBLIC); +} + int scope_add_var(struct scope *scope, struct ast *var) { struct ast *exists = scope_find_symbol(scope, var_id(var)); @@ -176,8 +196,7 @@ int scope_add_var(struct scope *scope, struct ast *var) } create_var(scope, var_id(var), var); - if (scope->parent && - scope_flags(scope, SCOPE_FILE) && ast_flags(var, AST_FLAG_PUBLIC)) + if (scope_add_recurse(scope, var)) return scope_add_var(scope->parent, var); return 0; @@ -193,8 +212,7 @@ int scope_add_type(struct scope *scope, char *id, struct ast *type) } create_type(scope, id, type); - if (scope->parent && - scope_flags(scope, SCOPE_FILE) && ast_flags(type, AST_FLAG_PUBLIC)) + if (scope_add_recurse(scope, type)) return scope_add_type(scope->parent, id, type); return 0; @@ -251,8 +269,7 @@ int scope_add_chain(struct scope *scope, char *id, struct ast *type) insert_chain(scope, id, type); - if (scope->parent && - scope_flags(scope, SCOPE_FILE) && ast_flags(type, AST_FLAG_PUBLIC)) + if (scope_add_recurse(scope, type)) return scope_add_chain(scope->parent, id, type); return 0; @@ -270,8 +287,7 @@ int scope_add_macro(struct scope *scope, struct ast *macro) /* always add to scope, do resolve checking later */ create_macro(scope, macro_def_id(macro), macro); - if (scope->parent && - scope_flags(scope, SCOPE_FILE) && ast_flags(macro, AST_FLAG_PUBLIC)) + if (scope_add_recurse(scope, macro)) return scope_add_macro(scope->parent, macro); return 0; @@ -282,15 +298,14 @@ int scope_add_proc(struct scope *scope, struct ast *proc) assert(proc->k == AST_PROC_DEF); struct ast *exists = file_scope_find_symbol(scope, proc_id(proc)); if (exists) { - semantic_error(scope->fctx, proc, "proc redefined"); - semantic_info(scope->fctx, exists, "previously here"); + semantic_error(proc->scope->fctx, proc, "proc redefined"); + semantic_info(exists->scope->fctx, exists, "previously here"); return -1; } /* always add to scope, do resolve checking later */ create_proc(scope, proc_id(proc), proc); - if (scope->parent && - scope_flags(scope, SCOPE_FILE) && ast_flags(proc, AST_FLAG_PUBLIC)) + if (scope_add_recurse(scope, proc)) return scope_add_proc(scope->parent, proc); return 0; @@ -309,8 +324,7 @@ int scope_add_trait(struct scope *scope, struct ast *trait) } create_type(scope, id, trait); - if (scope->parent && - scope_flags(scope, SCOPE_FILE) && ast_flags(trait, AST_FLAG_PUBLIC)) + if (scope_add_recurse(scope, trait)) return scope_add_trait(scope->parent, trait); return 0; @@ -324,8 +338,7 @@ int scope_add_expd_struct(struct scope *scope, struct ast *def, assert(file_scope_find_expd_struct(scope, def, types) == NULL); create_expanded(scope, def, types, expd); - if (scope->parent && - scope_flags(scope, SCOPE_FILE) && ast_flags(def, AST_FLAG_PUBLIC)) + if (scope_add_recurse(scope, expd)) return scope_add_expd_struct(scope->parent, def, types, expd); return 0; @@ -386,9 +399,8 @@ int scope_add_expd_chain(struct scope *scope, struct ast *def, 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); + if (scope_add_recurse(scope, expd)) + return scope_add_expd_chain(scope->parent, def, types, expd); return 0; } @@ -563,3 +575,9 @@ void scope_add_scope(struct scope *parent, struct scope *child) child->next = parent->children; parent->children = child; } + +bool same_src(struct ast *a, struct ast *b) +{ + return same_src_scope(a->scope, b->scope); +} + |
