From: Jérémie Astor Date: Sat, 20 Jun 2020 09:30:35 +0000 (+0200) Subject: :art: Improve lambdas X-Git-Tag: nightly~1466 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=367151cccfc8e8bbf860fdf9d0ed6a68b658e254;p=gwion.git :art: Improve lambdas --- diff --git a/src/lib/func.c b/src/lib/func.c index b579a9db..3d26ee1f 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -152,7 +152,11 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Func_Def def ERR_B(exp_self(l)->pos, _("argument number does not match for lambda")) l->def->flag = def->flag; l->def->base->td = cpy_type_decl(env->gwion->mp, def->base->td); - CHECK_BB(traverse_func_def(env, l->def)) + SET_FLAG(l->def, abstract); // mark as non immediate lambda + map_set(&env->curr->info->value->map, (m_uint)l->def->base, env->scope->depth); + const m_bool ret = traverse_func_def(env, l->def); + map_remove(&env->curr->info->value->map, (m_uint)l->def->base); + CHECK_BB(ret) arg = l->def->base->args; while(arg) { arg->td = NULL; diff --git a/src/parse/check.c b/src/parse/check.c index 677b63c8..7eb363c4 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -286,19 +286,37 @@ static inline Nspc value_owner(const Value v) { return v ? v->from->owner : NULL; } +ANN static inline m_bool lambda_valid(const Env env, const Exp_Primary* exp) { + const Value val = exp->value; + const Symbol sym = insert_symbol(val->name); + const vtype xid = (vtype)sym; + const Vector vec = (Vector)&env->curr->info->value->ptr; + const m_uint scope = map_get(&env->curr->info->value->map, (m_uint)env->func->def->base) + 1; + if((val != (Value)map_get((Map)vector_back(vec), xid) && !nspc_lookup_value1(env->global_nspc, sym) && + val != (Value)map_get((Map)vector_at(vec, vector_size(vec) - scope), xid)) && + val->from->owner_class != env->class_def) + ERR_B(exp_self(exp)->pos, _("variable '%s' is not in lambda scope"), val->name) + return GW_OK; +} + ANN static Type prim_id_non_res(const Env env, const Symbol *data) { - const Symbol var = *data; + const Symbol sym = *data; const Value v = check_non_res_value(env, data); if(!v || !GET_FLAG(v, valid) || (v->from->ctx && v->from->ctx->error)) { env_err(env, prim_pos(data), - _("variable %s not legit at this point."), s_name(var)); - did_you_mean_nspc(value_owner(v) ?: env->curr, s_name(var)); + _("variable %s not legit at this point."), s_name(sym)); + if(v) + did_you_mean_nspc(value_owner(v) ?: env->curr, s_name(sym)); return NULL; } + prim_self(data)->value = v; + if(env->func) { + if(GET_FLAG(env->func->def, abstract)) + CHECK_BO(lambda_valid(env, prim_self(data))) if(env->func && !GET_FLAG(v, const) && v->from->owner) UNSET_FLAG(env->func, pure); + } SET_FLAG(v, used); - prim_self(data)->value = v; if(GET_FLAG(v, const)) exp_setmeta(prim_exp(data), 1); if(v->from->owner_class) {