From a5a10fedada0263c35400a60604f699e2ab07e78 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Tue, 26 Apr 2022 13:15:55 +0200 Subject: [PATCH] :art: More on unary captures --- include/parse.h | 5 +++++ src/emit/emit.c | 37 ++++++++++++++++++++++++++----------- src/lib/lib_func.c | 5 +++-- src/parse/check.c | 6 ------ src/parse/scan1.c | 3 ++- 5 files changed, 36 insertions(+), 20 deletions(-) diff --git a/include/parse.h b/include/parse.h index f70845fb..6617a81e 100644 --- a/include/parse.h +++ b/include/parse.h @@ -115,4 +115,9 @@ static inline bool exp_is_zero(const Exp exp) { !exp->d.prim.d.num; } +ANN static inline bool not_upvalue(const Env env, const Value v) { + return GET_FLAG(v, global) || vflag(v, vflag_fglobal) || + (v->from->owner_class && isa(v->from->owner_class, env->class_def) > 0) || + nspc_lookup_value1(env->curr, insert_symbol(v->name)); +} #endif diff --git a/src/emit/emit.c b/src/emit/emit.c index 4b3fcd97..bf6c440d 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1951,11 +1951,22 @@ ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary *unary) { if(!sporker.is_spork) emit_local_exp(emit, exp_self(unary)); spork_ini(emit, &sporker); - -if(sporker.captures) { + // add this if needed + uint32_t offset = 0; + if(emit->env->class_def && sporker.code) { + struct Exp_ exp = { + .d = { .prim = { + .d = { .var = insert_symbol("this") }, + .prim_type = ae_prim_id + }}, + .type = emit->env->class_def, + .exp_type = ae_exp_primary + }; + emit_exp(emit, &exp); + offset += SZ_INT; + } + if(sporker.captures) { Capture_List caps = sporker.captures; -// what about types? - uint32_t offset = 0; for (uint32_t i = 0; i < caps->len; i++) { Capture *cap = mp_vector_at(caps, Capture, i); const Value v = nspc_lookup_value1(emit->env->curr, cap->xid); @@ -1968,17 +1979,16 @@ if(sporker.captures) { .type = v->type, .exp_type = ae_exp_primary }; -// handle emit var? -//exp_setvar(&exp, false); + if(cap->is_ref) exp_setvar(&exp, true); + offset += exp_size(&exp); emit_exp(emit, &exp); } -// pop_exp(emit, &exp); -regpop(emit, SZ_INT); + } + if(offset) { + regpop(emit, offset); const Instr args = emit_add_instr(emit, SporkCode); - args->m_val = 8; //emit->code->stack_depth; + args->m_val = offset; } - -// emit_local_exp(emit, exp_self(unary)); (unary->unary_type == unary_code ? spork_code : spork_func)(emit, &sporker); return GW_OK; } @@ -2537,6 +2547,7 @@ nspc_add_value(emit->env->curr, stmt->idx->sym, stmt->idx->v); ANN static m_bool emit_stmt_each(const Emitter emit, const Stmt_Each stmt) { const uint n = emit->info->unroll; + nspc_push_value(emit->gwion->mp, emit->env->curr); CHECK_BB(emit_exp(emit, stmt->exp)); // add ref? regpop(emit, SZ_INT); @@ -2550,6 +2561,7 @@ ANN static m_bool emit_stmt_each(const Emitter emit, const Stmt_Each stmt) { m_uint end_pc = 0; const m_bool ret = _emit_stmt_each(emit, stmt, &end_pc); emit_pop_stack(emit, end_pc); +nspc_pop_value(emit->gwion->mp, emit->env->curr); emit->info->unroll = 0; return ret; } @@ -2936,6 +2948,7 @@ ANN static void emit_func_def_args(const Emitter emit, Arg_List args) { emit->code->stack_depth += type->size; arg->var_decl.value->from->offset = emit_localn(emit, type); emit_debug(emit, arg->var_decl.value); + nspc_add_value(emit->env->curr, insert_symbol(arg->var_decl.value->name), arg->var_decl.value); } } @@ -3057,8 +3070,10 @@ ANN static m_bool emit_fdef(const Emitter emit, const Func_Def fdef) { const Func f = fdef->base->func; if (f->memoize && fflag(f, fflag_pure)) CHECK_BB(emit_memoize(emit, fdef)); + nspc_push_value(emit->gwion->mp, emit->env->curr); // handle CHECK_BB(emit_func_def_body(emit, fdef)); emit_func_def_return(emit); + nspc_pop_value(emit->gwion->mp, emit->env->curr); // handle return GW_OK; } diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index 3edb530d..78ed4caa 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -666,7 +666,7 @@ static OP_CHECK(opck_spork) { } if (unary->unary_type == unary_code) { if(unary->captures) { - uint32_t offset = 0; + uint32_t offset = !env->class_def ? 0 : SZ_INT; for(uint32_t i = 0; i < unary->captures->len; i++) { Capture *const cap = mp_vector_at(unary->captures, Capture, i); DECL_OO(const Type, t, = upvalue_type(env, cap)); @@ -686,7 +686,8 @@ static OP_CHECK(opck_spork) { } const Func f = env->func; struct Value_ value = {}; - set_vflag(&value, vflag_member); + if(env->class_def) + set_vflag(&value, vflag_member); struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = scope}; struct Func_Def_ fdef = { .base = &fbase}; struct Func_ func = { .name = "in spork", .def = &fdef, .value_ref = &value}; diff --git a/src/parse/check.c b/src/parse/check.c index a374bf54..4318a512 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -326,12 +326,6 @@ static inline Nspc value_owner(const Env env, const Value v) { return v ? v->from->owner : env->curr; } -ANN bool not_upvalue(const Env env, const Value v) { - return GET_FLAG(v, global) || vflag(v, vflag_fglobal) || - (v->from->owner_class && isa(v->from->owner_class, env->class_def) > 0) || - nspc_lookup_value1(env->curr, insert_symbol(v->name)); -} - ANN static m_bool check_upvalue(const Env env, const Exp_Primary *prim) { const Value v = prim->value; if(not_upvalue(env, v)) diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 8dba5259..28a31518 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -236,6 +236,7 @@ ANN static m_bool scan1_exp_if(const Env env, const Exp_If *exp_if) { ANN static inline m_bool scan1_exp_unary(const restrict Env env, Exp_Unary *const unary) { if (unary->unary_type == unary_code) { +/* if(strcmp("fork", s_name(unary->op))) { const loc_t pos = exp_self(unary)->pos; const Symbol sym = lambda_name(env->gwion->st, pos.first); @@ -245,7 +246,7 @@ if(strcmp("fork", s_name(unary->op))) { mp_free(env->gwion->mp, Stmt, unary->code); unary->exp = new_exp_call(env->gwion->mp, lambda, NULL, pos); unary->unary_type = unary_exp; -} else { +} else */{ return scan1_stmt(env, unary->code); } -- 2.43.0