]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve check_lambda
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Fri, 8 May 2020 10:09:15 +0000 (12:09 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Fri, 8 May 2020 10:09:15 +0000 (12:09 +0200)
include/env/func.h
include/parse.h
src/lib/func.c
src/parse/check.c

index 17df20353cbdcb104d004c3fd4a40c82b78e654d..5375b0a630e26a86fbbfdb43b568542bad144582 100644 (file)
@@ -13,5 +13,5 @@ struct Func_ {
 
 ANEW ANN Func new_func(MemPool, const m_str, const Func_Def);
 ANN2(1,2) Symbol func_symbol(const Env, const m_str, const m_str, const m_str, const m_uint);
-ANN2(1,3,4) m_bool check_lambda(const Env, const Type, Exp_Lambda*, const Func_Def);
+ANN m_bool check_lambda(const Env, const Type, Exp_Lambda*);
 #endif
index af616b36e56f2ea2eb94f862a71e00efa634fab6..992b1d37f790a7835d60fc6a2b62fbb21d9c5fe0 100644 (file)
@@ -77,6 +77,7 @@ static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
   return scanx_cdef(env, env, cdef,                                       \
       (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def);      \
 }
+xxx_cdef_flag(scan0)
 xxx_cdef_flag(scan1)
 xxx_cdef_flag(scan2)
 xxx_cdef_flag(check)
index c977bf6ab5cf336943e3ef0242bf74c5bd321508..cd148023b43e005c05e19b6d9f9cdd36a431f8ca 100644 (file)
@@ -165,27 +165,21 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Func_Def def
   return GW_OK;
 }
 
-ANN2(1,3,4) m_bool check_lambda(const Env env, const Type owner,
-    Exp_Lambda *l, const Func_Def def) {
+ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) {
+  const Func_Def fdef = t->e->d.func->def;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
     .scope=env->scope->depth, .flag=ae_flag_check };
-  if((l->owner = owner))
-    envset_push(&es, owner);
-  const m_bool ret = _check_lambda(env, l, def);
+  if((l->owner = t->e->owner_class))
+    envset_push(&es, l->owner);
+  const m_bool ret = _check_lambda(env, l, fdef);
   if(es.run)
-    envset_pop(&es, owner);
+    envset_pop(&es, l->owner);
   if(ret < 0)
     return GW_ERROR;
   exp_self(l)->info->type = l->def->base->func->value_ref->type;
   return GW_OK;
 }
 
-ANN static m_bool fptr_lambda(const Env env, struct FptrInfo *info) {
-  Exp_Lambda *l = &info->exp->d.exp_lambda;
-  const Type owner = info->rhs->value_ref->from->owner_class;
-  return check_lambda(env, owner, l, info->rhs->def);
-}
-
 ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) {
   if(isa(info->exp->info->type, env->gwion->type[et_lambda]) < 0) {
     m_bool nonnull = GET_FLAG(info->exp->info->type, nonnull);
@@ -194,7 +188,8 @@ ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) {
     info->exp->info->type = !nonnull ? t : type_nonnull(env, t);
     return GW_OK;
   }
-  return fptr_lambda(env, info);
+  Exp_Lambda *l = &info->exp->d.exp_lambda;
+  return check_lambda(env, actual_type(env->gwion, info->rhs->value_ref->type), l);
 }
 
 static OP_CHECK(opck_fptr_at) {
index 3d9329f00e418d2db6613106d6c1b875d29c3224..d8ba501e1fda2f34b2c77de3f512c6f959139485 100644 (file)
@@ -389,7 +389,7 @@ ANN static m_bool func_match_inner(const Env env, const Exp e, const Type t,
     array_base(e->info->type) == array_base(t);
     if(!match) {
       if(e->info->type == env->gwion->type[et_lambda] && is_fptr(env->gwion, t)) {
-        const m_bool ret = check_lambda(env, t->e->owner_class, &e->d.exp_lambda, t->e->d.func->def);
+        const m_bool ret = check_lambda(env, t, &e->d.exp_lambda);
         exp_setvar(e, 1);
         return ret;
       }