From: fennecdjay Date: Tue, 28 Jun 2022 05:11:08 +0000 (+0200) Subject: :bug: Fix op => funptr X-Git-Tag: nightly~265 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=e4e12d3b1dfda4b939886e2e33a2778a85b9efba;p=gwion.git :bug: Fix op => funptr --- diff --git a/include/emit.h b/include/emit.h index 239ca6de..fea69aad 100644 --- a/include/emit.h +++ b/include/emit.h @@ -121,4 +121,5 @@ ANN void emit_push_scope(const Emitter emit); ANN void emit_pop_scope(const Emitter emit); ANN m_bool ensure_emit(const Emitter, const Type); +ANN m_bool emit_ensure_func(const Emitter emit, const Func f); #endif diff --git a/src/emit/emit.c b/src/emit/emit.c index cc689565..ec6ae806 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -774,7 +774,6 @@ ANN static m_bool emit_prim_id(const Emitter emit, const Symbol *data) { struct SpecialId_ *spid = specialid_get(emit->gwion, *data); if (spid) return specialid_instr(emit, spid, prim_self(data)) ? GW_OK : GW_ERROR; - if(vflag(prim->value, vflag_fglobal)) exp_self(prim)->acquire = 1; return emit_symbol(emit, prim_self(data)); } @@ -874,7 +873,7 @@ ANN static m_bool emit_prim_interp(const Emitter emit, const Exp *exp) { return GW_OK; } -ANN static m_bool emit_ensure_func(const Emitter emit, const Func f) { +ANN m_bool emit_ensure_func(const Emitter emit, const Func f) { const ValueFrom *from = f->value_ref->from; if(from->owner_class) CHECK_BB(ensure_emit(emit, from->owner_class)); diff --git a/src/lib/closure.c b/src/lib/closure.c index 61091efa..3f32d10f 100644 --- a/src/lib/closure.c +++ b/src/lib/closure.c @@ -464,6 +464,17 @@ static OP_EMIT(opem_fptr_impl) { return emit_fptr_assign(emit, impl->e->type, impl->t); } +static OP_CHECK(opck_fptr_cast) { + Exp_Cast *cast = (Exp_Cast *)data; + const Type t = known_type(env, cast->td); + const Func f = closure_def(t)->base->func; + struct FptrInfo info = {.lhs = cast->exp->type->info->func, + .rhs = f, + .exp = cast->exp}; + CHECK_BN(fptr_do(env, &info)); + return t; +} + static void op_narg_err(const Env env, const Func_Def fdef, const loc_t loc) { if (!env->context->error) { gwerr_basic(_("invalid operator decay"), @@ -500,8 +511,7 @@ ANN Type check_op_call(const Env env, Exp_Call *const exp) { static m_bool op_impl_narg(const Env env, const Func_Def fdef, const loc_t loc) { - Arg_List arg = fdef->base->args; - if (!arg && arg->len == 2) return GW_OK; + if (mp_vector_len(fdef->base->args) == 2) return GW_OK; op_narg_err(env, fdef, loc); return GW_ERROR; } @@ -526,9 +536,18 @@ static inline void op_impl_ensure_types(const Env env, const Func func) { if (func_tmpl) nspc_pop_type(env->gwion->mp, env->curr); } +static OP_EMIT(opem_op_impl) { + struct Implicit *impl = (struct Implicit *)data; + if(!impl->e->type->info->func->code) + emit_ensure_func(emit, impl->e->type->info->func); + const Instr instr = emit_add_instr(emit, RegPushImm); + instr->m_val = (m_uint)impl->e->type->info->func->code; + return emit_fptr_assign(emit, impl->e->type, impl->t); +} + static OP_CHECK(opck_op_impl) { struct Implicit *impl = (struct Implicit *)data; - const Func func = impl->t->info->func; + const Func func = closure_def(impl->t)->base->func; CHECK_BN(op_impl_narg(env, func->def, impl->e->pos)); op_impl_ensure_types(env, func); const Symbol lhs_sym = insert_symbol("@lhs"); @@ -575,13 +594,13 @@ static OP_CHECK(opck_op_impl) { _("`{+Y}%s{0}` has effects not present in `{+G}%s{0}`\n"), s_name(impl->e->d.prim.d.var), func->name); } - return actual_type(env->gwion, func->value_ref->type); + return func->value_ref->from->owner_class; } } const Arg_List args = cpy_arg_list(env->gwion->mp, func->def->base->args); Arg *larg0 = (Arg*)(args->ptr); Arg *larg1 = (Arg*)(args->ptr + sizeof(Arg)); - larg0->var_decl.xid = rhs_sym; + larg0->var_decl.xid = lhs_sym; larg1->var_decl.xid = rhs_sym; Func_Base *base = new_func_base(env->gwion->mp, type2td(env->gwion, t, impl->e->pos), @@ -615,9 +634,15 @@ static OP_CHECK(opck_op_impl) { /*const m_bool ret = */ traverse_func_def(env, def); env_pop(env, scope); def->base->func->value_ref->type->info->parent = env->gwion->type[et_op]; - impl->e->type = def->base->func->value_ref->type; + impl->e->type = def->base->func->value_ref->type; impl->e->d.prim.value = def->base->func->value_ref; - return actual_type(env->gwion, func->value_ref->type); + return opck_fptr_impl(env, impl); +} + +static OP_CHECK(opck_op_cast) { + Exp_Cast *cast = (Exp_Cast*)data; + struct Implicit impl = { .e = cast->exp, .t = known_type(env, cast->td) }; + return opck_op_impl(env, &impl); } static OP_CHECK(opck_func_partial) { @@ -734,9 +759,14 @@ GWION_IMPORT(func) { GWI_BB(gwi_oper_add(gwi, opck_fptr_impl)) GWI_BB(gwi_oper_emi(gwi, opem_fptr_impl)) GWI_BB(gwi_oper_end(gwi, "@implicit", NULL)) + GWI_BB(gwi_oper_add(gwi, opck_fptr_cast)) + GWI_BB(gwi_oper_end(gwi, "$", NULL)) GWI_BB(gwi_oper_ini(gwi, "operator", "funptr", NULL)) GWI_BB(gwi_oper_add(gwi, opck_op_impl)) + GWI_BB(gwi_oper_emi(gwi, opem_op_impl)) GWI_BB(gwi_oper_end(gwi, "@implicit", NULL)) + GWI_BB(gwi_oper_add(gwi, opck_op_cast)) + GWI_BB(gwi_oper_end(gwi, "$", NULL)) GWI_BB(gwi_oper_ini(gwi, "function", "function", NULL)) GWI_BB(gwi_oper_add(gwi, opck_auto_fptr)) GWI_BB(gwi_oper_end(gwi, "@=>", int_r_assign))