#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);
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)
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);
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]);
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);
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;
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) {
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;
}
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;
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
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;