-Subproject commit c24bc9c768b4521845b7b7b5e7947cd31ed993ef
+Subproject commit f7a74f13840d253dc95ccdbf38adee626f7dd5e0
ANN m_bool check_lambda(const Env, const Type, Exp_Lambda *);
ANN Type check_op_call(const Env env, Exp_Call *const exp);
ANN void builtin_func(const MemPool mp, const Func f, void *func_ptr);
+
+static inline Value upvalues_lookup(const Upvalues *upvalues, const Symbol sym) {
+ const Value v = (Value)scope_lookup1(upvalues->values, (m_uint)sym);
+ if(v) return v;
+ return upvalues->parent ? upvalues_lookup(upvalues->parent, sym) : NULL;
+}
#endif
// if(GET_FLAG(def->base, global) && !l->owner &&
// def->base->func->value_ref->from->owner_class)
UNSET_FLAG(l->def->base, global);
- l->def->base->values = env->curr->info->value;
+ Upvalues upvalues = {
+ .values = env->curr->info->value
+ };
+ l->def->base->values = &upvalues;
const m_uint scope = env->scope->depth;
if(GET_FLAG(fdef->base, global) && !l->owner &&
fdef->base->func->value_ref->from->owner_class)
env_pop(env, scope);
if (l->def->base->func) {
- if (env->curr->info->value != l->def->base->values) {
+ if (env->curr->info->value != l->def->base->values->values) {
free_scope(env->gwion->mp, env->curr->info->value);
- env->curr->info->value = l->def->base->values;
+ env->curr->info->value = l->def->base->values->values;
}
}
}
}
++env->scope->depth;
- const Scope scope = env->curr->info->value;
+ Upvalues values = {
+ .values = env->curr->info->value
+ };
+ if(env->func && env->func->def->base->values)
+ values.parent = env->func->def->base->values;
env->curr->info->value = new_scope(env->gwion->mp);
if(unary->captures) {
for(uint32_t i = 0; i < unary->captures->len; i++) {
struct Value_ value = { .type = env->gwion->type[et_lambda]};
if(env->class_def)
set_vflag(&value, vflag_member);
- struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = scope};
+ struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = &values};
set_fbflag(&fbase, fbflag_lambda);
struct Func_Def_ fdef = { .base = &fbase};
struct Func_ func = { .name = "in spork", .def = &fdef, .value_ref = &value};
const m_bool ret = check_stmt(env, unary->code);
env->func = f;
free_scope(env->gwion->mp, env->curr->info->value);
- env->curr->info->value = scope;
+ env->curr->info->value = values.values;
--env->scope->depth;
CHECK_BN(ret);
return env->gwion
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 upvalues_lookup(env->func->def->base->values, member->xid);
return NULL;
}
return value;
}
if (env->func && env->func->def->base->values) {
- DECL_OO(const Value, v, = (Value)scope_lookup1(env->func->def->base->values, (vtype)sym));
+ DECL_OO(const Value, v, = upvalues_lookup(env->func->def->base->values, sym));
if(isa(env->func->value_ref->type, env->gwion->type[et_lambda]) > 0)
CHECK_OO(not_upvalue(env, v));
return v;
return env->gwion->type[et_op];
}
if (env->func && fbflag(env->func->def->base, fbflag_lambda) && env->func->def->base->values) {
- const Value v = (Value)scope_lookup1(env->func->def->base->values, (vtype)sym);
- if(v) CHECK_BO(check_upvalue(env, prim_self(data), v));
+ const Value v = upvalues_lookup(env->func->def->base->values, sym);
+ if(v) {
+ CHECK_BO(check_upvalue(env, prim_self(data), v));
+ return v->type;
+ }
}
gwerr_basic(_("Invalid variable"), _("not legit at this point."), NULL,
env->name, prim_pos(data), 0);
}
if(e)
ERR_O(exp_self(exp)->pos, _("argument number does not match for lambda"))
- l->def->base->values = env->curr->info->value;
+ Upvalues upvalues = { .values = env->curr->info->value};
+ if(env->func && env->func->def->base->values)
+ upvalues.parent = env->func->def->base->values;
+ l->def->base->values = &upvalues;
const m_bool ret = traverse_func_def(env, l->def);
if (l->def->base->func) {
free_scope(env->gwion->mp, env->curr->info->value);
- env->curr->info->value = l->def->base->values;
+ env->curr->info->value = l->def->base->values->values;
if (env->class_def) set_vflag(l->def->base->func->value_ref, vflag_member);
exp->func->type = l->def->base->func->value_ref->type;
if (!l->def->base->ret_type)