From 7e14bdc37452a1eed3318384b1fd8cae680e0356 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Thu, 17 Dec 2020 11:24:17 +0100 Subject: [PATCH] :bug: Fix member in closure --- ast | 2 +- src/lib/object_op.c | 12 +++++++++++- src/parse/check.c | 30 +++++++++++++++++------------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/ast b/ast index b3aba278..a10370e4 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit b3aba278f4602a02959f97f7ddee3813f3f2337e +Subproject commit a10370e47f0218651bfbc0da2b0a2dc85c4860c3 diff --git a/src/lib/object_op.c b/src/lib/object_op.c index b926e39b..30e3ee49 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -141,6 +141,16 @@ ANN static inline void emit_struct_data(const Emitter emit, const Value v, const } ANN m_bool not_from_owner_class(const Env env, const Type t, const Value v, const loc_t pos); + +ANN static inline Value get_value(const Env env, const Exp_Dot *member, const Type t) { + const Value value = find_value(t, member->xid); + if(value) + return value; + if(env->func && env->func->def->base->values) + return (Value)scope_lookup1(env->func->def->base->values, (m_uint)member->xid); + return NULL; +} + OP_CHECK(opck_object_dot) { const Exp_Dot *member = (Exp_Dot*)data; const m_str str = s_name(member->xid); @@ -153,7 +163,7 @@ OP_CHECK(opck_object_dot) { if(member->xid == insert_symbol(env->gwion->st, "this") && base_static) ERR_N(exp_self(member)->pos, _("keyword 'this' must be associated with object instance...")) - const Value value = find_value(the_base, member->xid); + const Value value = get_value(env, member, the_base); if(!value) { env_err(env, exp_self(member)->pos, _("class '%s' has no member '%s'"), the_base->name, str); diff --git a/src/parse/check.c b/src/parse/check.c index 00a716b7..316b9d4a 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -310,6 +310,17 @@ ANN static void check_upvalue(const Env env, const Exp_Primary *prim) { } } +ANN static Type prim_owned(const Env env, const Symbol *data) { + const Exp exp = exp_self(prim_exp(data)); + const Value v = exp->d.prim.value; + const m_str name = !GET_FLAG(v, static) ? "this" : v->from->owner_class->name; + const Exp base = new_prim_id(env->gwion->mp, insert_symbol(name), loc_cpy(env->gwion->mp, prim_pos(data))); + exp->exp_type = ae_exp_dot; + exp->d.exp_dot.base = base; + exp->d.exp_dot.xid = *data; + return check_exp(env, exp); +} + ANN static Type prim_id_non_res(const Env env, const Symbol *data) { const Symbol sym = *data; const Value v = check_non_res_value(env, data); @@ -321,24 +332,17 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) { return NULL; } prim_self(data)->value = v; + if(v->from->owner_class) + return prim_owned(env, data); + if(GET_FLAG(v, const)) + exp_setmeta(prim_exp(data), 1); if(env->func) { + if(!GET_FLAG(v, const) && v->from->owner) + unset_fflag(env->func, fflag_pure); if(fbflag(env->func->def->base, fbflag_lambda)) check_upvalue(env, prim_self(data)); - if(env->func && !GET_FLAG(v, const) && v->from->owner) - unset_fflag(env->func, fflag_pure); } //set_vflag(v->vflag, vflag_used); - if(GET_FLAG(v, const)) - exp_setmeta(prim_exp(data), 1); - if(v->from->owner_class) { - const Exp exp = exp_self(prim_exp(data)); - const m_str name = !GET_FLAG(v, static) ? "this" : v->from->owner_class->name; - const Exp base = new_prim_id(env->gwion->mp, insert_symbol(name), loc_cpy(env->gwion->mp, prim_pos(data))); - exp->exp_type = ae_exp_dot; - exp->d.exp_dot.base = base; - exp->d.exp_dot.xid = sym; - return check_exp(env, exp); - } return v->type; } -- 2.43.0