]> Nishi Git Mirror - gwion.git/commitdiff
:art: Split _find_template_match (1/2) (#217)
authorPranav Joglekar <pranav2000joglekar@gmail.com>
Tue, 20 Oct 2020 19:15:24 +0000 (00:45 +0530)
committerGitHub <noreply@github.com>
Tue, 20 Oct 2020 19:15:24 +0000 (21:15 +0200)
* :art: Split _find_template_match (1/2)

* :art: Split _find_template_match (2/2)

src/parse/func_resolve_tmpl.c

index 1dc2345199e054bbed3dfc9bc5d8887e5d198edf..bb5a606320e9e9318df98fc7b9d20325e7919ce3 100644 (file)
 #include "specialid.h"
 #include "tmp_resolve.h"
 
+struct ResolverArgs {
+  Value v;
+  const Exp_Call *e;
+  m_str tmpl_name;
+  Func m_func;
+  Type_List types;
+};
+
 ANN static inline Value template_get_ready(const Env env, const Value v, const m_str tmpl, const m_uint i) {
   const Symbol sym = func_symbol(env, v->from->owner->name, v->name, tmpl, i);
   return v->from->owner_class ? find_value(v->from->owner_class, sym) :
@@ -47,6 +55,80 @@ ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *
   return NULL;
 }
 
+ANN static Func fptr_match(const Env env, struct ResolverArgs* f_ptr_args) {
+  const Value v = f_ptr_args->v;
+  const m_str tmpl_name = f_ptr_args->tmpl_name;
+  const Exp_Call *exp = f_ptr_args->e;
+  Type_List types = f_ptr_args->types;
+  const Symbol sym = func_symbol(env, v->from->owner->name, v->name, tmpl_name, 0);
+  const Type exists = nspc_lookup_type0(v->from->owner, sym);
+  if(exists)
+    return exists->e->d.func;
+
+  Func m_func = f_ptr_args->m_func; 
+  Func_Def base = v->d.func_ref ? v->d.func_ref->def : exp->func->info->type->e->d.func->def;
+  Func_Base *fbase = cpy_func_base(env->gwion->mp, base->base);
+  fbase->xid = sym;
+  fbase->tmpl->base = 0;
+  fbase->tmpl->call = cpy_type_list(env->gwion->mp, types);
+  if(template_push_types(env, fbase->tmpl) > 0) {
+    const Fptr_Def fptr = new_fptr_def(env->gwion->mp, fbase);
+    if(traverse_fptr_def(env, fptr) > 0 &&
+        (base->base->ret_type = known_type(env, base->base->td)) &&
+        (!exp->args || !!check_exp(env, exp->args))) {
+      m_func = find_func_match(env, fbase->func, exp->args);
+      nspc_pop_type(env->gwion->mp, env->curr);
+      if(m_func)
+        nspc_add_type_front(v->from->owner, sym, actual_type(env->gwion, m_func->value_ref->type));
+    }
+    if(fptr->type)
+      REM_REF(fptr->type, env->gwion)
+    free_fptr_def(env->gwion->mp, fptr);
+  }
+  return m_func;
+}
+
+ANN static Func func_match(const Env env, struct ResolverArgs* f_ptr_args) {
+  const Value v = f_ptr_args->v;
+  const m_str tmpl_name = f_ptr_args->tmpl_name;
+  const Exp_Call *exp = f_ptr_args->e;
+  Func m_func = f_ptr_args->m_func; 
+  Type_List types = f_ptr_args->types;
+  for(m_uint i = 0; i < v->from->offset + 1; ++i) {
+    const Value exists = template_get_ready(env, v, tmpl_name, i);
+    if(exists) {
+      if(env->func == exists->d.func_ref) {
+        if(check_call(env, exp) < 0 ||
+           !find_func_match(env, env->func, exp->args))
+          continue;
+        m_func = env->func;
+        break;
+      }
+      if((m_func = ensure_tmpl(env, exists->d.func_ref->def, exp)))
+        break;
+    } else {
+      const Value value = template_get_ready(env, v, "template", i);
+      if(!value)
+        continue;
+      if(GET_FLAG(v, builtin)) {
+        SET_FLAG(value, builtin);
+        SET_FLAG(value->d.func_ref, builtin);
+      }
+      const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
+      SET_FLAG(fdef->base, template);
+      fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, types);
+      fdef->base->tmpl->base = i;
+      if((m_func = ensure_tmpl(env, fdef, exp))) {
+        break;
+      }
+      if(!fdef->base->func) {
+        free_func_def(env->gwion->mp, fdef);
+      }
+    }
+  }
+  return m_func;
+}
+
 ANN static Func _find_template_match(const Env env, const Value v, const Exp_Call* exp) {
   CHECK_BO(check_call(env, exp))
   const Type_List types = exp->tmpl->call;
@@ -55,63 +137,13 @@ ANN static Func _find_template_match(const Env env, const Value v, const Exp_Cal
   const m_uint scope = env->scope->depth;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
     .scope=scope, .flag=ae_flag_check };
+  struct ResolverArgs f_ptr_args = {.v = v, .e = exp, .tmpl_name = tmpl_name, m_func =  m_func, .types = types};
   CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner))
   (void)env_push(env, v->from->owner_class, v->from->owner);
   if(is_fptr(env->gwion, v->type)) {
-    const Symbol sym = func_symbol(env, v->from->owner->name, v->name, tmpl_name, 0);
-    const Type exists = nspc_lookup_type0(v->from->owner, sym);
-    if(exists)
-      m_func = exists->e->d.func;
-    else {
-      Func_Def base = v->d.func_ref ? v->d.func_ref->def : exp->func->info->type->e->d.func->def;
-      Func_Base *fbase = cpy_func_base(env->gwion->mp, base->base);
-      fbase->xid = sym;
-      fbase->tmpl->base = 0;
-      fbase->tmpl->call = cpy_type_list(env->gwion->mp, types);
-      if(template_push_types(env, fbase->tmpl) > 0) {
-        const Fptr_Def fptr = new_fptr_def(env->gwion->mp, fbase);
-        if(traverse_fptr_def(env, fptr) > 0 &&
-            (base->base->ret_type = known_type(env, base->base->td)) &&
-            (!exp->args || !!check_exp(env, exp->args))) {
-          m_func = find_func_match(env, fbase->func, exp->args);
-          nspc_pop_type(env->gwion->mp, env->curr);
-          if(m_func)
-            nspc_add_type_front(v->from->owner, sym, actual_type(env->gwion, m_func->value_ref->type));
-        }
-        free_fptr_def(env->gwion->mp, fptr);
-        if(fptr->type)
-          REM_REF(fptr->type, env->gwion)
-      }
-    }
+    m_func = fptr_match(env, &f_ptr_args);
   } else {
-    for(m_uint i = 0; i < v->from->offset + 1; ++i) {
-      const Value exists = template_get_ready(env, v, tmpl_name, i);
-      if(exists) {
-        if(env->func == exists->d.func_ref) {
-          if(check_call(env, exp) < 0 ||
-             !find_func_match(env, env->func, exp->args))
-            continue;
-          m_func = env->func;
-          break;
-        }
-        if((m_func = ensure_tmpl(env, exists->d.func_ref->def, exp)))
-          break;
-      } else {
-        const Value value = template_get_ready(env, v, "template", i);
-        if(!value)
-          continue;
-        if(GET_FLAG(v, builtin)) {
-          SET_FLAG(value, builtin);
-          SET_FLAG(value->d.func_ref, builtin);
-        }
-        const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
-        SET_FLAG(fdef->base, template);
-        fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, types);
-        fdef->base->tmpl->base = i;
-        if((m_func = ensure_tmpl(env, fdef, exp)))
-          break;
-      }
-    }
+    m_func = func_match(env, &f_ptr_args);
   }
   free_mstr(env->gwion->mp, tmpl_name);
   if(es.run)