]> Nishi Git Mirror - gwion.git/commitdiff
:art: FIx member template
authorfennecdjay <astor.jeremie@wanadoo.fr>
Sat, 16 Feb 2019 10:56:03 +0000 (11:56 +0100)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Sat, 16 Feb 2019 10:56:03 +0000 (11:56 +0100)
include/instr.h
src/emit/emit.c
src/lib/instr.c
src/parse/check.c
src/parse/scan2.c

index e13236f8ec3f9d94d4171e1e4df7854a38e67f8a..555b20f4796530f4ee5a76861967dcd6bfdd2dbf 100644 (file)
@@ -69,9 +69,19 @@ INSTR(PopArrayClass);
 INSTR(AutoLoopStart);
 INSTR(AutoLoopEnd);
 INSTR(DotTmpl);
+
+struct dottmpl_ {
+  size_t len;
+  m_str name;
+  Func_Def base;
+  size_t overload; // => vtindex ?
+  Type_List tl;
+};
+ANN void free_dottmpl(struct dottmpl_*);
+#endif
+
 // optimizations
 #ifdef OPTIMIZE
 INSTR(PutArgsInMem);
-#endif
 #include "opcode.h"
 #endif
index b5856660cd5e6e1d5c6e75eec4a4f460911e274b..7641e77b3cf45f04dddb3cdd9e4536908495a429 100644 (file)
@@ -690,7 +690,11 @@ assert(_instr->execute == DotTmpl);
     char c[sz + 1];
     strncpy(c, f->name, sz);
     c[sz] = '\0';
-    _instr->m_val = (m_uint)s_name(insert_symbol(c));
+    struct dottmpl_ *dt = mp_alloc(dottmpl);
+    dt->name = s_name(insert_symbol(c));
+    dt->overload = f->def->tmpl->base;
+    dt->base = f->def;
+   _instr->m_val = (m_uint)dt;
     _instr->m_val2 = strlen(c);
     *(m_int*)_instr->ptr = f->def->tmpl->base;
     return GW_OK;
index 78214c67cf7011a41e7ebad46c75c2ed38b27aae..04f70ac03d0870b6cc5bdfbde142a0c1eebd375e 100644 (file)
@@ -109,7 +109,8 @@ INSTR(PopArrayClass) { GWDEBUG_EXE
 #include "value.h"
 #include "template.h"
 INSTR(DotTmpl) {
-  const m_str name = (m_str)instr->m_val;
+  const struct dottmpl_ * dt = (struct dottmpl_*)instr->m_val;
+  const m_str name = dt->name;
   const M_Object o = *(M_Object*)REG(-SZ_INT);
   Type t = o->type_ref;
   do {
@@ -130,19 +131,17 @@ strcpy(c, start + 1);
 c[strlen(start) - strlen(end) - 2] = '\0';
 m_uint depth;
 const Type_List tl = str2tl(emit->env, c, &depth);
-assert(v);
-assert(v->d.func_ref->def = f->def);
-env_push_type(emit->env, v->owner_class);
-if(template_push_types(emit->env, f->def->tmpl->list, tl) > 0)
-//  if(traverse_func_def(emit->env, f->value_ref->d.func_ref->def) > 0)
-  if(traverse_func_def(emit->env, f->def) > 0)
-emit_func_def(emit, f->def);
-assert(f->code);
-assert(f->code = f->def->func->code);
-nspc_pop_type(emit->env->curr);
-env_pop(emit->env, 0);
-free_type_list(tl);
-f->def->func->code->stack_depth -= SZ_INT;
+  m_uint scope = env_push_type(emit->env, v->owner_class);
+  m_bool ret = GW_ERROR;
+  if(traverse_func_template(emit->env, f->def, tl) > 0) {
+    ret = emit_func_def(emit, f->def);
+    nspc_pop_type(emit->env->curr);
+  }//}
+  env_pop(emit->env, scope);
+  free_type_list(tl);
+  if(ret < 0)
+    continue;
+
 }
       *(VM_Code*)shred->reg = f->code;
       shred->reg += SZ_INT;
@@ -156,31 +155,30 @@ m_str end = strchr(name, '<');
 char c[instr->m_val2];
 strcpy(c, start);
 c[strlen(start) - strlen(end)] = '\0';
-const Symbol sym = func_symbol(o->type_ref->name, c, "template", 
-*(m_uint*)instr->ptr);
+const Symbol sym = func_symbol(o->type_ref->name, c, "template", dt->overload);
     const Value v = nspc_lookup_value1(o->type_ref->nspc, sym);
+    if(!v)
+      continue;
       const Func_Def base = v->d.func_ref->def; 
       const Func_Def def = new_func_def(base->td, insert_symbol(v->name),
                 base->arg_list, base->d.code, base->flag);
-      def->tmpl = new_tmpl_list(base->tmpl->list, *(m_int*)instr->ptr);
+      def->tmpl = new_tmpl_list(base->tmpl->list, dt->overload);
       SET_FLAG(def, template);
-  Type_List tl = tmpl_tl(emit->env, name);
-  env_push_type(emit->env, v->owner_class);
-  if(template_push_types(emit->env, def->tmpl->list, tl) > 0)
-    if(traverse_func_def(emit->env, def) > 0) {
-      emit_func_def(emit, def);
-    nspc_pop_type(emit->env->curr);
-  }
-env_pop(emit->env, 0);
-def->func->code->stack_depth -= SZ_INT;
-      *(VM_Code*)shred->reg = def->func->code;
-      shred->reg += SZ_INT;
-      return;
-
-
-
-}
+      Type_List tl = tmpl_tl(emit->env, name);
+      m_uint scope = env_push_type(emit->env, v->owner_class);
+      m_bool ret = GW_ERROR;
+      if(traverse_func_template(emit->env, def, tl) > 0) {
+          ret = emit_func_def(emit, def);
+          nspc_pop_type(emit->env->curr);
+      }
+      env_pop(emit->env, scope);
+      free_type_list(tl);
+      if(ret > 0) {
+        *(VM_Code*)shred->reg = def->func->code;
+        shred->reg += SZ_INT;
+        return;
+      }
+    }
   } while((t = t->parent));
