]> Nishi Git Mirror - gwion.git/commitdiff
:bug: Fix op => funptr
authorfennecdjay <fennecdjay@gmail.com>
Tue, 28 Jun 2022 05:11:08 +0000 (07:11 +0200)
committerfennecdjay <fennecdjay@gmail.com>
Tue, 28 Jun 2022 05:11:08 +0000 (07:11 +0200)
include/emit.h
src/emit/emit.c
src/lib/closure.c

index 239ca6de39e3b065f0f97585fa7bda588d0ba523..fea69aade5561edb0e72a2a9a1106f44bbefefe2 100644 (file)
@@ -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
index cc689565779ef446ac7e5b0fa48fcc5c406cdda6..ec6ae806cc0d913beab4765ea60c05375eacf462 100644 (file)
@@ -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));
index 61091efa9bce885b156da4005a46424431149c70..3f32d10fd8ac5ceb56824cb9787474f4e74c9e5c 100644 (file)
@@ -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))