From 7e83c9c298fb9898766ee6da3e3d82680f4a2f5d Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Tue, 21 May 2019 00:15:59 +0200 Subject: [PATCH] :art: Type alias templating --- ast | 2 +- include/parse.h | 10 +++++++ src/emit/emit.c | 42 ++++++++++++++------------ src/lib/import.c | 4 +-- src/lib/instr.c | 2 +- src/parse/check.c | 50 +++++++++++++------------------ src/parse/func.c | 2 +- src/parse/scan0.c | 11 +++---- src/parse/scan1.c | 20 +++++-------- src/parse/scan2.c | 20 ++++++------- src/parse/scanx.c | 55 +++++++++++++++++++++++++++++++---- src/parse/template.c | 16 +++++----- src/parse/traverse_template.c | 2 +- util | 2 +- 14 files changed, 140 insertions(+), 98 deletions(-) diff --git a/ast b/ast index c902b188..2f8759c5 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit c902b1888ae8aadcb2cdf6000308e0d55043b8ed +Subproject commit 2f8759c59db171ce3d4737c7912b3b57d1d6dec6 diff --git a/include/parse.h b/include/parse.h index c3ef0eb6..42dbcd68 100644 --- a/include/parse.h +++ b/include/parse.h @@ -69,4 +69,14 @@ static inline ANN m_bool env_body(const Env env, const Class_Def cdef, const _ex return scanx_body(env, cdef, f, env); } #define env_body(a,b,c) env_body(a,b,(_exp_func)c) + +ANN m_bool scanx_ext(const Env e, const Class_Def c, const _exp_func f, void* d); +static inline ANN m_bool env_ext(const Env env, const Class_Def cdef, const _exp_func f) { + return scanx_ext(env, cdef, f, env); +} +#define env_ext(a,b,c) env_ext(a, b, (_exp_func)c) +#define scanx_ext(a,b,c,d) scanx_ext(a, b, (_exp_func)c, d) + +ANN m_bool scanx_parent(const Type t, const _exp_func f, void *d); +#define scanx_parent(a,b,c) scanx_parent(a, (_exp_func)b, c) #endif diff --git a/src/emit/emit.c b/src/emit/emit.c index 7926d6fe..5bb689f2 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -608,10 +608,14 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_de ANN static m_bool emit_class_def(const Emitter, const Class_Def); +ANN static m_bool emit_parent_inner(const Emitter emit, const Class_Def cdef) { + CHECK_BB(traverse_class_def(emit->env, cdef)) + return emit_class_def(emit, cdef); +} + ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) { - const Type t = typedef_base(decl->type); - CHECK_BB(traverse_class_def(emit->env, t->e->def)) - return !GET_FLAG(t, emit) ? emit_class_def(emit, t->e->def) : GW_OK; + const Type t = decl->type; + return !GET_FLAG(t, emit) ? emit_parent_inner(emit, t->e->def) : GW_OK; } ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) { @@ -687,7 +691,7 @@ ANN static inline m_int push_tmpl_func(const Emitter emit, const Func f) { ANN static m_bool emit_exp_call_template(const Emitter emit, const Exp_Call* exp_call) { if(emit->env->func && emit->env->func == exp_call->m_func) return prepare_call(emit, exp_call); - exp_call->m_func->def->tmpl->call = exp_call->tmpl->call; + exp_call->m_func->def->base->tmpl->call = exp_call->tmpl->call; const m_int scope = push_tmpl_func(emit, exp_call->m_func); CHECK_BB(scope); CHECK_BB(prepare_call(emit, exp_call)) @@ -748,7 +752,7 @@ ANN static Type_List tmpl_tl(const Env env, const m_str name) { ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) { const m_uint scope = emit_push_type(emit, dt->owner); m_bool ret = GW_ERROR; - dt->def->tmpl->call = dt->tl;// in INSTR + dt->def->base->tmpl->call = dt->tl;// in INSTR if(traverse_func_template(emit->env, dt->def) > 0) { ret = emit_func_def(emit, dt->def); nspc_pop_type(emit->gwion->mp, emit->env->curr); @@ -768,7 +772,7 @@ static inline m_bool push_func_code(const Emitter emit, const Func f) { c[sz] = '\0'; struct dottmpl_ *dt = mp_calloc(emit->gwion->mp, dottmpl); dt->name = s_name(insert_symbol(c)); - dt->overload = f->def->tmpl->base; + dt->overload = f->def->base->tmpl->base; dt->tl = tmpl_tl(emit->env, c); dt->base = f->def; instr->opcode = eOP_MAX; @@ -1552,7 +1556,7 @@ ANN static m_bool emit_member_func(const Emitter emit, const Exp_Dot* member, co func_i->m_val = (m_uint)(func->code ?: (VM_Code)func); return GW_OK; } - if(func->def->tmpl) + if(func->def->base->tmpl) emit_add_instr(emit, DotTmplVal); else { const Instr instr = emit_add_instr(emit, GET_FLAG(func, member) ? DotFunc : DotStaticFunc); @@ -1662,13 +1666,13 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { const Func former = emit->env->func; if(func->code) return GW_OK; - if(tmpl_base(func_def->tmpl)) { + if(tmpl_base(func_def->base->tmpl)) { UNSET_FLAG(func_def, template); return GW_OK; } if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template)) return GW_OK; - if(!emit->env->class_def && !GET_FLAG(func_def, global) && !func_def->tmpl && !emit->env->scope->depth) + if(!emit->env->class_def && !GET_FLAG(func_def, global) && !func_def->base->tmpl && !emit->env->scope->depth) func->value_ref->offset = emit_local(emit, SZ_INT, 0); emit_func_def_init(emit, func); if(GET_FLAG(func, member)) @@ -1690,7 +1694,7 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { emit_pop_code(emit); if(GET_FLAG(func_def, op)) SET_FLAG(func->code, op); - if(!emit->env->class_def && !GET_FLAG(func_def, global) && !func_def->tmpl) + if(!emit->env->class_def && !GET_FLAG(func_def, global) && !func_def->base->tmpl) emit_func_def_global(emit, func->value_ref); if(emit->memoize && GET_FLAG(func, pure)) func->code->memoize = memoize_ini(emit, func, @@ -1712,20 +1716,21 @@ ANN Code* emit_class_code(const Emitter emit, const m_str name) { ANN inline void emit_class_finish(const Emitter emit, const Nspc nspc) { emit_add_instr(emit, FuncReturn); nspc->pre_ctor = emit_code(emit); + SET_FLAG(nspc->pre_ctor, ctor); +} + +ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) { + const Type parent = cdef->base.type->e->parent; + return scanx_parent(parent, emit_parent_inner, emit); } ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { const Type type = cdef->base.type; const Nspc nspc = type->nspc; - if(tmpl_base(cdef->tmpl)) + if(tmpl_base(cdef->base.tmpl)) return GW_OK; - if(cdef->base.ext && ((!GET_FLAG(type->e->parent, emit) && - GET_FLAG(cdef->base.ext, typedef)) || cdef->base.ext->types)) { - const Type base = cdef->base.ext->array ? - array_base(type->e->parent) : type->e->parent; - if(!base->nspc->pre_ctor) - CHECK_BB(emit_class_def(emit, base->e->def)) - } + if(cdef->base.ext && cdef->base.ext->types) + CHECK_BB(scanx_ext(emit->env, cdef, emit_parent, emit)) nspc_allocdata(emit->gwion->mp, nspc); emit_class_code(emit, type->name); if(cdef->base.ext && cdef->base.ext->array) @@ -1733,7 +1738,6 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { if(cdef->body) CHECK_BB(scanx_body(emit->env, cdef, (_exp_func)emit_section, emit)) emit_class_finish(emit, nspc); - SET_FLAG(cdef->base.type->nspc->pre_ctor, ctor); emit_pop_code(emit); SET_FLAG(type, emit); return GW_OK; diff --git a/src/lib/import.c b/src/lib/import.c index 7b2dc7ee..f8aea4e4 100644 --- a/src/lib/import.c +++ b/src/lib/import.c @@ -221,7 +221,7 @@ ANN2(1,2) m_int gwi_class_ini(const Gwi gwi, const Type type, const f_xtor pre_c if(gwi->templater.n) { const ID_List types = templater_def(gwi->gwion->st, gwi); type->e->def = new_class_def(gwi->gwion->mp, 0, insert_symbol(gwi->gwion->st, type->name), NULL, NULL, loc_cpy(gwi->gwion->mp, gwi->loc)); - type->e->def->tmpl = new_tmpl(gwi->gwion->mp, types, -1); + type->e->def->base.tmpl = new_tmpl(gwi->gwion->mp, types, -1); type->e->def->base.type = type; SET_FLAG(type, template); } else @@ -452,7 +452,7 @@ ANN m_int gwi_func_end(const Gwi gwi, const ae_flag flag) { if(gwi->templater.n) { def = new_func_def(gwi->gwion->mp, new_func_base(gwi->gwion->mp, NULL, NULL, NULL), NULL, 0, loc_cpy(gwi->gwion->mp, gwi->loc)); const ID_List list = templater_def(gwi->gwion->st, gwi); - def->tmpl = new_tmpl(gwi->gwion->mp, list, -1); + def->base->tmpl = new_tmpl(gwi->gwion->mp, list, -1); SET_FLAG(def, template); } if(gwi->gwion->env->class_def && GET_FLAG(gwi->gwion->env->class_def, template)) { diff --git a/src/lib/instr.c b/src/lib/instr.c index 4929dc44..8529b8cd 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -66,7 +66,7 @@ ANN static Func_Def from_base(const Env env, const struct dottmpl_ *dt, const Ty const Func_Def base = v->d.func_ref->def; const Func_Def def = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, base->base->td, insert_symbol(env->gwion->st, v->name), base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->mp, base->pos)); - def->tmpl = new_tmpl(env->gwion->mp, base->tmpl->list, dt->overload); + def->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, dt->overload); SET_FLAG(def, template); return def; } diff --git a/src/parse/check.c b/src/parse/check.c index 6dbecbd5..f6c07bd2 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -104,9 +104,8 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { if(!decl->type) // TODO: remove when scan passes are complete ERR_O(td_pos(decl->td), "can't infer type."); if(GET_FLAG(decl->type , template)) { - const Type t = typedef_base(decl->type); - if(!GET_FLAG(t, check)) - CHECK_BO(traverse_class_def(env, t->e->def)) + if(!GET_FLAG(decl->type, check)) + CHECK_BO(traverse_class_def(env, decl->type->e->def)) } const m_bool global = GET_FLAG(decl->td, global); const m_uint scope = !global ? env->scope->depth : env_push_global(env); @@ -258,7 +257,7 @@ ANN static Type prim_vec(const Env env, const Exp_Primary* primary) { struct VecInfo info = { .n=vec->dim }; vec_info(t, &info); if(vec->dim > info.n) - ERR_O(vec->exp->pos, "extraneous component of %s value...", info.s) + ERR_O(vec->exp->pos, "extraneous component of %s value...", info.t->name) CHECK_BO(vec_value(env, vec->exp, info.s)) return info.t; } @@ -423,11 +422,11 @@ if(types->td->types)exit(12); return env->func; } base = def = value->d.func_ref->def; - if(!def->tmpl) { + if(!def->base->tmpl) { if(!(value = template_get_ready(env, v, "template", i))) continue; base = value->d.func_ref->def; - def->tmpl = new_tmpl(env->gwion->mp, base->tmpl->list, (m_int)i); + def->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i); } } else { if(!(value = template_get_ready(env, v, "template", i))) @@ -435,10 +434,10 @@ if(types->td->types)exit(12); base = value->d.func_ref->def; def = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, base->base->td, insert_symbol(v->name), base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->mp, base->pos)); - def->tmpl = new_tmpl(env->gwion->mp, base->tmpl->list, (m_int)i); + def->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i); SET_FLAG(def, template); } - def->tmpl->call = types; + def->base->tmpl->call = types; if(traverse_func_template(env, def) > 0) { nspc_pop_type(env->gwion->mp, env->curr); if(check_call(env, exp) > 0) { @@ -518,7 +517,7 @@ ANN static Func get_template_func(const Env env, const Exp_Call* func, const Val const Func f = find_template_match(env, v, func); if(f) { Tmpl* tmpl = new_tmpl_call(env->gwion->mp, func->tmpl->call); - tmpl->list = v->d.func_ref->def->tmpl->list; + tmpl->list = v->d.func_ref->def->base->tmpl->list; ((Exp_Call*)func)->tmpl = tmpl; return ((Exp_Call*)func)->m_func = f; } @@ -535,9 +534,9 @@ ANN static Type check_exp_call_template(const Env env, const Exp_Call *exp) { m_uint args_number = 0; const Value value = nspc_lookup_value1(call->type->e->owner, insert_symbol(call->type->name)); CHECK_OO(value) - const m_uint type_number = get_type_number(value->d.func_ref->def->tmpl->list); + const m_uint type_number = get_type_number(value->d.func_ref->def->base->tmpl->list); Type_List tl[type_number]; - ID_List list = value->d.func_ref->def->tmpl->list; + ID_List list = value->d.func_ref->def->base->tmpl->list; while(list) { Arg_List arg = value->d.func_ref->def->base->args; Exp template_arg = args; @@ -650,7 +649,7 @@ ANN static Type check_exp_call(const Env env, Exp_Call* exp) { ERR_O(exp_self(exp)->pos, " template call of non-existant function.") if(!GET_FLAG(v, func)) ERR_O(exp_self(exp)->pos, "template call of non-function value.") - if(!v->d.func_ref->def->tmpl) + if(!v->d.func_ref->def->base->tmpl) ERR_O(exp_self(exp)->pos, "template call of non-template function.") const Func ret = find_template_match(env, v, exp); CHECK_OO((exp->m_func = ret)) @@ -1007,7 +1006,7 @@ ANN static m_bool check_signature_match(const Env env, const Func_Def f, const F c_name, f_name, p_name, c_name, GET_FLAG(f, static) ? c_name : p_name, f_name) } - return !f->tmpl ? isa(f->base->ret_type, parent->def->base->ret_type) : GW_OK; + return !f->base->tmpl ? isa(f->base->ret_type, parent->def->base->ret_type) : GW_OK; } ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def f, @@ -1016,7 +1015,7 @@ 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(env, f, parent_func)) - if(!f->tmpl) { + if(!f->base->tmpl) { f->base->func->vt_index = parent_func->vt_index; vector_set(&env->curr->info->vtable, f->base->func->vt_index, (vtype)f->base->func); } @@ -1088,7 +1087,7 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def f) { "\tfrom super class '%s'...", s_name(f->base->xid), override->owner_class->name) } - if(func->value_ref->offset && (!f->tmpl || !f->tmpl->base)) + if(func->value_ref->offset && (!f->base->tmpl || !f->base->tmpl->base)) CHECK_BB(check_func_overload(env, f)) return GW_OK; } @@ -1113,7 +1112,7 @@ ANN static void operator_func(const Func f) { ANN m_bool check_func_def(const Env env, const Func_Def f) { const Func func = get_func(env, f); m_bool ret = GW_OK; - if(tmpl_base(f->tmpl)) + if(tmpl_base(f->base->tmpl)) return env->class_def ? check_parent_match(env, f) : 1; if(f->base->td && !f->base->td->xid) { f->base->ret_type = check_td(env, f->base->td); @@ -1156,18 +1155,9 @@ DECL_SECTION_FUNC(check) ANN static m_bool check_class_parent(const Env env, const Class_Def cdef) { const Type parent = cdef->base.type->e->parent; const Type_Decl *td = cdef->base.ext; - if(td->array) { + if(td->array) CHECK_BB(check_exp_array_subscripts(env, td->array->exp)) - if(!GET_FLAG(cdef->base.type, check) && cdef->tmpl) - REM_REF(parent->nspc, env->gwion); - } - if(td->types) { - const Type t = parent->array_depth ? array_base(parent) : parent; - if(!GET_FLAG(t, checked)) - CHECK_BB(traverse_class_def(env, t->e->def)) - } - if(!GET_FLAG(parent, checked)) - CHECK_BB(check_class_def(env, parent->e->def)) + CHECK_BB(scanx_parent(parent, traverse_class_def, env)) if(GET_FLAG(parent, typedef)) SET_FLAG(cdef->base.type, typedef); return GW_OK; @@ -1181,15 +1171,15 @@ ANN static inline void inherit(const Type t) { } ANN m_bool check_class_def(const Env env, const Class_Def cdef) { - if(tmpl_base(cdef->tmpl)) + if(tmpl_base(cdef->base.tmpl)) return GW_OK; const Type type = cdef->base.type; - if(type->e->parent == t_undefined) { + if(type->e->parent == t_undefined) { type->e->parent = check_td(env, cdef->base.ext); return traverse_class_def(env, cdef); } if(cdef->base.ext) - CHECK_BB(check_class_parent(env, cdef)) + CHECK_BB(env_ext(env, cdef, check_class_parent)) else if(!type->e->parent) type->e->parent = t_object; inherit(type); diff --git a/src/parse/func.c b/src/parse/func.c index 62597aaa..d34f381d 100644 --- a/src/parse/func.c +++ b/src/parse/func.c @@ -11,7 +11,7 @@ ANN static void free_func(Func a, Gwion gwion) { if(GET_FLAG(a, template)) { - free_tmpl(gwion->mp, a->def->tmpl); + free_tmpl(gwion->mp, a->def->base->tmpl); free_func_base(gwion->mp, a->def->base); free_loc(gwion->mp, a->def->pos); mp_free(gwion->mp, Func_Def, a->def); diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 9c8ebbdf..10ac8069 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -45,7 +45,7 @@ ANN m_bool scan0_stmt_fptr(const Env env, const Stmt_Fptr stmt) { ANN m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) { CHECK_BB(env_access(env, stmt->ext->flag, stmt_self(stmt)->pos)) - const Type base = known_type(env, stmt->ext); + const Type base = stmt->tmpl ? find_type(env, stmt->ext->xid) : known_type(env, stmt->ext); CHECK_OB(base) CHECK_BB(scan0_defined(env, stmt->xid, td_pos(stmt->ext))) if(!stmt->ext->types && (!stmt->ext->array || !stmt->ext->array->exp)) { @@ -65,6 +65,7 @@ ANN m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) { loc_cpy(env->gwion->mp, td_pos(stmt->ext))); CHECK_BB(scan0_class_def(env, cdef)) stmt->type = cdef->base.type; + cdef->base.tmpl = stmt->tmpl; } SET_FLAG(stmt->type, typedef); return GW_OK; @@ -200,7 +201,7 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) { t->flag = cdef->flag; if(!strstr(t->name, "<")) nspc_add_type(env->curr, cdef->base.xid, t); - if(cdef->tmpl) { + if(cdef->base.tmpl) { SET_FLAG(t, template); SET_FLAG(cdef, template); } @@ -227,10 +228,10 @@ ANN m_bool scan0_class_def(const Env env, const Class_Def cdef) { CHECK_BB(scan0_class_def_pre(env, cdef)) CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef))) if(cdef->body) { -int call = cdef->tmpl && !cdef->tmpl->call; -if(call)cdef->tmpl->call = (Type_List)1; +int call = cdef->base.tmpl && !cdef->base.tmpl->call; +if(call)cdef->base.tmpl->call = (Type_List)1; CHECK_BB(env_body(env, cdef, scan0_section)) -if(call)cdef->tmpl->call = NULL; +if(call)cdef->base.tmpl->call = NULL; } (void)mk_class(env, cdef->base.type); if(GET_FLAG(cdef, global)) diff --git a/src/parse/scan1.c b/src/parse/scan1.c index a5fe7efa..68b83bee 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -287,7 +287,7 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) { ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { if(fdef->base->td) CHECK_BB(env_storage(env, fdef->flag, td_pos(fdef->base->td))) - if(tmpl_base(fdef->tmpl)) + if(tmpl_base(fdef->base->tmpl)) return GW_OK; struct Func_ fake = { .name=s_name(fdef->base->xid) }, *const former = env->func; env->func = &fake; @@ -309,27 +309,21 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { DECL_SECTION_FUNC(scan1) -ANN static m_bool scan1_class_parent(const Env env, const Class_Def cdef) { +ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) { const loc_t pos = td_pos(cdef->base.ext); if(cdef->base.ext->array) CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp)) const Type parent = cdef->base.type->e->parent = known_type(env, cdef->base.ext); CHECK_OB(parent) - if(parent == t_undefined) - return GW_OK; Type t = parent; while(t) { if(cdef->base.type == t) ERR_B(pos, "recursive (%s <= %s) class declaration.", cdef->base.type->name, t->name); t = t->e->parent; } - if(parent == cdef->base.type) - ERR_B(pos, "class '%s' cannot extend itself", cdef->base.type->name); - if(isa(cdef->base.type->e->parent, t_object) < 0) - ERR_B(pos, "cannot extend primitive type '%s'", - cdef->base.type->e->parent->name) - if(!GET_FLAG(parent, scan1) && parent->e->def) - CHECK_BB(scan1_class_def(env, parent->e->def)) + if(isa(parent, t_object) < 0) + ERR_B(pos, "cannot extend primitive type '%s'", parent->name) + CHECK_BB(scanx_parent(parent, scan1_class_def, env)) if(type_ref(parent)) ERR_B(pos, "can't use ref type in class extend") return GW_OK; @@ -338,10 +332,10 @@ ANN static m_bool scan1_class_parent(const Env env, const Class_Def cdef) { ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) { if(!cdef->base.type) CHECK_BB(scan0_class_def(env, cdef)) - if(tmpl_base(cdef->tmpl)) + if(tmpl_base(cdef->base.tmpl)) return GW_OK; if(cdef->base.ext) - CHECK_BB(scan1_class_parent(env, cdef)) + CHECK_BB(env_ext(env, cdef, scan1_parent)) if(cdef->body) CHECK_BB(env_body(env, cdef, scan1_section)) SET_FLAG(cdef->base.type, scan1); diff --git a/src/parse/scan2.c b/src/parse/scan2.c index c1860089..254967f1 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -298,7 +298,7 @@ ANN static m_bool scan2_stmt_list(const Env env, Stmt_List list) { } ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) { - const m_bool base = tmpl_base(f->tmpl); + const m_bool base = tmpl_base(f->base->tmpl); const m_bool tmpl = GET_FLAG(overload, template); if(isa(overload->type, t_function) < 0 || isa(overload->type, t_fptr) > 0) ERR_B(f->pos, "function name '%s' is already used by another value", overload->name) @@ -438,7 +438,7 @@ ANN static void scan2_func_def_flag(const Env env, const Func_Def f) { ANN static m_str func_tmpl_name(const Env env, const Func_Def f) { const m_str name = s_name(f->base->xid); struct Vector_ v; - ID_List id = f->tmpl->list; + ID_List id = f->base->tmpl->list; m_uint tlen = 0; vector_init(&v); do { @@ -461,7 +461,7 @@ ANN static m_str func_tmpl_name(const Env env, const Func_Def f) { } tmpl_name[tlen+1] = '\0'; vector_release(&v); - const Symbol sym = func_symbol(env, env->curr->name, name, tmpl_name, (m_uint)f->tmpl->base); + const Symbol sym = func_symbol(env, env->curr->name, name, tmpl_name, (m_uint)f->base->tmpl->base); return s_name(sym); } @@ -500,7 +500,7 @@ ANN static m_str template_helper(const Env env, const Func_Def f) { } ANN2(1,2) static m_str func_name(const Env env, const Func_Def f, const Value v) { - if(!f->tmpl) { + if(!f->base->tmpl) { const Symbol sym = func_symbol(env, env->curr->name, s_name(f->base->xid), NULL, v ? ++v->offset : 0); return s_name(sym); } @@ -516,7 +516,7 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { f->stack_depth = 0; if(overload) CHECK_BB(scan2_func_def_overload(env, f, overload)) - if(tmpl_base(f->tmpl)) + if(tmpl_base(f->base->tmpl)) return scan2_func_def_template(env, f, overload); const m_str name = func_name(env, f, overload); if((m_int)name <= GW_OK) @@ -547,20 +547,18 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { DECL_SECTION_FUNC(scan2) ANN static m_bool scan2_class_parent(const Env env, const Class_Def cdef) { - const Type t = cdef->base.type->e->parent->array_depth ? - array_base(cdef->base.type->e->parent) : cdef->base.type->e->parent; - if(!GET_FLAG(t, scan2) && GET_FLAG(cdef->base.ext, typedef)) - CHECK_BB(scan2_class_def(env, t->e->def)) + const Type parent = cdef->base.type->e->parent; + CHECK_BB(scanx_parent(parent, scan2_class_def, env)) if(cdef->base.ext->array) CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp)) return GW_OK; } ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) { - if(tmpl_base(cdef->tmpl)) + if(tmpl_base(cdef->base.tmpl)) return GW_OK; if(cdef->base.ext) - CHECK_BB(scan2_class_parent(env, cdef)) + CHECK_BB(env_ext(env, cdef, scan2_class_parent)) if(cdef->body) CHECK_BB(env_body(env, cdef, scan2_section)) SET_FLAG(cdef->base.type, scan2); diff --git a/src/parse/scanx.c b/src/parse/scanx.c index be6917e4..e722b086 100644 --- a/src/parse/scanx.c +++ b/src/parse/scanx.c @@ -20,20 +20,18 @@ ANN static inline int actual(const Tmpl *tmpl) { } ANN static inline m_bool tmpl_push(const Env env, const Tmpl* tmpl) { - if(actual(tmpl)) - return template_push_types(env, tmpl); - return GW_ERROR; + return actual(tmpl) ? template_push_types(env, tmpl) : GW_ERROR; } ANN static inline m_int _push(const Env env, const Class_Def c) { const m_uint scope = env_push_type(env, c->base.type); - if(c->tmpl && !tmpl_push(env, c->tmpl)) + if(c->base.tmpl && !tmpl_push(env, c->base.tmpl)) return GW_ERROR; return scope; } ANN static inline void _pop(const Env e, const Class_Def c, const m_uint s) { - if(c->tmpl && actual(c->tmpl)) + if(c->base.tmpl && actual(c->base.tmpl)) nspc_pop_type(e->gwion->mp, e->curr); env_pop(e, s); } @@ -46,3 +44,50 @@ scanx_body(const Env e, const Class_Def c, const _exp_func f, void* d) { _pop(e, c, scope); return ret; } + +#undef scanx_ext +ANN m_bool +scanx_ext(const Env e, const Class_Def c, const _exp_func f, void* d) { + const m_int scope = _push(e, c); + CHECK_BB(scope) + const m_bool ret = f(d, c); + _pop(e, c, scope); + return ret; +} +#undef scanx_parent +__attribute__((returns_nonnull)) +static inline Type get_type(const Type t) { + return !t->array_depth ? t : array_base(t); +} + +__attribute__((returns_nonnull)) +static inline Class_Def get_type_def(const Type t) { + return get_type(t)->e->def; +} + +ANN m_bool +scanx_parent(const Type t, const _exp_func f, void* d) { + const Class_Def def = get_type_def(t); + return def ? f(d, def) : GW_OK; +} +/* +struct Parent_ { + void* ptr; + const Type t; + m_bool (*f)(void*, void*); + const ae_flag flag; +}; +ANN m_bool scanx_parent_actual(void* ptr, const Type t, m_bool (*f)(void*, void*), const ae_flag flag) { + if(t->e->def && (t->flag & flag) != flag) + return f(ptr, t->e->def); + return GW_OK; +} + +ANN m_bool scanx_parent(void* ptr, const Type t, m_bool (*f)(void*, void*), const ae_flag flag) { + if(t->array_depth) + CHECK_BB(f(ptr, array_base(t))) + else + CHECK_BB(f(ptr, t)) + return GW_OK; +} +*/ diff --git a/src/parse/template.c b/src/parse/template.c index 60749128..f2511a58 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -19,7 +19,7 @@ ANN static inline Type owner_type(const Env env, const Type t) { 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->tmpl->list); + vector_add(v, (vtype)t->e->def->base.tmpl->list); while((t = owner_type(env, t))); return v; } @@ -35,12 +35,12 @@ ANEW ANN static ID_List id_list_copy(MemPool p, ID_List src) { ANN static ID_List get_total_type_list(const Env env, const Type t) { const Type parent = owner_type(env, t); if(!parent) - return t->e->def->tmpl ? t->e->def->tmpl->list : NULL; + return t->e->def->base.tmpl ? t->e->def->base.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 t->e->def->tmpl ? t->e->def->tmpl->list : NULL; + return t->e->def->base.tmpl ? t->e->def->base.tmpl->list : NULL; } const ID_List types = id_list_copy(env->gwion->mp, base); ID_List list, tmp = types; @@ -48,7 +48,7 @@ ANN static ID_List get_total_type_list(const Env env, const Type t) { list = (ID_List)vector_pop(v); tmp = (tmp->next = id_list_copy(env->gwion->mp, list)); } - tmp->next = t->e->def->tmpl->list; + tmp->next = t->e->def->base.tmpl->list; free_vector(env->gwion->mp, v); return types; } @@ -69,7 +69,7 @@ ANN static inline size_t tmpl_set(struct tmpl_info* info, const Type t) { } ANN static size_t template_size(const Env env, struct tmpl_info* info) { - ID_List base = info->cdef->tmpl->list; + ID_List base = info->cdef->base.tmpl->list; size_t size = tmpl_set(info, info->cdef->base.type); do size += tmpl_set(info, type_decl_resolve(env, info->call->td)); while((info->call = info->call->next) && (base = base->next) && ++size); @@ -150,14 +150,14 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) { if(!type->types) ERR_O(t->e->def->pos, "you must provide template types for type '%s'", t->name) - if(template_match(t->e->def->tmpl->list, type->types) < 0) + if(template_match(t->e->def->base.tmpl->list, type->types) < 0) ERR_O(type->xid->pos, "invalid template types number") const Class_Def a = template_class(env, t->e->def, type->types); SET_FLAG(a, ref); if(a->base.type) return a->base.type; - a->tmpl = new_tmpl(env->gwion->mp, get_total_type_list(env, t), 0); - a->tmpl->call = type->types; + a->base.tmpl = new_tmpl(env->gwion->mp, get_total_type_list(env, t), 0); + a->base.tmpl->call = type->types; CHECK_BO(scan0_class_def(env, a)) SET_FLAG(a->base.type, template | ae_flag_ref); diff --git a/src/parse/traverse_template.c b/src/parse/traverse_template.c index 9dbbb03f..8b32476f 100644 --- a/src/parse/traverse_template.c +++ b/src/parse/traverse_template.c @@ -9,6 +9,6 @@ #include "gwion.h" ANN m_bool traverse_func_template(const Env env, const Func_Def def) { - CHECK_BB(template_push_types(env, def->tmpl)) + CHECK_BB(template_push_types(env, def->base->tmpl)) return traverse_func_def(env, def); } diff --git a/util b/util index 059393b7..6e10d0bd 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 059393b7d69ed555bfef29ba99500d508a378637 +Subproject commit 6e10d0bd6a9e6731e35cc01d44562e0271755676 -- 2.43.0