]> Nishi Git Mirror - gwion.git/commitdiff
:art: update towards const generics
authorfennecdjay <fennecdjay@gmail.com>
Fri, 29 Sep 2023 18:23:59 +0000 (20:23 +0200)
committerfennecdjay <fennecdjay@gmail.com>
Fri, 29 Sep 2023 18:23:59 +0000 (20:23 +0200)
19 files changed:
src/clean.c
src/emit/emit.c
src/env/context.c
src/env/func.c
src/import/import_checker.c
src/lib/array.c
src/lib/closure.c
src/lib/dict.c
src/lib/ref.c
src/lib/tmpl_info.c
src/lib/union.c
src/parse/check.c
src/parse/func_resolve_tmpl.c
src/parse/operator.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/spread.c
src/parse/template.c
src/parse/type_decl.c

index d5308ab135405b1a8e96f298141207d5c28a51c7..aa7d57df587c5fc6fbdbc6f3114d6a3f9e10ed23 100644 (file)
@@ -15,8 +15,11 @@ ANN static void clean_array_sub(Clean *a, Array_Sub b) {
 
 ANN static void clean_type_list(Clean *a, Type_List b) {
   for(uint32_t i = 0; i < b->len; i++) {
-    Type_Decl *td = *mp_vector_at(b, Type_Decl*, i);
-    clean_type_decl(a, td);
+    TmplArg arg = *mp_vector_at(b, TmplArg, i);
+    if(arg.type == tmplarg_td)
+      clean_type_decl(a, arg.d.td);
+    else if(arg.type == tmplarg_exp)
+      clean_exp(a, arg.d.exp);
   }
 }
 
index 4da51effff2acd21bf789af78bc8b962a5c2a47b..52d3734705f7cfd729d4b00ba01d8a853318749f 100644 (file)
@@ -2913,6 +2913,37 @@ ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) {
   return ret;
 }
 
