From 7ca1cf5dbae1f17237ad5a41befd31000e648319 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Fri, 30 Jul 2021 09:45:08 +0200 Subject: [PATCH] :art: Add scoped enums --- ast | 2 +- src/emit/emit.c | 8 ++++---- src/parse/check.c | 9 ++++++++- src/parse/scan1.c | 19 +++++++++++++++---- tests/enum/class_scoped.gw | 7 +++++++ tests/enum/scoped.gw | 6 ++++++ 6 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 tests/enum/class_scoped.gw create mode 100644 tests/enum/scoped.gw diff --git a/ast b/ast index 2505a7e7..d1d23609 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 2505a7e746b8a63731c11310593d3d7aaddce714 +Subproject commit d1d23609b24dc2f754c2808bd23f13100edcc001 diff --git a/src/emit/emit.c b/src/emit/emit.c index c84c5b3c..f8d95dee 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -2213,12 +2213,12 @@ ANN static m_bool emit_enum_def(const Emitter emit, const Enum_Def edef) { LOOP_OPTIM for (m_uint i = 0; i < vector_size(&edef->values); ++i) { const Value v = (Value)vector_at(&edef->values, i); - if (!emit->env->class_def) { + if(edef->is_scoped || emit->env->class_def) + *(m_uint *)(v->from->owner->info->class_data + v->from->offset) = i; + else { v->from->offset = emit_local(emit, emit->gwion->type[et_int]); v->d.num = i; - } else - *(m_uint *)(emit->env->class_def->nspc->info->class_data + - v->from->offset) = i; + } } set_tflag(edef->t, tflag_emit); return GW_OK; diff --git a/src/parse/check.c b/src/parse/check.c index dc509863..0e2fff4c 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1095,11 +1095,18 @@ ANN Type check_exp(const Env env, const Exp exp) { } ANN m_bool check_enum_def(const Env env, const Enum_Def edef) { - if (env->class_def) { + const bool is_scoped = edef->is_scoped; + const m_uint scope = is_scoped ? + env_push_type(env, edef->t) : 0; + if (is_scoped || env->class_def) { ID_List list = edef->list; do decl_static(env, nspc_lookup_value0(env->curr, list->xid)); while ((list = list->next)); } + if (is_scoped) { + env_pop(env, scope); + nspc_allocdata(env->gwion->mp, edef->t->nspc); + } return GW_OK; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index c7f41554..c5224191 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -366,11 +366,20 @@ ANN static inline m_bool scan1_stmt_exp(const Env env, const Stmt_Exp stmt) { } ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) { + const m_bool is_scoped = edef->is_scoped; + if(is_scoped) + edef->t->nspc = new_nspc(env->gwion->mp, edef->t->name); + const Nspc nspc = is_scoped ? + edef->t->nspc : edef->t->info->value->from->owner; + const m_uint scope = is_scoped ? + env_push_type(env, edef->t) : 0; ID_List list = edef->list; do { - CHECK_BB(already_defined(env, list->xid, edef->pos)); - if (nspc_lookup_value1(edef->t->info->value->from->owner, list->xid)) - ERR_B(edef->pos, "'%s' already defined", s_name(list->xid)); + if(!is_scoped) { + CHECK_BB(already_defined(env, list->xid, edef->pos)); + if (nspc_lookup_value1(nspc, list->xid)) + ERR_B(edef->pos, "'%s' already defined", s_name(list->xid)); + } const Value v = new_value(env->gwion->mp, edef->t, s_name(list->xid)); valuefrom(env, v->from, edef->pos); if (env->class_def) { @@ -381,9 +390,11 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) { set_vflag(v, vflag_builtin); SET_FLAG(v, const); set_vflag(v, vflag_valid); - nspc_add_value(edef->t->info->value->from->owner, list->xid, v); + nspc_add_value(nspc, list->xid, v); vector_add(&edef->values, (vtype)v); } while ((list = list->next)); + if(is_scoped) + env_pop(env, scope); return GW_OK; } diff --git a/tests/enum/class_scoped.gw b/tests/enum/class_scoped.gw new file mode 100644 index 00000000..d0b7d194 --- /dev/null +++ b/tests/enum/class_scoped.gw @@ -0,0 +1,7 @@ +class C { + enum MyEnum@ { + zero, one + } +} + +<<< C.MyEnum.one >>>; diff --git a/tests/enum/scoped.gw b/tests/enum/scoped.gw new file mode 100644 index 00000000..4b4fcf76 --- /dev/null +++ b/tests/enum/scoped.gw @@ -0,0 +1,6 @@ +#! [contains] 1 +enum MyEnum@ { + zero, one +} + +<<< MyEnum.one >>>; -- 2.43.0