]> Nishi Git Mirror - gwion.git/commitdiff
:smile: Really improve class templating
authorfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 9 Oct 2019 11:42:42 +0000 (13:42 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 9 Oct 2019 11:42:42 +0000 (13:42 +0200)
include/cpy_ast.h
src/parse/cpy_ast.c
src/parse/scan0.c
src/parse/template.c

index 948a3a4db918b9436b8d2ea3f56f8c05a46bc9f6..79487ea25b747442e881adab717331193999ed0f 100644 (file)
@@ -5,8 +5,10 @@ ANN Type_Decl* cpy_type_decl(MemPool, const Type_Decl*);
 ANN Type_List cpy_type_list(MemPool, const Type_List);
 ANN Func_Def cpy_func_def(MemPool, const Func_Def);
 ANN Func_Def cpy_func_def(MemPool, Func_Def);
-ANN struct Func_Base_* cpy_func_base(MemPool, struct Func_Base_*);
+ANN struct Func_Base_* cpy_func_base(MemPool, const struct Func_Base_*);
 ANN Class_Def cpy_class_def(MemPool, Class_Def);
 ANN Type_List cpy_type_list(MemPool p, const Type_List src);
 ANN Decl_List cpy_decl_list(MemPool p, const Decl_List src);
+ANN ID_List cpy_id_list(MemPool p, const ID_List src);
+ANN Tmpl* cpy_tmpl(MemPool p, const Tmpl *src);
 #endif
index c23e7304b0e68a44ce3606938de95cf0ea7ac741..3a7937af4c7e4188b7baac92cb9befdba8e3bc72 100644 (file)
@@ -1,9 +1,9 @@
 #include "gwion_util.h"
 #include "gwion_ast.h"
+#include "cpy_ast.h"
 
 ANN static Stmt cpy_stmt(MemPool p, const Stmt src);
 ANN static Exp cpy_exp(MemPool p, const Exp src);
-ANN static ID_List cpy_id_list(MemPool p, const ID_List src);
 ANN Type_List cpy_type_list(MemPool p, const Type_List src);
 ANN static Arg_List cpy_arg_list(MemPool p, const Arg_List src);
 ANN Class_Def cpy_class_def(MemPool p, const Class_Def src);
@@ -65,7 +65,7 @@ ANN Type_Decl* cpy_type_decl(MemPool p, const Type_Decl* src) {
   return a;
 }
 
-ANN static ID_List cpy_id_list(MemPool p, const ID_List src) {
+ANN ID_List cpy_id_list(MemPool p, const ID_List src) {
   ID_List a = mp_calloc(p, ID_List);
   a->xid = src->xid; // 1 
   if(src->next)
@@ -136,7 +136,7 @@ ANN static void cpy_exp_primary(MemPool p, Exp_Primary *a, const Exp_Primary *sr
   a->primary_type = src->primary_type;
 }
 
-ANN static Tmpl* cpy_tmpl(MemPool p, const Tmpl *src) {
+ANN Tmpl* cpy_tmpl(MemPool p, const Tmpl *src) {
   Tmpl *a = mp_calloc(p, Tmpl);
   if(src->list)
     a->list = cpy_id_list(p, src->list);
index 9311ef3dcca806663be8b5a0334e49cb62ee3c87..5a2468a8dd2619287f4dbd72d7e60f914ecb25c5 100644 (file)
@@ -300,13 +300,27 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
   return GW_OK;
 }
 
-
 ANN static m_bool scan0_class_def_pre(const Env env, const Class_Def cdef) {
   CHECK_BB(env_storage(env, cdef->flag, cdef->pos))
   CHECK_BB(isres(env, cdef->base.xid, cdef->pos))
   return GW_OK;
 }
 
+ANN static void set_template(const Type t, const Class_Def cdef) {
+  SET_FLAG(t, template);
+  SET_FLAG(cdef, template);
+}
+
+
+ANN static void inherit_tmpl(const Env env, const Class_Def cdef) {
+  const ID_List list = env->class_def->e->def->base.tmpl->list;
+  const ID_List prev_list = cpy_id_list(env->gwion->mp, list);
+  ID_List il = prev_list;
+  while(il->next && (il = il->next));
+  il->next = cdef->base.tmpl->list;
+  cdef->base.tmpl->list = prev_list;
+}
+
 ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
   CHECK_BO(scan0_defined(env, cdef->base.xid, cdef->pos))
   const Type t = scan0_type(env, ++env->scope->type_xid, s_name(cdef->base.xid), env->gwion->type[et_object]);
@@ -315,11 +329,14 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
   t->nspc->parent = env->curr;
   t->e->def = cdef;
   t->flag = cdef->flag;
-  if(!strstr(t->name, "<"))
-    add_type(env, t->e->owner, t);
+  add_type(env, t->e->owner, t);
   if(cdef->base.tmpl) {
-    SET_FLAG(t, template);
-    SET_FLAG(cdef, template);
+    if(SAFE_FLAG(env->class_def, template) && env->class_def->e->def->base.tmpl->call == (Type_List)1)
+      inherit_tmpl(env, cdef);
+    set_template(t, cdef);
+  } else if(SAFE_FLAG(env->class_def, template)) {
+    cdef->base.tmpl = new_tmpl(env->gwion->mp, env->class_def->e->def->base.tmpl->list, -1);
+    set_template(t, cdef);
   }
   if(cdef->base.ext && cdef->base.ext->array)
     SET_FLAG(t, typedef);
index 82d7778d8bcf1f254ca384c9de93bc1064822102..8d79762afe18952eb173ba9394935fb443aaa094 100644 (file)
@@ -21,43 +21,6 @@ ANN static inline Type owner_type(const Env env, const Type t) {
   return (nspc && nspc->parent) ? nspc_lookup_type1(nspc->parent, insert_symbol(nspc->name)) : NULL;
 }
 
-ANEW ANN static Vector get_types(const Env env, Type t) {
-  const Vector v = new_vector(env->gwion->mp);
-  do if(GET_FLAG(t, template))
-    vector_add(v, (vtype)t->e->def->base.tmpl->list);
-  while((t = owner_type(env, t)));
-  return v;
-}
-
-ANEW ANN static ID_List id_list_copy(MemPool p, ID_List src) {
-  const ID_List list = new_id_list(p, src->xid, loc_cpy(p, src->pos));
-  ID_List tmp = list;
-  while((src = src->next))
-    tmp = (tmp->next = new_id_list(p, src->xid, loc_cpy(p, src->pos)));
-  return list;
-}
-
-ANN2(1,2) static ID_List get_total_type_list(const Env env, const Type t, const Tmpl *tmpl) {
-  const Type parent = owner_type(env, t);
-  if(!parent)
-    return tmpl ? tmpl->list : NULL;
-  const Vector v = get_types(env, parent);
-  const ID_List base = (ID_List)vector_pop(v);
-  if(!base) {
-    free_vector(env->gwion->mp, v);
-    return tmpl ? tmpl->list : NULL;
-  }
-  const ID_List types = id_list_copy(env->gwion->mp, base);
-  ID_List list, tmp = types;
-  for(m_uint i = vector_size(v) + 1; --i;) {
-    list = (ID_List)vector_pop(v);
-    tmp = (tmp->next = id_list_copy(env->gwion->mp, list));
-  }
-  tmp->next = tmpl->list;
-  free_vector(env->gwion->mp, v);
-  return types;
-}
-
 struct tmpl_info {
   const  Class_Def cdef;
   Type_List        call;
@@ -123,7 +86,7 @@ ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_
 
 ANN m_bool template_match(ID_List base, Type_List call) {
   while((call = call->next) && (base = base->next));
-  return !call ? 1 : -1;
+  return !call ? GW_OK : GW_ERROR;
 }
 
 ANN static Class_Def template_class(const Env env, const Class_Def def, const Type_List call) {
@@ -181,8 +144,8 @@ ANN Type scan_tuple(const Env env, const Type_Decl *td) {
   return ret;
 }
 
-ANN Tmpl* mk_tmpl(const Env env, const Type t, const Tmpl *tm, const Type_List types) {
-  Tmpl *tmpl = new_tmpl(env->gwion->mp, get_total_type_list(env, t, tm), 0);
+ANN Tmpl* mk_tmpl(const Env env, const Tmpl *tm, const Type_List types) {
+  Tmpl *tmpl = new_tmpl(env->gwion->mp, tm->list, 0);
   tmpl->call = cpy_type_list(env->gwion->mp, types);
   return tmpl;
 }
@@ -204,11 +167,10 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) {
       SET_FLAG(a, ref);
       if(a->base.type)
         return a->base.type;
-      a->base.tmpl = mk_tmpl(env, t, t->e->def->base.tmpl, type->types);
-      if(t->e->parent !=  env->gwion->type[et_union]) {
+      a->base.tmpl = mk_tmpl(env, t->e->def->base.tmpl, type->types);
+      if(t->e->parent !=  env->gwion->type[et_union])
         CHECK_BO(scan0_class_def(env, a))
-        nspc_add_type_front(env->curr, a->base.xid, a->base.type);
-      } else {
+      else {
         a->union_def = new_union_def(env->gwion->mp, a->list,
           loc_cpy(env->gwion->mp, t->e->def->pos));
         a->union_def->type_xid = a->base.xid;
@@ -220,7 +182,7 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) {
       SET_FLAG(a->base.type, template | ae_flag_ref);
       a->base.type->e->owner = t->e->owner;
       if(GET_FLAG(t, builtin))
-      SET_FLAG(a->base.type, builtin);
+        SET_FLAG(a->base.type, builtin);
       CHECK_BO(scan1_cdef(env, a))
       return a->base.type;
     } else
@@ -247,7 +209,7 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) {
       value->from->owner = t->e->owner;
       value->from->owner_class = t->e->d.func->value_ref->from->owner_class;
       func->value_ref = value;
-      func->def->base->tmpl = mk_tmpl(env, t, t->e->d.func->def->base->tmpl, type->types);
+      func->def->base->tmpl = mk_tmpl(env, t->e->d.func->def->base->tmpl, type->types);
       def->base->func = func;
       nspc_add_value_front(t->e->owner, sym, value);
       return ret;