-// should not be reached
-  Except(shred, "MissigTmplException[internal]");
+  Except(shred, "MissigTmplException[internal]"); //unreachable
 }
index 0a3692921f89748d85d757eb84b522ee6faad471..fc809229f020c308a04f639185d84aa2b9fe7cdc 100644 (file)
@@ -434,22 +434,20 @@ end:
   return m_func;
 }
 ANN Func find_template_match(const Env env, const Value value, const Exp_Call* exp) {
-//  Value v = value;
   Type t = value->owner_class;
   const Func f = _find_template_match(env, value, exp);
   if(f)
     return f;
   while(t) {
-//assert(t->nspc);
-    const Value v = nspc_lookup_value1(t->nspc, value->d.func_ref->def->name);
-if(!v)goto next;
-    const Func f = _find_template_match(env, v, exp);
-    if(f)
-      return f;
-next:
-t = t->parent;
-}
-
+   Value v = nspc_lookup_value1(t->nspc, value->d.func_ref->def->name);
+   if(!v)
+     goto next;
+     const Func f = _find_template_match(env, v, exp);
+     if(f)
+       return f;
+   next:
+     t = t->parent;
+  }
   assert(exp->self);
   err_msg(exp->self->pos, "arguments do not match for template call");
   return NULL;
@@ -976,7 +974,9 @@ ANN static m_bool check_signature_match(const Func_Def f, const Func parent) { G
           c_name, f_name, p_name, c_name,
           GET_FLAG(f, static) ? c_name : p_name, f_name)
   }
-  return isa(f->ret_type, parent->def->ret_type);
+  if(!f->tmpl) // ???
+    return isa(f->ret_type, parent->def->ret_type);
+  return GW_OK;
 }
 
 ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def f,
@@ -985,8 +985,10 @@ ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def f,
   do {
     if(compat_func(f, parent_func->def) > 0) {
       CHECK_BB(check_signature_match(f, parent_func))
-      f->func->vt_index = parent_func->vt_index;
-      vector_set(&env->curr->vtable, f->func->vt_index, (vtype)f->func);
+      if(!f->tmpl) {
+        f->func->vt_index = parent_func->vt_index;
+        vector_set(&env->curr->vtable, f->func->vt_index, (vtype)f->func);
+      }
       return GW_OK;
     }
   } while((parent_func = parent_func->next));
index 464897003b23b0fd7ddb30b727ace7b903cd9b42..05753c153f0e859fd703a6ac131d8322789bda19 100644 (file)
@@ -342,7 +342,7 @@ ANN2(1,2) static Value func_value(const Env env, const Func f,
   if(!overload) {
     ADD_REF(v);
     nspc_add_value(env->curr, f->def->name, v);
-  } else if(!GET_FLAG(f->def, template)) {
+  } else /* if(!GET_FLAG(f->def, template)) */ {
     f->next = overload->d.func_ref->next;
     overload->d.func_ref->next = f;
   }
@@ -355,12 +355,43 @@ ANN2(1, 2) static m_bool scan2_func_def_template(const Env env, const Func_Def f
   const Value value = func_value(env, func, overload);
   SET_FLAG(value, checked | ae_flag_template);
   SET_FLAG(value->type, func); // the only types with func flag, name could be better
-  const Symbol sym = func_symbol(env->curr->name, func_name, "template", overload ? ++overload->offset : 0);
+  Type type = env->class_def;
+  Nspc nspc = env->curr;
+  uint i = 0;
+  do {
+    const Value v = nspc_lookup_value1(nspc, f->name);
+    if(v) {
+      Func ff = v->d.func_ref;
+      do {
+        if(ff->def == f) {
+          ++i;
+          continue;
+        }
+        m_bool ret = compat_func(ff->def, f);
+        if(ret > 0) {
+          const Symbol sym = func_symbol(env->curr->name, func_name,
+            "template", ff->vt_index);
+          nspc_add_value(env->curr, sym, value);
+          if(!overload) {
+            ADD_REF(value)
+            nspc_add_value(env->curr, f->name, value);
+          }
+          func->vt_index = ff->vt_index;
+          return GW_OK;
+        }
+      } while((ff = ff->next) && ++i);
+   }
+  } while(type && (type = type->parent) && (nspc = type->nspc));
+  --i;
+  const Symbol sym = func_symbol(env->curr->name, func_name, "template", i);
   nspc_add_value(env->curr, sym, value);
-if(!overload) {
-  ADD_REF(value)
-  nspc_add_value(env->curr, f->name, value);
-}
+   nspc_add_value(env->curr, sym, value);
+  if(!overload) {
+    func->vt_index = i;
+    ADD_REF(value)
+    nspc_add_value(env->curr, f->name, value);
+  } else
+    func->vt_index = ++overload->offset;
   return GW_OK;
 }