]> Nishi Git Mirror - gwion.git/commitdiff
:bug: Fix member in closure
authorJérémie Astor <fennecdjay@gmail.com>
Thu, 17 Dec 2020 10:24:17 +0000 (11:24 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Thu, 17 Dec 2020 10:24:17 +0000 (11:24 +0100)
ast
src/lib/object_op.c
src/parse/check.c

diff --git a/ast b/ast
index b3aba278f4602a02959f97f7ddee3813f3f2337e..a10370e47f0218651bfbc0da2b0a2dc85c4860c3 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit b3aba278f4602a02959f97f7ddee3813f3f2337e
+Subproject commit a10370e47f0218651bfbc0da2b0a2dc85c4860c3
index b926e39bbbb14742cb5f07552c9042b9bec6e4e5..30e3ee49f8dd2806c725303b8ab2c7febc165ae7 100644 (file)
@@ -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);
index 00a716b7fee9932bb722efe132d8df0d233f0c22..316b9d4aa0c5a59e32c0d0338595a6f7e58ba90b 100644 (file)
@@ -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;
 }