diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/actualize.c | 80 | ||||
| -rw-r--r-- | src/ast.c | 11 | ||||
| -rw-r--r-- | src/compiler.c | 11 | ||||
| -rw-r--r-- | src/scope.c | 18 |
4 files changed, 94 insertions, 26 deletions
diff --git a/src/actualize.c b/src/actualize.c index 0d2c624..903d283 100644 --- a/src/actualize.c +++ b/src/actualize.c @@ -1201,6 +1201,8 @@ static struct ast *maybe_expand_type(struct scope *scope, struct ast *def, || def->k == AST_STRUCT_CONT_DEF || def->k == AST_TRAIT_DEF); + ast_set_flags_recurse(def, AST_FLAG_INSTANCE); + if (def->k == AST_STRUCT_DEF) return maybe_expand_struct(scope, def, loc, args); else if (def->k == AST_STRUCT_CONT_DEF) @@ -1432,6 +1434,40 @@ static int undefined_gotos(struct act_state *state, struct scope *scope) return ret; } +struct exported_helper { + struct scope *scope; + struct ast *node; +}; + +static int _check_exported(struct type *type, struct exported_helper *helper) +{ + struct ast *def = type->d; + if (!def) + return 0; + + struct ast *node = helper->node; + struct scope *scope = helper->scope; + + if (is_exported_type(scope, def)) + return 0; + + char *tstr = type_str(type); + semantic_error(node->scope->fctx, node, + "type %s should be exported", + tstr); + free(tstr); + return -1; +} + +static int check_exported(struct scope *scope, struct ast *node ,struct type *type) +{ + struct exported_helper helper = { + .scope = scope, + .node = node + }; + return type_visit((type_callback_t)_check_exported, NULL, type, &helper); +} + static int actualize_proc_sign(struct scope *scope, struct ast *proc) { assert(proc && proc->k == AST_PROC_DEF); @@ -1440,6 +1476,11 @@ static int actualize_proc_sign(struct scope *scope, struct ast *proc) proc->scope = create_scope(); scope_add_scope(scope, proc->scope); + foreach_node(p, proc_params(proc)) { + if (ast_flags(proc, AST_FLAG_PUBLIC)) + ast_set_flags(p, AST_FLAG_PUBLIC); + } + if (actualize_list(&new_state, proc->scope, proc_params(proc))) { destroy_act_state(&new_state); return -1; @@ -1454,6 +1495,12 @@ static int actualize_proc_sign(struct scope *scope, struct ast *proc) return -1; } + if (ast_flags(proc, AST_FLAG_PUBLIC) && !ast_flags(proc, AST_FLAG_INSTANCE)) + foreach_type(t, rtype) { + if (check_exported(scope, proc, t)) + return -1; + } + struct type *callable = tgen_callable(NULL, rtype, proc->loc); foreach_node(p, proc_params(proc)) { /* we must manually 'start' the chain */ @@ -1684,6 +1731,11 @@ static int actualize_var(struct act_state *state, /* declare */ set_type(var, type); + if (ast_flags(var, AST_FLAG_PUBLIC) && !ast_flags(var, AST_FLAG_INSTANCE)) { + if (check_exported(scope, var, var->t)) + return -1; + } + /* an unnamed var is a var in a signature that should not produce a * warning on not being used (if I ever get around to adding those kinds * of warnings) */ @@ -2485,18 +2537,6 @@ static int expand_struct_body(struct act_state *state, if (actualize_type(&type_state, scope, type)) return -1; - if (ast_flags(node, AST_FLAG_PUBLIC)) { - struct ast *def = type->d; - /* traits should only show up during the initial - * expansion, but should maybe make sure somehow */ - if (def->k == AST_TRAIT_DEF && !is_exported_type(scope, - def)) { - semantic_error(struct_scope->fctx, n, - "trait used in pub def must also be exported"); - return -1; - } - } - type_append(&types, type); struct ast *alias = gen_alias(strdup(id), type, n->loc); @@ -2507,6 +2547,19 @@ static int expand_struct_body(struct act_state *state, if (actualize(&state, struct_scope, alias)) return -1; + if (!ast_flags(node, AST_FLAG_PUBLIC)) + continue; + + if (ast_flags(node, AST_FLAG_INSTANCE)) + continue; + + struct ast *def = type->d; + if (is_exported_type(scope, def)) + continue; + + semantic_error(struct_scope->fctx, n, + "trait used in pub def must also be exported"); + return -1; } if (node->k == AST_STRUCT_CONT_DEF @@ -2608,6 +2661,9 @@ static int expand_struct_body(struct act_state *state, if (n->k == AST_TYPE_EXPAND) continue; + if (ast_flags(node, AST_FLAG_PUBLIC)) + ast_set_flags(n, AST_FLAG_PUBLIC); + struct act_state state = {0}; if (actualize(&state, struct_scope, n)) return -1; @@ -149,6 +149,17 @@ void ast_set_flags(struct ast *node, enum ast_flags flags) node->f |= flags; } +static int _ast_set_flags(struct ast *node, enum ast_flags *flags) +{ + ast_set_flags(node, *flags); + return 0; +} + +void ast_set_flags_recurse(struct ast *node, enum ast_flags flags) +{ + ast_visit((ast_callback_t)_ast_set_flags, NULL, node, &flags); +} + void ast_clear_flags(struct ast *node, enum ast_flags flags) { node->f &= ~(flags); diff --git a/src/compiler.c b/src/compiler.c index 881326c..d865ea5 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -171,13 +171,14 @@ struct scope *process_file(const char *file) return *exists; } else { struct scope *scope = create_scope(); - if (process(scope, base)) { - destroy_scope(scope); - free(real); - goto out; - } + if (scopes_len(&scopes) == 0) + scope_set_flags(scope, SCOPE_ROOT); scopes_insert(&scopes, real, scope); + + if (process(scope, base)) + goto out; + res_destroy(r); return scope; } diff --git a/src/scope.c b/src/scope.c index 1eae065..4c9097f 100644 --- a/src/scope.c +++ b/src/scope.c @@ -17,12 +17,6 @@ #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. */ @@ -123,9 +117,6 @@ static bool scope_add_recurse(struct scope *scope, struct ast *node) if (!ast_flags(node, AST_FLAG_PUBLIC)) return false; - if (same_src_scope(scope, node->scope)) - return true; - return scope_flags(scope, SCOPE_PUBLIC); } @@ -459,6 +450,9 @@ void scope_add_scope(struct scope *parent, struct scope *child) bool is_exported_type(struct scope *scope, struct ast *def) { + if (scope_flags(scope, SCOPE_ROOT)) + return true; + struct ast **found = exported_find(&scope->exported_types, def); if (found) return true; @@ -471,6 +465,9 @@ bool is_exported_type(struct scope *scope, struct ast *def) bool is_exported_symbol(struct scope *scope, struct ast *def) { + if (scope_flags(scope, SCOPE_ROOT)) + return true; + struct ast **found = exported_find(&scope->exported_symbols, def); if (found) return true; @@ -483,6 +480,9 @@ bool is_exported_symbol(struct scope *scope, struct ast *def) bool is_exported_macro(struct scope *scope, struct ast *def) { + if (scope_flags(scope, SCOPE_ROOT)) + return true; + struct ast **found = exported_find(&scope->exported_macros, def); if (found) return true; |
