aboutsummaryrefslogtreecommitdiff
path: root/environment.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-03-10 13:33:31 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-03-10 13:33:31 -0400
commit7c68fc958599c74818697056c3b4372d1bb14bfe (patch)
tree38e139138fde47ca3eb3afb22b9d14fe6585eb80 /environment.c
parenteb8b501b95e4d8704245375eb5f532303cc8e2e7 (diff)
Fix some scoping issues with type methods and enum returns
Diffstat (limited to 'environment.c')
-rw-r--r--environment.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/environment.c b/environment.c
index b871bffc..e09ef75a 100644
--- a/environment.c
+++ b/environment.c
@@ -641,6 +641,14 @@ env_t *load_module_env(env_t *env, ast_t *ast)
return module_env;
}
+env_t *global_scope(env_t *env)
+{
+ env_t *scope = new(env_t);
+ *scope = *env;
+ scope->locals = new(Table_t, .fallback=env->globals);
+ return scope;
+}
+
env_t *namespace_scope(env_t *env)
{
env_t *scope = new(env_t);
@@ -657,6 +665,25 @@ env_t *fresh_scope(env_t *env)
return scope;
}
+env_t *with_enum_scope(env_t *env, type_t *t)
+{
+ while (t->tag == OptionalType)
+ t = Match(t, OptionalType)->type;
+
+ if (t->tag != EnumType) return env;
+ env = fresh_scope(env);
+ env_t *ns_env = Match(t, EnumType)->env;
+ for (tag_t *tag = Match(t, EnumType)->tags; tag; tag = tag->next) {
+ if (get_binding(env, tag->name))
+ continue;
+ binding_t *b = get_binding(ns_env, tag->name);
+ assert(b);
+ Table$str_set(env->locals, tag->name, b);
+ }
+ return env;
+}
+
+
env_t *for_scope(env_t *env, ast_t *ast)
{
auto for_ = Match(ast, For);