From 03b2be923725989984c2757471987fbac446ba52 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Wed, 27 Apr 2022 15:52:26 +0200 Subject: [PATCH] :bug: Fix macro argument on commas and newline, also capture scoping --- ast | 2 +- include/env/func.h | 6 ++++++ src/lib/lib_func.c | 19 +++++++++++++------ src/lib/object_op.c | 3 +-- src/parse/check.c | 16 +++++++++++----- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/ast b/ast index c24bc9c7..f7a74f13 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit c24bc9c768b4521845b7b7b5e7947cd31ed993ef +Subproject commit f7a74f13840d253dc95ccdbf38adee626f7dd5e0 diff --git a/include/env/func.h b/include/env/func.h index 00ad9690..113f8140 100644 --- a/include/env/func.h +++ b/include/env/func.h @@ -36,4 +36,10 @@ Symbol func_symbol(const Env, const m_str, const m_str, const m_str, 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 diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index 26e6c116..a9e6cb51 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -264,7 +264,10 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, // 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) @@ -277,9 +280,9 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, 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; } } @@ -661,7 +664,11 @@ static OP_CHECK(opck_spork) { } } ++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++) { @@ -673,7 +680,7 @@ static OP_CHECK(opck_spork) { 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}; @@ -681,7 +688,7 @@ static OP_CHECK(opck_spork) { 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 diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 99aad2bd..12ff7c61 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -167,8 +167,7 @@ ANN static inline Value get_value(const Env env, const Exp_Dot *member, 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; } diff --git a/src/parse/check.c b/src/parse/check.c index 676cea9e..44aa72b3 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -275,7 +275,7 @@ ANN static inline Value get_value(const Env env, const Symbol sym) { 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; @@ -362,8 +362,11 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) { 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); @@ -786,11 +789,14 @@ ANN static Type check_lambda_call(const Env env, Exp_Call *const exp) { } 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) -- 2.43.0