+static INSTR(set) {
+  Value v = *(Value*)(shred->reg + -SZ_INT);
+  shred->reg -= instr->m_val;
+  memcpy(&v->d.ptr, shred->reg, instr->m_val2);
+}
+
+ANN static m_bool emit_class_tmpl(const Emitter emit, const Tmpl *tmpl, const Nspc nspc) {
+  if(tmplarg_ntypes(tmpl->list) != tmpl->list->len) {
+    emit_push_code(emit, "tmpl");
+    for(uint32_t i = 0; i < tmpl->list->len; i++) {
+      const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i);
+      if(likely(targ.type == tmplarg_td)) continue;
+      CHECK_BB(emit_exp(emit, targ.d.exp));
+      const Specialized spec = *mp_vector_at(tmpl->list, Specialized, i);
+      const Value v = nspc_lookup_value1(nspc, spec.xid);
+      emit_pushimm(emit, (m_uint)v);
+      const Instr instr = emit_add_instr(emit, set);
+      instr->m_val2 = targ.d.exp->type->size;
+      instr->m_val = instr->m_val2 + SZ_INT;
+    }
+    VM_Code code = finalyze(emit, EOC);
+    VM_Shred shred = new_vm_shred(emit->gwion->mp, code);
+    vm_add_shred(emit->gwion->vm, shred);
+    const bool loop = emit->gwion->vm->shreduler->loop;
+    vm_run(emit->gwion->vm);
+    emit->gwion->vm->bbq->is_running = true;
+    emit->gwion->vm->shreduler->loop = loop;
+  }
+  return GW_OK;
+}
+
 ANN static m_bool _emit_class_def(const Emitter emit, const Class_Def cdef) {
   const Type      t = cdef->base.type;
   set_tflag(t, tflag_emit);
@@ -2920,6 +2951,7 @@ ANN static m_bool _emit_class_def(const Emitter emit, const Class_Def cdef) {
   if (c->base.ext && t->info->parent->info->cdef &&
       !tflag(t->info->parent, tflag_emit)) // ?????
     CHECK_BB(cdef_parent(emit, c));
+  if (c->base.tmpl) CHECK_BB(emit_class_tmpl(emit, c->base.tmpl, c->base.type->nspc));
   if (c->body)
     return scanx_body(emit->env, c, (_exp_func)emit_section, emit);
   return GW_OK;
index 207062b38cf955420a23095f543e3fa3f50ccd75..e5f5639e1488979513de42bb61447b7fa5c6ce65 100644 (file)
@@ -44,7 +44,7 @@ ANN static void clean(const Nspc nspc, const Env env) {
 
 ANN void unload_context(const Context ctx, const Env env) {
   const Nspc global = ctx->nspc->parent;
-  if(global != env->global_nspc) exit(3);
+  if(global != env->global_nspc) exit(53);
   context_remref(ctx, env->gwion);
   env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
   const Nspc user = (Nspc)vector_at(&env->scope->nspc_stack, 1);
index 4a17896e4b1340e663e46e824c8e193a411d9c09..d06873dd3e3a1c9185f808e4c2836baaf85bf2cd 100644 (file)
@@ -40,14 +40,20 @@ ANN void builtin_func(const Gwion gwion, const Func f, void *func_ptr) {
   f->code = new_vmcode(gwion->mp, NULL, NULL, f->name, f->def->stack_depth, true, false);
   f->code->native_func = (m_uint)func_ptr;
   f->code->ret_type = f->def->base->ret_type;
-  if(f->def->base->tmpl && f->def->base->tmpl->call) {
+  if(f->def->base->tmpl) {
+    const Type_List tl = f->def->base->tmpl->call;
+    if(!tl) return;
     const Specialized *spec = mp_vector_at(f->def->base->tmpl->list, Specialized, f->def->base->tmpl->list->len - 1);
     if(!strcmp(s_name(spec->xid), "...")) {
-      f->code->types = new_mp_vector(gwion->mp, Type_Decl*, f->def->base->tmpl->call->len);
-      for(uint32_t i = 0; i < f->def->base->tmpl->call->len; i++)  {
-        Type_Decl *const td = *mp_vector_at(f->def->base->tmpl->call, Type_Decl*, i);
-        mp_vector_set(f->code->types, Type, i, known_type(gwion->env, td));
+      const uint32_t len = tmplarg_ntypes(tl);
+      f->code->types = new_mp_vector(gwion->mp, Type, len);
+      uint32_t n = 0;
+      for(uint32_t i = 0; i < tl->len; i++)  {
+        const TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+        if(likely(arg.type == tmplarg_td))
+          mp_vector_set(f->code->types, Type, n++, known_type(gwion->env, arg.d.td));
       }
+//      f->code->types->len = n;
     }
   }
 }
index 1b0109bd274fb13c486bd2458177a7811ab675c8..682031260e1f7590c07df93b82b7cce05f03547d 100644 (file)
@@ -133,14 +133,19 @@ ANN m_bool check_typename_def(const Gwi gwi, ImportCK *ck) {
 
 ANN static Type_Decl *_str2td(const Gwion gwion, struct td_checker *tdc);
 ANN bool str2tl(const Gwion gwion, struct td_checker *tdc, Type_List *tl) {
-  Type_Decl *td = _str2td(gwion, tdc);
-  if (!td) GWION_ERR_B(tdc->pos, "invalid types");
-  mp_vector_add(gwion->mp, tl, Type_Decl*, td);
-  if (*tdc->str == ',') {
-    ++tdc->str;
-    if (!str2tl(gwion, tdc, tl))
-      return false;
-  }
+  if(isalpha(*tdc->str)) {
+    TmplArg targ = {
+      .type = tmplarg_td,
+      .d = { .td = _str2td(gwion, tdc) }
+    };
+    if (!targ.d.td) GWION_ERR_B(tdc->pos, "invalid types");
+    mp_vector_add(gwion->mp, tl, TmplArg, targ);
+    if (*tdc->str == ',') {
+      ++tdc->str;
+      if (!str2tl(gwion, tdc, tl))
+        return false;
+    }
+  } else exit(6);
   return true;
 }
 
@@ -152,7 +157,7 @@ ANN static Type_List td_tmpl(const Gwion gwion, struct td_checker *tdc) {
     return (Type_List)GW_ERROR;
   }
   ++tdc->str;
-  Type_List tl = new_mp_vector(gwion->mp, Type_Decl*, 0);
+  Type_List tl = new_mp_vector(gwion->mp, TmplArg, 0);
   if (!str2tl(gwion, tdc, &tl)) {
     free_type_list(gwion->mp, tl);
     return (Type_List)GW_ERROR;
@@ -281,7 +286,7 @@ ANN Type str2type(const Gwion gwion, const m_str str, const loc_t pos) {
 
 struct td_info {
   Type_List tl;
-  GwText    text;
+  Gwfmt     *fmt;
 };
 
 ANN static void td_fullname(const Env env, GwText *text, const Type t) {
@@ -295,15 +300,13 @@ ANN static void td_fullname(const Env env, GwText *text, const Type t) {
 
 ANN static m_bool td_info_run(const Env env, struct td_info *info) {
   Type_List tl = info->tl;
-  if(unlikely(!tl->len)) {
-    text_add(&info->text, "");
-    return GW_OK;
-  }
   for(uint32_t i = 0; i < tl->len; i++) {
-    if (i) text_add(&info->text, ",");
-    DECL_OB(Type_Decl *, td, = *mp_vector_at(tl, Type_Decl*, i));
-    DECL_OB(const Type, t, = known_type(env, td));
-    td_fullname(env, &info->text, t);
+    if (i) text_add(&info->fmt->ls->text, ",");
+    TmplArg targ = *mp_vector_at(tl, TmplArg, i);
+    if(targ.type == tmplarg_td) {
+      DECL_OB(const Type, t, = known_type(env, targ.d.td));
+      td_fullname(env, &info->fmt->ls->text, t);
+    } else gwfmt_exp(info->fmt, targ.d.exp);
   }
   return GW_OK;
 }
@@ -318,10 +321,12 @@ ANEW ANN m_str type2str(const Gwion gwion, const Type t,
 
 ANEW ANN m_str tl2str(const Gwion gwion, const Type_List tl,
                       const loc_t pos NUSED) {
-  struct td_info info = {.tl = tl};
-  text_init(&info.text, gwion->mp);
+  struct GwfmtState ls = {.minimize=true, .ppa = gwion->ppa};
+  text_init(&ls.text, gwion->mp);
+  Gwfmt l = {.mp = gwion->mp, .st = gwion->st, .ls = &ls, .line = 1, .last = cht_nl };
+  struct td_info info = {.tl = tl, .fmt = &l };
   CHECK_BO(td_info_run(gwion->env, &info));
-  return info.text.str;
+  return ls.text.str;
 }
 
 ANN static inline m_bool ac_finish(const Gwion gwion, const struct AC *ac) {
index aede652d9326f8eef63e456d91a9406e865f3f35..8b0f0a699772a67081e5449e526452ccbd01b064 100644 (file)
@@ -799,7 +799,7 @@ static OP_CHECK(opck_array_scan) {
   const Type           t_array = env->gwion->type[et_array];
   const Class_Def      c       = t_array->info->cdef;
   DECL_ON(const Type, base,
-          = ts->t != t_array ? ts->t : known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 0)));
+          = ts->t != t_array ? ts->t : known_type(env, mp_vector_at(ts->td->types, TmplArg, 0)->d.td));
   if (base->size == 0) {
     gwerr_basic("Can't use type of size 0 as array base", NULL, NULL,
                 "/dev/null", (loc_t) {}, 0);
@@ -818,8 +818,9 @@ static OP_CHECK(opck_array_scan) {
   const Class_Def cdef  = cpy_class_def(env->gwion->mp, c);
   cdef->base.ext        = type2td(env->gwion, t_array, (loc_t) {});
   cdef->base.xid        = sym;
-  cdef->base.tmpl->call = new_mp_vector(env->gwion->mp, Type_Decl*, 1);
-  mp_vector_set(cdef->base.tmpl->call, Type_Decl*, 0, type2td(env->gwion, base, (loc_t) {}));
+  cdef->base.tmpl->call = new_mp_vector(env->gwion->mp, TmplArg, 1);
+  TmplArg arg = {.type = tmplarg_td, .d = {.td = type2td(env->gwion, base, (loc_t) {})} };
+  mp_vector_set(cdef->base.tmpl->call, TmplArg, 0, arg);
   const Context ctx  = env->context;
   env->context       = base->info->value->from->ctx;
   const m_uint scope = env_push(env, base->info->value->from->owner_class,
index 73e5b3d984ba562a6b0ab27552fad8a9570b81c3..2c1754a1fd41b75954b152b435b11e3181fef90b 100644 (file)
@@ -167,8 +167,10 @@ ANN static void _fptr_tmpl_push(const Env env, const Func f) {
   Specialized_List sl = tmpl->list;
   for(uint32_t i = 0; i < sl->len; i++) {
     Specialized *spec = mp_vector_at(sl, Specialized, i);
-    Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
-    const Type t = known_type(env, td);
+    // can it be called with consts?
+    if(spec->td) continue;
+    TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+    const Type t = known_type(env, arg.d.td);
     nspc_add_type(env->curr, spec->xid, t);
   }
 }
@@ -659,8 +661,10 @@ static FREEARG(freearg_dottmpl) {
 
 ANN static bool is_base(const Env env, const Type_List tl) {
   for(uint32_t i = 0; i < tl->len; i++) {
-    Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
-    if(known_type(env, td) == env->gwion->type[et_auto])
+    // can call with const happen?
+    TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+    if(unlikely(arg.type == tmplarg_exp)) continue;
+    if(known_type(env, arg.d.td) == env->gwion->type[et_auto])
       return true;
   }
   return false;
index 9d5ba6a570083995d3a16152e738966edd4368ad..d8e9f250083041fe1bbf3b220f120b9cdfe7cd07 100644 (file)
@@ -560,8 +560,8 @@ static OP_CHECK(opck_dict_scan) {
   const Type  exists = tmpl_exists(env, &info);
   if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
   if(!ts->td->types || ts->td->types->len != 2) return env->gwion->type[et_error];
-  DECL_ON(const Type, key, = known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 0)));
-  DECL_ON(const Type, val, = known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 1)));
+  DECL_ON(const Type, key, = known_type(env, mp_vector_at(ts->td->types, TmplArg, 0)->d.td));
+  DECL_ON(const Type, val, = known_type(env, mp_vector_at(ts->td->types, TmplArg, 1)->d.td));
   if(tflag(key, tflag_ref) || tflag(val, tflag_ref))
     ERR_N(ts->td->pos, "can't use Ref:[] in dicts");
   const Class_Def cdef  = cpy_class_def(env->gwion->mp, env->gwion->type[et_dict]->info->cdef);
index 521822b83d961e321470b38570838828970cde20..3a0b807621c5f1c4ccd5fb3faf2b164446af34f1 100644 (file)
@@ -149,7 +149,8 @@ static OP_CHECK(opck_ref_scan) {
       .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list};
   const Type exists = tmpl_exists(env, &info);
   if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
-  const Type base = known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 0));
+  const TmplArg arg = *mp_vector_at(ts->td->types, TmplArg, 0);
+  const Type base = known_type(env, arg.d.td);
   const Type t    = new_type(env->gwion->mp, s_name(info.name), base);
   t->size = SZ_INT;
   SET_FLAG(t, abstract | ae_flag_final);
index 4a0121c8ec4017c9edca11af7aa8f1fdb0c937a5..3033d5c37f5ab840b63641b76089271fd47b6b8b 100644 (file)
@@ -99,8 +99,9 @@ ANN Type tmpl_exists(const Env env, struct tmpl_info *const info) {
 
 ANN bool tmpl_global(const Env env, Type_List tl) {
   for(uint32_t i = 0; i < tl->len; i++) {
-    Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
-    const Type t = known_type(env, td);
+    TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+    if(unlikely(arg.type == tmplarg_exp)) continue;
+    const Type t = known_type(env, arg.d.td);
     if(!t || !type_global(env, t))
       return false;
   }
index 68605fc8733e2f296cc4b3e815f5f70b20ed057c..868df059528c713d39b70c22f7175a241d287e27 100644 (file)
@@ -188,28 +188,14 @@ ANN GWION_IMPORT(union) {
   GWI_BB(gwi_func_arg(gwi, "int", "id"))
   GWI_BB(gwi_func_arg(gwi, "T", "value"))
   GWI_BB(gwi_func_end(gwi, union_new, ae_flag_none))
-  
+
   GWI_BB(gwi_class_end(gwi))
 
-  const Func             f      = (Func)vector_at(&t_union->nspc->vtable, 0);
-  const struct Op_Func   opfunc = {.ck = opck_union_is};
-  const struct Op_Import opi    = {
-      .rhs  = f->value_ref->type,
-      .func = &opfunc,
-      .data = (uintptr_t)f,
-      .pos  = gwi->loc,
-      .op   = insert_symbol(gwi->gwion->st, "@func_check")};
-  CHECK_BB(add_op(gwi->gwion, &opi));
-
-  const Func             f1      = (Func)vector_at(&t_union->nspc->vtable, 1);
+  const struct Op_Func   opfunc0 = {.ck = opck_union_is};
+  GWI_BB(add_op_func_check(gwi->gwion->env, t_union, &opfunc0, 0));
+
   const struct Op_Func   opfunc1 = {.ck = opck_union_new};
-  const struct Op_Import opi1    = {
-      .rhs  = f1->value_ref->type,
-      .func = &opfunc1,
-      .data = (uintptr_t)f1,
-      .pos  = gwi->loc,
-      .op   = insert_symbol(gwi->gwion->st, "@func_check")};
-  CHECK_BB(add_op(gwi->gwion, &opi1));
+  GWI_BB(add_op_func_check(gwi->gwion->env, t_union, &opfunc1, 1));
 
   GWI_BB(gwi_oper_ini(gwi, "union", (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_emi(gwi, opem_union_dot))
index 8274b15da7cc6c44710fe3bcf8dc95e849f8664f..3a35d7e185460711c995d063bcc325cae59f0f33 100644 (file)
@@ -751,7 +751,7 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp,
   Specialized_List sl = tm->list;
   const bool spread = is_spread_tmpl(fdef->base->tmpl);
   const uint32_t len = sl->len - spread;
-  Type_List    tl = new_mp_vector(env->gwion->mp, Type_Decl*, len);
+  Type_List    tl = new_mp_vector(env->gwion->mp, TmplArg, len);
   m_uint       args_number = 0;
 
   if(exp->other) {
@@ -760,15 +760,21 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp,
       if (tmpl_arg_match(env, spec->xid, fdef->base->td->xid, fdef->base->ret_type)) {
         CHECK_OO(check_exp(env, exp->other));
          if(!is_func(env->gwion, exp->other->type)) {
-           Type_Decl *td = type2td(env->gwion, exp->other->type, fdef->base->td->pos);
-           mp_vector_set(tl, Type_Decl*, 0, td);
+           TmplArg targ = {
+             .type = tmplarg_td,
+             .d = { .td = type2td(env->gwion, exp->other->type, fdef->base->td->pos) }
+           };
+           mp_vector_set(tl, TmplArg, 0, targ);
          } else {
            Func func = exp->other->type->info->func;
            do {
              if(mp_vector_len(func->def->base->args) == 1) {
                Arg *arg = mp_vector_at(func->def->base->args, Arg, 0);
-               Type_Decl *td = cpy_type_decl(env->gwion->mp, arg->td);
-               mp_vector_set(tl, Type_Decl*, 0, td);
+               TmplArg targ = {
+                 .type = tmplarg_td,
+                 .d = { .td = cpy_type_decl(env->gwion->mp, arg->td) }
+               };
+               mp_vector_set(tl, TmplArg, 0, targ);
                break;
              }
            } while((func = func->next));
@@ -787,8 +793,11 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp,
     while (count < args_len && template_arg) {
       Arg *arg = mp_vector_at(args, Arg, count);
       if (tmpl_arg_match(env, spec->xid, arg->td->xid, template_arg->type)) {
-        mp_vector_set(tl, Type_Decl*, args_number,
-          mk_td(env, arg->td, template_arg->type, fdef->base->pos));
+        TmplArg targ = {
+          .type = tmplarg_td,
+          .d = { .td = mk_td(env, arg->td, template_arg->type, fdef->base->pos) }
+        };
+        mp_vector_set(tl, TmplArg, args_number, targ);
         ++args_number;
         break;
       }
@@ -804,7 +813,11 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp,
     if(fdef->base->args)
     for(uint32_t i = 0; i < fdef->base->args->len && e; i++) e = e->next;
     while(e) {
-      mp_vector_add(env->gwion->mp, &tl, Type_Decl*, type2td(env->gwion, e->type, e->pos));
+      TmplArg targ = {
+        .type = tmplarg_td,
+        .d = { .td = type2td(env->gwion, e->type, e->pos) }
+      };
+      mp_vector_add(env->gwion->mp, &tl, TmplArg, targ);
       e = e->next;
     }
   }
@@ -1130,10 +1143,12 @@ ANN2(1) static inline bool is_partial(const Env env, Exp exp) {
 ANN static bool tl_match(const Env env, const Type_List tl0, const Type_List tl1) {
   if (tl0->len != tl1->len) return false;
   for(uint32_t i = 0; i < tl0->len; i++) {
-    Type_Decl *td0 = *mp_vector_at(tl0, Type_Decl*, i);
-    Type_Decl *td1 = *mp_vector_at(tl1, Type_Decl*, i);
-    if(known_type(env, td0) != known_type(env, td1))
+    TmplArg targ0 = *mp_vector_at(tl0, TmplArg, i);
+    TmplArg targ1 = *mp_vector_at(tl1, TmplArg, i);
+    if (targ0.type != targ1.type) return false;
+    if(targ0.type == tmplarg_td && known_type(env, targ0.d.td) != known_type(env, targ1.d.td))
       return false;
+    // how do we check exps???
   }
   return true;
 }
@@ -2047,25 +2062,6 @@ ANN m_bool check_abstract(const Env env, const Class_Def cdef) {
   }
   return !err ? GW_OK : GW_ERROR;
 }
-/*
-ANN static inline void ctor_effects(const Env env) {
-  const Vector v  = &env->scope->effects;
-  MP_Vector *const w = (MP_Vector*)vector_back(v);
-  if (!w) return;
-  vector_init(&env->class_def->effects);
-  for (uint32_t j = 0; j < w->len; j++) {
-    struct ScopeEffect *eff = mp_vector_at(w, struct ScopeEffect, j);
-    vector_add(&env->class_def->effects, (m_uint)eff->sym);
-  }
-  free_mp_vector(env->gwion->mp, struct ScopeEffect, w);
-  vector_pop(v);
-}
-*/
-ANN static m_bool check_body(const Env env, Section *const section) {
-  const m_bool ret = check_section(env, section);
-//  ctor_effects(env);
-  return ret;
-}
 
 ANN static bool class_def_has_body(Ast ast) {
   const Section *section = mp_vector_at(ast, Section, 0);
@@ -2166,12 +2162,36 @@ ANN static m_bool recursive_type_base(const Env env, const Type t) {
 }
 
 ANN bool check_trait_requests(const Env env, const Type t, const ID_List list, const ValueFrom *from);
+
+ANN static m_bool check_class_tmpl(const Env env, const Tmpl *tmpl, const Nspc nspc) {
+  if(tmplarg_ntypes(tmpl->list) != tmpl->list->len) {
+    for(uint32_t i = 0; i < tmpl->list->len; i++) {
+      const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i);
+      if(likely(targ.type == tmplarg_td)) continue;
+      CHECK_OB(check_exp(env, targ.d.exp));
+//      if(isa(targ.d.exp->type, known_type(env, spec)
+      const Specialized spec = *mp_vector_at(tmpl->list, Specialized, i);
+      const Value v = new_value(env, targ.d.exp->type, s_name(spec.xid), targ.d.exp->pos);
+      valuefrom(env, v->from);
+      set_vflag(v, vflag_valid);
+      nspc_add_value(nspc, spec.xid, v);
+//      valid_value(env, spec.xid, v);
+      SET_FLAG(v, const| ae_flag_static);
+      set_vflag(v, vflag_builtin);
+
+      // set value type
+    }
+  }
+  return GW_OK;
+}
+
 ANN static m_bool _check_class_def(const Env env, const Class_Def cdef) {
   const Type t = cdef->base.type;
   if (cdef->base.ext) CHECK_BB(cdef_parent(env, cdef));
   if (!tflag(t, tflag_struct)) inherit(t);
+  if(cdef->base.tmpl) CHECK_BB(check_class_tmpl(env, cdef->base.tmpl, cdef->base.type->nspc));
   if (cdef->body) {
-    CHECK_BB(env_body(env, cdef, check_body));
+    CHECK_BB(env_body(env, cdef, check_section));
     if (cflag(cdef, cflag_struct) || class_def_has_body(cdef->body))
 //    if (class_def_has_body(cdef->body))
       set_tflag(t, tflag_ctor);
index 97daeab2e91a24dbb907f7f4e375dd2cfae1d990..f2ef19cb4d3163f73f85bcccb76212ef5959f9aa 100644 (file)
@@ -109,8 +109,8 @@ ANN static Func create_tmpl(const Env env, struct ResolverArgs *ra,
     for(uint32_t idx = 0; idx < ra->types->len; idx++) {
       char c[256];
       sprintf(c, "arg%u", idx);
-      Type_Decl *td = *mp_vector_at(ra->types, Type_Decl*, idx);
-      Arg arg = { .td = cpy_type_decl(env->gwion->mp, td), .var_decl = {.xid = insert_symbol(c), /*.value = v*/ }};
+      TmplArg targ = *mp_vector_at(ra->types, TmplArg, idx);
+      Arg arg = { .td = cpy_type_decl(env->gwion->mp, targ.d.td), .var_decl = {.xid = insert_symbol(c), /*.value = v*/ }};
       mp_vector_add(env->gwion->mp, &args, Arg, arg);
     }
     fdef->base->args = args;
@@ -181,12 +181,16 @@ ANN static Func _find_template_match(const Env env, const Value v,
   Type_List        tl = exp->tmpl->call;
   Specialized_List sl = f->def->base->tmpl->list;
   for(uint32_t i = 0; i < tl->len; i++) {
-    Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
-    DECL_OO(const Type, t, = known_type(env, td));
-    if(t->info->traits) {
-      Specialized * spec = mp_vector_at(sl, Specialized, i);
-      if (miss_traits(t, spec)) return NULL;
+    Specialized * spec = mp_vector_at(sl, Specialized, i);
+    TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+    if(unlikely(spec->td)) {
+// check argument in call exp
+      continue;
+
     }
+    DECL_OO(const Type, t, = known_type(env, arg.d.td));
+    if(t->info->traits && miss_traits(t, spec))
+      return NULL;
   }
   return f;
 }
index 478b16bd25b3769cc8f027e9f8f72a0178a35e4d..022ac4c92c2b64d3e23125de88101bdce89202bd 100644 (file)
@@ -228,22 +228,24 @@ ANN bool tmpl_match(const Env env, const struct Op_Import *opi,
   return true;
 }
 
+ANN static void op_tmpl_set(const Gwion gwion, Type_List tl,
+      const Type t, const loc_t pos, const uint32_t idx) {
+  TmplArg arg = {.type = tmplarg_td, .d = { .td = type2td(gwion, t, pos)}};
+  mp_vector_set(tl, TmplArg, idx, arg);
+}
+
 //! make template operator Func_def
 ANN static Type op_def(const Env env, struct Op_Import *const opi,
                 const Func_Def fdef) {
   const Func_Def tmpl_fdef    = cpy_func_def(env->gwion->mp, fdef);
   tmpl_fdef->base->tmpl->call = new_mp_vector(env->gwion->mp,
-    Type_Decl*, fdef->base->tmpl->list->len);
+    TmplArg, fdef->base->tmpl->list->len); // we need to check op def for type, maybe
   if (opi->lhs) {
-     uint32_t idx = 0;
-     const Type lhs = find_type(env, mp_vector_at(fdef->base->args, Arg, 0)->td);
-     if(!lhs)
-       mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, idx++, type2td(env->gwion, opi->lhs, opi->pos));
-     const Type rhs = find_type(env, mp_vector_at(fdef->base->args, Arg, 1)->td);
-     if(!rhs)
-       mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, idx, type2td(env->gwion, opi->rhs, opi->pos));
+     op_tmpl_set(env->gwion, tmpl_fdef->base->tmpl->call, opi->lhs, opi->pos, 0);
+     if(opi->rhs)
+       op_tmpl_set(env->gwion, tmpl_fdef->base->tmpl->call, opi->rhs, opi->pos, 1);
   } else
-     mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, 0, type2td(env->gwion, opi->rhs, opi->pos));
+       op_tmpl_set(env->gwion, tmpl_fdef->base->tmpl->call, opi->rhs, opi->pos, 0);
   if (traverse_func_def(env, tmpl_fdef) < 0) {
     if (!tmpl_fdef->base->func) func_def_cleaner(env->gwion, tmpl_fdef);
     return NULL;
@@ -485,3 +487,13 @@ ANN void op_cpy(const Env env, const struct Op_Import *opi) {
   op_visit(env->gwion->mp, env->curr, opi, &visited);
   vector_release(&visited);
 }
+
+ANN m_bool add_op_func_check(const Env env, const Type t, const struct Op_Func *opfunc, const m_uint idx) {
+  const Func f = (Func)vector_at(&t->nspc->vtable, idx);
+  const struct Op_Import opi = {
+      .rhs  = f->value_ref->type,
+      .func = opfunc,
+      .data = (uintptr_t)f,
+      .op   = insert_symbol(env->gwion->st, "@func_check")};
+  return add_op(env->gwion, &opi);
+}
index 95eef09757ae2ae0ad08310eeec2f6618bac9b98..2eab1fe29ab17cddc85a73ea85a56d5c8b1b53ee 100644 (file)
@@ -835,6 +835,33 @@ ANN static m_bool scan1_class_def_body(const Env env, const Class_Def cdef) {
   return env_body(env, cdef, scan1_section);
 }
 
+ANN static m_bool scan1_class_tmpl(const Env env, const Class_Def c) {
+  Specialized_List sl = c->base.tmpl->list;
+  Type_List tl = c->base.tmpl->call;
+  env_push_type(env, c->base.type);
+  m_bool ret = GW_OK;
+// check len
+  for(uint32_t i = 0; i < sl->len; i++) {
+    const TmplArg targ = *mp_vector_at(tl, TmplArg, i);
+//      const Specialized spec = *mp_vector_at(sl, Specialized, i);
+    if (targ.type == tmplarg_td) continue;
+    if(scan1_exp(env, targ.d.exp) < 0) {
+      ret = GW_ERROR;
+      break;
+    }
+/*
+      const Value v = new_value(env, env->gwion->type[et_int], s_name(spec.xid), targ.d.exp->pos);
+      valuefrom(env, v->from);
+      valid_value(env, spec.xid, v);
+      SET_FLAG(v, const| ae_flag_static);
+      set_vflag(v, vflag_builtin);
+      v->d.num = targ.d.exp->d.prim.d.gwint.num;
+*/
+  }
+  env_pop(env, 0);
+  return ret;
+}
+
 ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
   if (tmpl_base(cdef->base.tmpl)) return GW_OK;
   const Type      t = cdef->base.type;
@@ -843,6 +870,7 @@ ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
   const Class_Def c = t->info->cdef;
   if (c->base.ext) CHECK_BB(cdef_parent(env, c));
   if (c->body) CHECK_BB(scan1_class_def_body(env, c));
+  if (c->base.tmpl) CHECK_BB(scan1_class_tmpl(env, c));
   return GW_OK;
 }
 
index 7a90296e421c6f8bded0cfde30cd51a5b04e7965..6d473406d10e39c41a2f3903661f84a292d0fa47 100644 (file)
@@ -568,6 +568,18 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
   return ret;
 }
 
+ANN m_bool scan2_class_body(const Env env, const Class_Def c) {
+  const Tmpl *tmpl = c->base.tmpl;
+  if(tmpl && tmplarg_ntypes(tmpl->list) != tmpl->list->len) {
+    for(uint32_t i = 0; i < tmpl->list->len; i++) {
+      const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i);
+      if(unlikely(targ.type != tmplarg_td))
+        CHECK_BB(scan2_exp(env, targ.d.exp));
+    }
+  }
+  return scan2_ast(env, &c->body);
+}
+
 ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
   if (tmpl_base(cdef->base.tmpl)) return GW_OK;
   const Type      t = cdef->base.type;
@@ -580,7 +592,7 @@ ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
     const Tmpl *tmpl = cdef->base.tmpl;
     if(tmpl && tmpl->call && tmpl->call != (Type_List)1 && tmpl->list)
       template_push_types(env, tmpl);
-    const m_bool ret = scan2_ast(env, &c->body);
+    const m_bool ret = scan2_class_body(env, c);
     if(tmpl && tmpl->call && tmpl->call != (Type_List)1 && tmpl->list)
       nspc_pop_type(env->gwion->mp, env->curr);
     env_pop(env, scope);
index 6fd7c799c72ad1141a33b43de22222a14a45a7a1..923efdf305f49e0b8bd1107d34ff4722a5a96554 100644 (file)
@@ -17,10 +17,12 @@ ANN m_bool spread_ast(const Env env, const Spread_Def spread, const Tmpl *tmpl)
   DECL_OB(FILE *,f, = fmemopen(data, strlen(data), "r"));
   for(uint32_t i = tmpl->list->len - 1; i < tmpl->call->len; i++) {
     fseek(f, 0, SEEK_SET);
-    Type_Decl* td = *mp_vector_at(tmpl->call, Type_Decl*, i);
-    DECL_OB(const Type, t, = known_type(env, td));
+    const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i);
+    // skip or error on const?
+    // or do smth else?
+    DECL_OB(const Type, t, = known_type(env, targ.d.td));
     struct AstGetter_ arg =  {env->name, f, env->gwion->st, .ppa = env->gwion->ppa};
-    const m_str type = type2str(env->gwion, t, td->pos);
+    const m_str type = type2str(env->gwion, t, targ.d.td->pos);
     sprintf(c, "%s=%s", s_name(spread->xid), type);
     free_mstr(env->gwion->mp, type);
     pparg_add(env->gwion->ppa, c);
index cf4940af1cf1e9cf22774c33b6f82ae8834902a8..c44a7977ca1bfc564e42b98ed259613f26dc78f6 100644 (file)
@@ -23,12 +23,13 @@ ANN static m_bool _push_types(const Env env, const Nspc nspc,
   if(!tl) return GW_OK;
   for(uint32_t i = 0; i < len; i++) {
     if (i >= tl->len) return GW_OK;
-    Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
-    const Type t = known_type(env, td);
+    TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+    if(unlikely(arg.type == tmplarg_exp)) continue;
+    const Type t = known_type(env, arg.d.td);
     Specialized *spec = mp_vector_at(sl, Specialized, i);
     nspc_add_type(nspc, spec->xid, t);
   };
-if(len != sl->len) return GW_OK;
+  if(len != sl->len) return GW_OK;
   return tl->len == sl->len ? GW_OK : GW_ERROR;
 }
 
@@ -59,22 +60,33 @@ ANN m_bool template_push(const Env env, const Type t) {
    return _template_push(env, t);
 }
 
+#include <ctype.h>
 ANN void check_call(const Env env, const Tmpl *tmpl) {
   for(uint32_t i = 0; i < tmpl->call->len; i++) {
-    Specialized *spec = mp_vector_at(tmpl->list, Specialized, i);
-    Type_Decl *call = *mp_vector_at(tmpl->call, Type_Decl*, i);
-    if(spec->xid == call->xid) {
-      if (!nspc_lookup_type1(env->curr, spec->xid))
-        call->xid = insert_symbol("auto");
-      else {
-         const Type t = nspc_lookup_type1(env->curr, spec->xid);
-         Type_Decl *td = type2td(env->gwion, t, call->pos);
-         free_type_decl(env->gwion->mp, call);
-         mp_vector_set(tmpl->call, Type_Decl*, i, td);
+    Specialized *spec = i < tmpl->list->len
+       ? mp_vector_at(tmpl->list, Specialized, i)
+       : NULL;
+    TmplArg *targ = mp_vector_at(tmpl->call, TmplArg, i);
+    if(spec && strcmp(s_name(spec->xid), "...")) {
+      //spec->is_const) exit(12);
+      if(spec->xid == targ->d.td->xid) {
+        if (!nspc_lookup_type1(env->curr, spec->xid))
+          targ->d.td->xid = insert_symbol("auto");
+        else {
+           const Type t = nspc_lookup_type1(env->curr, spec->xid);
+           Type_Decl *td = type2td(env->gwion, t, targ->d.td->pos);
+           free_type_decl(env->gwion->mp, targ->d.td);
+           targ->d.td = td;
+        }
       }
+    } else {
+      //if(targ->type == tmplarg_td)
+      //  targ->d.td->xid = insert_symbol("auto");
+      //else what
     }
   }
 }
+
 ANN m_bool template_push_types(const Env env, const Tmpl *tmpl) {
   nspc_push_type(env->gwion->mp, env->curr);
   if (tmpl->call) check_call(env, tmpl);
@@ -144,15 +156,69 @@ ANN2(1,2) static m_bool check_tmpl(const Env env, const Type_List tl, const Spec
   if (!sl || sl->len > tl->len || (tl->len != sl->len && !is_spread))
      ERR_B(pos, "invalid template type number");
   for (uint32_t i = 0; i < sl->len; i++) {
-    Type_Decl *tmp = *mp_vector_at(tl, Type_Decl*, i);
-    DECL_OB(const Type, t, = known_type(env, tmp));
+    TmplArg *arg = mp_vector_at(tl, TmplArg, i);
     Specialized *spec = mp_vector_at(sl, Specialized, i);
-    if(spec->traits) {
-      Symbol missing = miss_traits(t, spec);
-      if (missing) {
-        ERR_B(pos, "does not implement requested trait '{/}%s{0}'",
+    if(arg->type == tmplarg_td) {
+
+    // could be an enum or smth
+      if(spec->td) {
+
+Type_Decl *base = arg->d.td;
+Type_Decl *next = base;
+Type_Decl *last = next->next;
+while(next && last) {
+  if(!last->next) break;
+  last = last->next;
+  next = next->next;
+}
+
+if(last) {
+  next->next = NULL;
+const Type t = known_type(env, base);
+// check no array?
+// no template?
+if(t) {
+  arg->type = tmplarg_exp;
+  Exp e = new_exp_td(env->gwion->mp, base, base->pos);
+  arg->d.exp = new_exp_dot(env->gwion->mp, e, last->xid, base->pos);
+free_type_decl(env->gwion->mp, last);
+//  arg->d
+
+//turn into an exp;
+i--;continue;
+}
+  next->next = last;
+
+}
+
+//exit(3);
+        ERR_B(pos, "template type argument mismatch. expected %s",
+              spec->td ? "constant" : "type");
+      }
+
+      DECL_OB(const Type, t, = known_type(env, arg->d.td));
+      if(spec->traits) {
+        Symbol missing = miss_traits(t, spec);
+        if (missing) {
+          ERR_B(pos, "does not implement requested trait '{/}%s{0}'",
               s_name(missing));
+        }
+      }
+    } else {
+        if(!spec->td) {
+          ERR_B(pos, "template const argument mismatch. expected %s",
+              spec->td ? "constant" : "type");
       }
+
+      DECL_OB(const Type, t, = known_type(env, spec->td));
+CHECK_OB(check_exp(env, arg->d.exp));
+//      DECL_OB(const Type, t, = nspc_lookup_valueh);
+if(isa(arg->d.exp->type,t) < 0)
+          ERR_B(pos, "invalid type %s for template argument. expected %s",
+              arg->d.exp->type->name, t->name);
+  
+// exit(13);
+//puts("we could check here");
     }
   }
   return GW_OK;
@@ -170,7 +236,7 @@ ANN static Type _scan_type(const Env env, const Type t, Type_Decl *td) {
       if(!d->types) {
         if(!single_variadic)
           ERR_O(td->pos, _("you must provide template types for type '%s'"), t->name);
-        d->types = new_mp_vector(env->gwion->mp, Type_Decl*, 0);
+        d->types = new_mp_vector(env->gwion->mp, TmplArg, 0);
       }
       const Type ret = _scan_type(env, t, d);
       free_type_decl(env->gwion->mp, new_td);
index 819166243c470663b5c9fc27a3d2daaede69033a..a95f1ed30a60ae2e14b8c6db345e2390c74ff107 100644 (file)
 ANN static Type _option(const Env env, Type_Decl *td, const uint8_t n) {
   const Array_Sub array = td->array;
   td->array = NULL;
-  Type_List tl  = new_mp_vector(env->gwion->mp, Type_Decl*, 1);
-  mp_vector_set(tl, Type_Decl*, 0, td);
+  Type_List tl  = new_mp_vector(env->gwion->mp, TmplArg, 1);
+  TmplArg arg = { .type = tmplarg_td, .d = { .td = td } };
+  mp_vector_set(tl, TmplArg, 0, arg);
   Type_Decl         tmp = {
       .xid = insert_symbol("Option"), .types = tl, .pos = td->pos};
   const Type t = !(n - 1) ? known_type(env, &tmp) : _option(env, &tmp, n - 1);
-  free_mp_vector(env->gwion->mp, Type_Decl*, tl);
+  free_mp_vector(env->gwion->mp, TmplArg, tl);
   td->array = array;
   return t;
 }
@@ -31,11 +32,12 @@ ANN static Type option(const Env env, Type_Decl *td) {
 }
 
 ANN static Type _ref(const Env env, Type_Decl *td) {
-  Type_List tl  = new_mp_vector(env->gwion->mp, Type_Decl*, 1);
-  mp_vector_set(tl, Type_Decl*, 0, td);
+  Type_List tl  = new_mp_vector(env->gwion->mp, TmplArg, 1);
+  TmplArg arg = { .type = tmplarg_td, .d = { .td = td } };
+  mp_vector_set(tl, TmplArg, 0, arg);
   Type_Decl tmp = {.xid = insert_symbol("Ref"), .types = tl, .pos = td->pos};
   const Type t = known_type(env, &tmp);
-  free_mp_vector(env->gwion->mp, Type_Decl*, tl);
+  free_mp_vector(env->gwion->mp, TmplArg, tl);
   return t;
 }