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