From: fennecdjay Date: Sat, 18 May 2019 22:27:01 +0000 (+0200) Subject: :art: improve template calling X-Git-Tag: nightly~2453^2~6 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=f6a000eb7364c567972f6670e61f9e872a423242;p=gwion.git :art: improve template calling --- diff --git a/include/env.h b/include/env.h index 4dc3f5a7..6dab0b09 100644 --- a/include/env.h +++ b/include/env.h @@ -58,7 +58,7 @@ ANN Type find_type(const Env, ID_List); ANN m_bool already_defined(const Env env, const Symbol s, const loc_t pos); ANN m_bool type_engine_check_prog(const Env, const Ast); ANN Func get_func(const Env, const Func_Def); -ANN m_bool traverse_func_template(const Env env, const Func_Def def, const Type_List types); +ANN m_bool traverse_func_template(const Env, const Func_Def); ANN ID_List str2list(const Env, const m_str path, m_uint* array_depth); ANN2(1,3) void env_err(const Env, const struct YYLTYPE *pos, const m_str fmt, ...); #endif diff --git a/include/template.h b/include/template.h index cdc16686..a733a99b 100644 --- a/include/template.h +++ b/include/template.h @@ -1,5 +1,5 @@ #ifndef __TEMPLATE #define __TEMPLATE -ANN m_bool template_push_types(const Env, ID_List, Type_List); +ANN m_bool template_push_types(const Env, const Tmpl*); #define POP_RET(a) { nspc_pop_type(env->gwion->mp, env->curr); return (a); } #endif diff --git a/src/emit/emit.c b/src/emit/emit.c index 24e804e7..259aa9fd 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -680,18 +680,18 @@ ANN static m_bool prepare_call(const Emitter emit, const Exp_Call* exp_call) { return emit_exp(emit, exp_call->func, 0); } -ANN static inline m_int push_tmpl_func(const Emitter emit, const Func f, - const Type_List types) { +ANN static inline m_int push_tmpl_func(const Emitter emit, const Func f) { const Value v = f->value_ref; const m_uint scope = emit_push(emit, v->owner_class, v->owner); - CHECK_BB(traverse_func_template(emit->env, f->def, types)) + CHECK_BB(traverse_func_template(emit->env, f->def)) return (m_int)scope; } 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); - const m_int scope = push_tmpl_func(emit, exp_call->m_func, exp_call->tmpl->call); + exp_call->m_func->def->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)) emit_pop_type(emit); @@ -751,7 +751,8 @@ 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; - if(traverse_func_template(emit->env, dt->def, dt->tl) > 0) { + dt->def->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); } diff --git a/src/parse/check.c b/src/parse/check.c index a34ebc58..6dbecbd5 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -438,7 +438,8 @@ if(types->td->types)exit(12); def->tmpl = new_tmpl(env->gwion->mp, base->tmpl->list, (m_int)i); SET_FLAG(def, template); } - if(traverse_func_template(env, def, types) > 0) { + def->tmpl->call = types; + if(traverse_func_template(env, def) > 0) { nspc_pop_type(env->gwion->mp, env->curr); if(check_call(env, exp) > 0) { const Func next = def->base->func->next; diff --git a/src/parse/scanx.c b/src/parse/scanx.c index 50aa1277..be6917e4 100644 --- a/src/parse/scanx.c +++ b/src/parse/scanx.c @@ -15,25 +15,26 @@ ANN static inline m_bool _body(const Env e, Class_Body b, const _exp_func f) { return GW_OK; } +ANN static inline int actual(const Tmpl *tmpl) { + return tmpl->call && tmpl->call != (Type_List)1; +} + ANN static inline m_bool tmpl_push(const Env env, const Tmpl* tmpl) { - if(tmpl->call && tmpl->call != (Type_List)1) { - CHECK_BB(template_push_types(env, tmpl->list, tmpl->call)) - return GW_OK; - } + if(actual(tmpl)) + return template_push_types(env, tmpl); return 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) < 0) - ERR_B(c->pos, "you must provide template types for type '%s'", - s_name(c->base.xid)) + if(c->tmpl && !tmpl_push(env, c->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 && c->tmpl->call != (Type_List)1) - nspc_pop_type(e->gwion->mp, e->curr); + if(c->tmpl && actual(c->tmpl)) + nspc_pop_type(e->gwion->mp, e->curr); env_pop(e, s); } diff --git a/src/parse/template.c b/src/parse/template.c index 84cdd61d..60749128 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -120,8 +120,9 @@ ANN static Class_Def template_class(const Env env, const Class_Def def, const Ty loc_cpy(env->gwion->mp, def->pos)); } -ANN m_bool template_push_types(const Env env, ID_List base, Type_List tl) { - Type_List call = tl; +ANN m_bool template_push_types(const Env env, const Tmpl *tmpl) { + ID_List list = tmpl->list; + Type_List call = tmpl->call; nspc_push_type(env->gwion->mp, env->curr); do { if(!call) @@ -129,9 +130,9 @@ ANN m_bool template_push_types(const Env env, ID_List base, Type_List tl) { const Type t = known_type(env, call->td); if(!t) POP_RET(-1); - nspc_add_type(env->curr, base->xid, t); + nspc_add_type(env->curr, list->xid, t); call = call->next; - } while((base = base->next)); + } while((list = list->next)); if(!call) return GW_OK; POP_RET(-1); diff --git a/src/parse/traverse_template.c b/src/parse/traverse_template.c index 94bb009f..9dbbb03f 100644 --- a/src/parse/traverse_template.c +++ b/src/parse/traverse_template.c @@ -8,7 +8,7 @@ #include "vm.h" #include "gwion.h" -ANN m_bool traverse_func_template(const Env env, const Func_Def def, const Type_List types) { - CHECK_BB(template_push_types(env, def->tmpl->list, types)) +ANN m_bool traverse_func_template(const Env env, const Func_Def def) { + CHECK_BB(template_push_types(env, def->tmpl)) return traverse_func_def(env, def); }