From: fennecdjay Date: Wed, 9 Oct 2019 11:42:42 +0000 (+0200) Subject: :smile: Really improve class templating X-Git-Tag: nightly~2198^2~83 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=f8110bfc54b7ce663d5e46f16e2e88bdb2393199;p=gwion.git :smile: Really improve class templating --- diff --git a/include/cpy_ast.h b/include/cpy_ast.h index 948a3a4d..79487ea2 100644 --- a/include/cpy_ast.h +++ b/include/cpy_ast.h @@ -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 diff --git a/src/parse/cpy_ast.c b/src/parse/cpy_ast.c index c23e7304..3a7937af 100644 --- a/src/parse/cpy_ast.c +++ b/src/parse/cpy_ast.c @@ -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); diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 9311ef3d..5a2468a8 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -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); diff --git a/src/parse/template.c b/src/parse/template.c index 82d7778d..8d79762a 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -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;