]> Nishi Git Mirror - gwion.git/commitdiff
:art: improve template calling
authorfennecdjay <astor.jeremie@wanadoo.fr>
Sat, 18 May 2019 22:27:01 +0000 (00:27 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Sat, 18 May 2019 22:27:01 +0000 (00:27 +0200)
include/env.h
include/template.h
src/emit/emit.c
src/parse/check.c
src/parse/scanx.c
src/parse/template.c
src/parse/traverse_template.c

index 4dc3f5a722f7b1b97f3ea45eeb46e22ef7948812..6dab0b09acdcfbcf96759eda69b0c15b9375bc53 100644 (file)
@@ -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
index cdc16686206749072df597b1c1a17431236b7480..a733a99bfb003735f9144a340d6ba417b3abf123 100644 (file)
@@ -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
index 24e804e74670f382d41179d8310f4d4c764f6531..259aa9fd4ec6dad7d845b0cd8a34ab15d0e1b79d 100644 (file)
@@ -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);
   }
index a34ebc58d812c96941acdeba50bd56e2afaaff14..6dbecbd5ed6acb99b6c49dfec2bf1c706d5b649b 100644 (file)
@@ -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;
index 50aa12774ed3338b8163c6804011712722e11b82..be6917e4c961131e9cb71fc781d93d86e016a2cc 100644 (file)
@@ -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);
 }
 
index 84cdd61d7c6d6f887a22de59f1e6be16433402a7..60749128d7194d83515ce68fc3986b0463389101 100644 (file)
@@ -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);
index 94bb009f437dec799eed39a56995da60fa323c1c..9dbbb03f5c1ae28de57cee859290decddb4183f3 100644 (file)
@@ -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);
 }