]> Nishi Git Mirror - gwion.git/commitdiff
:art: function const generics :tada:
authorfennecdjay <fennecdjay@gmail.com>
Mon, 29 Jan 2024 19:24:26 +0000 (20:24 +0100)
committerfennecdjay <fennecdjay@gmail.com>
Mon, 29 Jan 2024 19:24:26 +0000 (20:24 +0100)
54 files changed:
ast
const-generic.gw [new file with mode: 0644]
examples/Gain.gw
include/env/func.h
include/env/type.h
include/gwion.h
include/import/checker.h
include/operator.h
include/parse.h
include/spread.h
include/template.h
include/tmp_resolve.h
src/clean.c
src/emit/emit.c
src/env/context.c
src/env/env_utils.c
src/env/envset.c
src/env/func.c
src/gwion.c
src/import/import_cdef.c
src/import/import_checker.c
src/import/import_enum.c
src/import/import_fdef.c
src/import/import_item.c
src/import/import_prim.c
src/import/import_udef.c
src/lib/array.c
src/lib/closure.c
src/lib/dict.c
src/lib/engine.c
src/lib/instr.c
src/lib/object.c
src/lib/object_op.c
src/lib/opfunc.c
src/lib/ref.c
src/lib/tmpl_info.c
src/lib/xork.c
src/parse/check.c
src/parse/check_traits.c
src/parse/default_arg.c
src/parse/func_operator.c
src/parse/func_resolve_tmpl.c
src/parse/operator.c
src/parse/partial.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/spread.c
src/parse/template.c
src/parse/type_decl.c
tests/driver/simple_driver.c
tests/error/template_unknown.gw
tests/union/union_ref.gw
tests/usr_op/op_tmpl.gw

diff --git a/ast b/ast
index 7c1340d71a2c83dfad0c1d933732e7d223beab59..6477df1118c1c7b011583f14cae9e7d185f2cbeb 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 7c1340d71a2c83dfad0c1d933732e7d223beab59
+Subproject commit 6477df1118c1c7b011583f14cae9e7d185f2cbeb
diff --git a/const-generic.gw b/const-generic.gw
new file mode 100644 (file)
index 0000000..451f7af
--- /dev/null
@@ -0,0 +1,22 @@
+#!enum Enum {
+#!  bar,
+#!  foo
+#!}
+#!class C:[const int N] {
+#!class C:[const Enum N] {
+#!  N :=> var auto n;
+#!  <<< "N:${N} n:${n}" >>>;
+#!}
+
+fun void foo:[T, const float N]() {
+#!   <<< __func__ >>>;
+   <<< N >>>;
+#!  <<< "heyo">>>;
+}
+#!const int i;
+#!new C:[Enum.foo];
+#!new C:[2];
+#!r
+#!foo:[int, Enum.foo]();
+foo:[int, .2]();
+#!foo:[int, 2]();
index 099e9fb1abb7d2f6d16f83013d6d27f590fb795d..7210dda3c838faf72799be5e402a014ac8c49ebe 100644 (file)
@@ -1,10 +1,13 @@
 adc ~> var Gain g ~> dac;
 g.chan(0);
+
 spork  { while(true) { (g.gain() == .2 ? .2 : .1) => g.gain; .15::second => now; }};
+
 for(var int i; i < 5; i++) {
     <<< g.op() >>>;
        i => g.op;
     <<< g.op() >>>;
        2::second => now;
 }
+
 1 => adc.op;
index 4c45038ebb16fe440b86a5ade67f12b6a86c1c93..cd90ee93015bb61707e2f97637f51115ff59561b 100644 (file)
@@ -49,6 +49,6 @@ ANN static inline m_uint captures_sz(const Capture_List captures) {
 }
 
 ANN static inline bool is_ctor(const Func_Def fdef) {
-  return !strcmp(s_name(fdef->base->xid), "@ctor");
+  return !strcmp(s_name(fdef->base->tag.sym), "@ctor");
 }
 #endif
index 32278ef163fbab4e3d5b4abd635d246b7e35e64e..a5cd0f3ab89ca50c845e4116429169fd2a0ed2f4 100644 (file)
@@ -67,7 +67,7 @@ ANN2(1, 2) ANEW Type new_type(MemPool, const m_str name, const Type);
 ANEW ANN Type type_copy(MemPool, const Type type);
 ANN Value     find_value(const Type, const Symbol);
 ANN m_bool    isa(const Type, const Type) __attribute__((pure));
-ANN m_bool    isres(const Env, const Symbol, const loc_t pos);
+ANN m_bool    isres(const Env, const Tag);
 ANN Type      array_type(const Env, const Type, const m_uint);
 ANN Type      find_common_anc(const Type, const Type) __attribute__((pure));
 ANN Type      array_base(Type) __attribute__((pure));
index 7e6ec2271eacb8ff1588d10426b915c547702f47..5f1e8b37416d53adecc62b8107fe9b6410710ac3 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef __GWION
 #define __GWION
 
-// typedef struct Gwion_* Gwion;
 #include "arg.h"
 #include "plug.h"
 #include "driver.h"
@@ -49,5 +48,11 @@ ANN static inline void shred_pool_run(const VM_Shred shred, void (*fun)(void*),
   threadpool_add(shred->info->vm->gwion->data->tpool, fun, arg);
 }
 
+typedef struct {
+  VM_Shred shred;
+  m_bit *mem;
+  m_bit *RETURN;
+  MemPool mp;
+} TpShredInfo;
 
 #endif
index f81de9ff4c50a7eeb9ae45d45465fecb891f8cbc..7f229d22b53f5133f6a2edf60acdff22722a5f7f 100644 (file)
@@ -16,7 +16,7 @@ typedef struct ImportCK { // name_checker ?
     f_xfun addr;
   };
   union {
-    Union_List     list; // union
+    Variable_List     list; // union
     struct Vector_ v;
     MP_Vector *mpv;
     //    ID_List curr;// enum
index 724830379d8880bb3a722a6d14e03cd9d60c425c..54c1ed42523d4ce343f5cf8f4d6bcddb7a7ee7a5 100644 (file)
@@ -93,7 +93,7 @@ ANN static inline void operator_resume(struct Op_Import *opi) {
 
 ANN static inline void set_decl_ref(const Exp e) {
   if (e->exp_type == ae_exp_decl)
-    SET_FLAG(e->d.exp_decl.vd.value, late);
+    SET_FLAG(e->d.exp_decl.var.vd.value, late);
 }
 
 ANN void func_operator(const Func_Def fdef, struct Op_Import *opi);
index 9cfed3252b0944b31759bcd2eafae3c58648bef0..14fd446bf7faa2bfcb9e47dd590fecd5dce8e670 100644 (file)
@@ -135,5 +135,5 @@ ANN static inline bool is_static_call(const Gwion gwion, const Exp e) {
          member->base->exp_type == ae_exp_cast;
 }
 
-#define is_new(a) !strcmp(s_name((a)->base->xid), "new")
+#define is_new(a) !strcmp(s_name((a)->base->tag.sym), "new")
 #endif
index cf1d45c14ede3490d3629881370df50822edb0a2..b95d4428dba641b58b4212be36a8a8b24a101f71 100644 (file)
@@ -3,7 +3,7 @@
 
 ANN static inline bool is_spread_tmpl(const Tmpl *tmpl) {
   const Specialized *spec = mp_vector_at(tmpl->list, Specialized, tmpl->list->len - 1);
-  return !strcmp(s_name(spec->xid), "...");
+  return !strcmp(s_name(spec->tag.sym), "...");
 }
 
 ANN m_bool spread_ast(const Env env, const Spread_Def spread, const Tmpl *tmpl);
index a91f5be63039d60c561b42c07aa286674c95a874..47f2d20a8d3b064ef1196556fbfa4395bcba718b 100644 (file)
@@ -3,6 +3,24 @@
 ANN m_bool template_push_types(const Env, const Tmpl *);
 ANN m_bool template_push(const Env env, const Type t);
 ANN Tmpl *mk_tmpl(const Env, const Tmpl *, const Type_List);
+/*
+//! returns the Tmpl of a class or enum def
+ANN static inline Tmpl* get_tmpl(const Type t) {
+  return tflag(t, tflag_cdef)
+      ?  t->info->cdef->base.tmpl
+//      :  tflag(t, tflag_udef)
+        : t->info->udef->tmpl;
+//        : NULL;
+}
+*/
+ANN static inline Tmpl* get_tmpl(const Type t) {
+  return tflag(t, tflag_udef)
+      ? t->info->udef->tmpl
+      :  t->info->cdef->base.tmpl;
+//      :  tflag(t, tflag_udef)
+//        : NULL;
+}
+
 #define POP_RET(a)                                                             \
   {                                                                            \
     nspc_pop_type(env->gwion->mp, env->curr);                                  \
index fe9729bea7b3eeeb3b1242d4a5ce25192fd32cfc..113566f173b277a5325396dfe0db8d8e2c41b87d 100644 (file)
@@ -3,4 +3,5 @@
 ANN Func find_template_match(const Env env, const Value value,
                              Exp_Call *const exp);
 ANN Func find_func_match(const Env env, const Func up, Exp_Call *const exp);
+ANN2(1,2) m_bool check_tmpl(const Env env, const Type_List tl, const Specialized_List sl, const loc_t pos, const bool is_spread);
 #endif
index aa7d57df587c5fc6fbdbc6f3114d6a3f9e10ed23..0a2328149c5ad664388d96f52bec37f3446e7e0b 100644 (file)
@@ -53,11 +53,15 @@ ANN static void clean_var_decl(Clean *a, Var_Decl *b) {
   if (a->scope && b->value) value_remref(b->value, a->gwion);
 }
 
-ANN static void clean_exp_decl(Clean *a, Exp_Decl *b) {
+ANN static void clean_variable(Clean *a, Variable *b) {
   if (b->td) clean_type_decl(a, b->td);
   clean_var_decl(a, &b->vd);
 }
 
+ANN static void clean_exp_decl(Clean *a, Exp_Decl *b) {
+  clean_variable(a, &b->var);
+}
+
 ANN static void clean_exp_binary(Clean *a, Exp_Binary *b) {
   clean_exp(a, b->lhs);
   clean_exp(a, b->rhs);
@@ -254,8 +258,7 @@ ANN static void clean_stmt(Clean *a, Stmt b) {
 ANN static void clean_arg_list(Clean *a, Arg_List b) {
   for(uint32_t i = 0; i < b->len; i++) {
     Arg *arg = mp_vector_at(b, Arg, i);
-    if (arg->td) clean_type_decl(a, arg->td);
-    clean_var_decl(a, &arg->var_decl);
+    clean_variable(a, &arg->var);
   }
 }
 
@@ -307,16 +310,16 @@ ANN void class_def_cleaner(const Gwion gwion, Class_Def b) {
 }
 
 #define clean_enum_def   clean_dummy
-ANN static void clean_union_list(Clean *a, Union_List b) {
+ANN static void clean_variable_list(Clean *a, Variable_List b) {
   for(uint32_t i = 0; i < b->len; i++) {
-    Union_Member *tgt = mp_vector_at(b, Union_Member, i);
+    Variable *tgt = mp_vector_at(b, Variable, i);
     clean_type_decl(a, tgt->td);
     clean_var_decl(a, &tgt->vd);
   }
 }
 
 ANN static void clean_union_def(Clean *a, Union_Def b) {
-  clean_union_list(a, b->l);
+  clean_variable_list(a, b->l);
   if (b->tmpl) clean_tmpl(a, b->tmpl);
 }
 
index 52d3734705f7cfd729d4b00ba01d8a853318749f..eb09a332cc9dfbbc9ab8efd1c18bf0349493e371 100644 (file)
@@ -824,7 +824,7 @@ ANN /*static*/ m_bool emit_interp(const Emitter emit, const Exp exp) {
 ANN static m_bool emit_prim_hack(const Emitter emit, const Exp *exp) {
   CHECK_BB(emit_interp(emit, *exp));
   if (!(emit->env->func &&
-        emit->env->func->def->base->xid == insert_symbol("@gack")))
+        emit->env->func->def->base->tag.sym == insert_symbol("@gack")))
     emit_add_instr(emit, GackEnd);
   else emit_regtomem(emit, SZ_INT, -SZ_INT);
   return GW_OK;
@@ -893,7 +893,7 @@ ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v,
 ANN static m_bool _decl_static(const Emitter emit, const Exp_Decl *decl,
                               const Var_Decl *var_decl, const uint is_ref) {
   const Value v    = var_decl->value;
-  if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, v->type, decl->td, is_ref));
+  if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, v->type, decl->var.td, is_ref));
   else CHECK_BB(emit_exp(emit, decl->args));
   CHECK_BB(emit_dot_static_data(emit, v, 1));
   emit_add_instr(emit, Assign);
@@ -932,7 +932,7 @@ ANN static m_uint decl_non_static_offset(const Emitter emit, const Exp_Decl *dec
 ANN static m_bool struct_finish(const Emitter emit, const Exp_Decl *decl) {
   const Type t = decl->type;
   const bool emit_addr = exp_getvar(exp_self(decl));
-  if(GET_FLAG(decl->vd.value, late) || GET_FLAG(decl->td, late)) {
+  if(GET_FLAG(decl->var.vd.value, late) || GET_FLAG(decl->var.td, late)) {
     if(!emit_addr)
     decl_expand(emit, t);
     return GW_OK;
@@ -1028,7 +1028,7 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter   emit,
   const bool      is_obj   = isa(type, emit->gwion->type[et_object]) > 0;
   const bool emit_addr = (!is_obj || is_ref) ? emit_var : true;
   if (is_obj && !is_ref && !exp_self(decl)->ref) {
-    if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref));
+    if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->var.td, is_ref));
     else CHECK_BB(emit_exp(emit, decl->args));
   }
   f_instr *exec = (f_instr *)allocmember;
@@ -1067,7 +1067,7 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl,
   const bool      is_obj   = isa(type, emit->gwion->type[et_object]) > 0;
   const bool emit_addr = (!is_obj || is_ref) ? emit_var : true;
   if (is_obj && !is_ref) {
-    if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref));
+    if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->var.td, is_ref));
     else CHECK_BB(emit_exp(emit, decl->args));
   }
   if (type->size > SZ_INT)
@@ -1089,7 +1089,7 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl,
 ANN static void set_late(const Exp_Decl *decl, const Var_Decl *var) {
   const Value v         = var->value;
   if (!exp_getvar(exp_self(decl)) &&
-      (GET_FLAG(array_base_simple(v->type), abstract) || GET_FLAG(decl->td, late)))
+      (GET_FLAG(array_base_simple(v->type), abstract) || GET_FLAG(decl->var.td, late)))
     SET_FLAG(v, late);
   else UNSET_FLAG(v, late);
 }
@@ -1099,13 +1099,13 @@ static inline bool late_array(const Type_Decl* td) {
 }
 
 ANN static m_bool emit_decl(const Emitter emit, Exp_Decl *const decl) {
-  const m_bool  global = GET_FLAG(decl->td, global);
+  const m_bool  global = GET_FLAG(decl->var.td, global);
   const uint    var    = exp_getvar(exp_self(decl));
-  const uint    ref    = GET_FLAG(decl->td, late) || type_ref(decl->type);
-  Var_Decl *vd = &decl->vd;
+  const uint    ref    = GET_FLAG(decl->var.td, late) || type_ref(decl->type);
+  Var_Decl *vd = &decl->var.vd;
   const Value v = vd->value;
   const uint  r = ref || GET_FLAG(v, late);
-  if (GET_FLAG(decl->td, static))
+  if (GET_FLAG(decl->var.td, static))
     CHECK_BB(emit_exp_decl_static(emit, decl, vd, r, var));
   else if (!global)
     CHECK_BB(emit_exp_decl_non_static(emit, decl, vd, r, var));
@@ -1120,11 +1120,11 @@ ANN static m_bool emit_decl(const Emitter emit, Exp_Decl *const decl) {
     CHECK_BB(op_emit(emit, &opi));
   }
   set_late(decl, vd);
-  if (!decl->args && !exp_getvar(exp_self(decl)) && GET_FLAG(array_base_simple(v->type), abstract) && !GET_FLAG(decl->td, late) &&
-      GET_FLAG(v, late) && late_array(decl->td)
+  if (!decl->args && !exp_getvar(exp_self(decl)) && GET_FLAG(array_base_simple(v->type), abstract) && !GET_FLAG(decl->var.td, late) &&
+      GET_FLAG(v, late) && late_array(decl->var.td)
       && GET_FLAG(v->type, abstract)) {
-    env_err(emit->env, decl->td->pos, _("Type '%s' is abstract, use {+G}late{0} instead of {G+}%s{0}"),
-             v->type->name, !GET_FLAG(decl->td, const) ? "var" : "const");
+    env_err(emit->env, decl->var.td->tag.loc, _("Type '%s' is abstract, use {+G}late{0} instead of {G+}%s{0}"),
+             v->type->name, !GET_FLAG(decl->var.td, const) ? "var" : "const");
     if(v->type->nspc->vtable.ptr) {
       const Vector vec = &v->type->nspc->vtable;
       for(m_uint i = 0; i < vector_size(vec); i++) {
@@ -1147,12 +1147,12 @@ ANN /*static */ m_bool emit_exp_decl(const Emitter emit, Exp_Decl *const decl) {
   if(decl->args && !strncmp(decl->args->type->name, "partial:", 8))
     ERR_B(decl->args->pos, "unresolved partial");
   CHECK_BB(ensure_emit(emit, t));
-  const m_bool global = GET_FLAG(decl->td, global);
+  const m_bool global = GET_FLAG(decl->var.td, global);
   const m_uint scope =
       !global ? emit->env->scope->depth : emit_push_global(emit);
   const m_bool ret = emit_decl(emit, decl);
   if (global) emit_pop(emit, scope);
-  if(emit->status.in_return && GET_FLAG(decl->vd.value, late) && isa(t, emit->gwion->type[et_object]) > 0)
+  if(emit->status.in_return && GET_FLAG(decl->var.vd.value, late) && isa(t, emit->gwion->type[et_object]) > 0)
     emit_add_instr(emit, GWOP_EXCEPT);
   return ret;
 }
@@ -1502,7 +1502,7 @@ ANN static m_bool emit_template_code(const Emitter emit, const Func f) {
 ANN static void tmpl_prelude(const Emitter emit, const Func f) {
   const Instr gtmpl = emit_add_instr(emit, GTmpl);
   gtmpl->m_val      = (m_uint)f->def;
-  gtmpl->m_val2     = (m_uint)tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->pos);
+  gtmpl->m_val2     = (m_uint)tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->tag.loc);
 }
 
 ANN static Instr get_prelude(const Emitter emit, const Func f,
@@ -1541,7 +1541,7 @@ static m_bool me_cmp(MemoizeEmitter *me, const Arg *arg) {
   struct Exp_      lhs  = {
     .exp_type = ae_exp_primary,
     .type = arg->type,
-    .pos = arg->td->pos,
+    .pos = arg->var.td->tag.loc,
     .d = {
       .prim = { .prim_type = ae_prim_id }
     }
@@ -1549,7 +1549,7 @@ static m_bool me_cmp(MemoizeEmitter *me, const Arg *arg) {
   struct Exp_      rhs  = {
     .exp_type = ae_exp_primary,
     .type     = me->emit->gwion->type[et_bool],
-    .pos = arg->td->pos,
+    .pos = arg->var.td->tag.loc,
     .d = {
       .prim = { .prim_type = ae_prim_id }
     }
@@ -1557,7 +1557,7 @@ static m_bool me_cmp(MemoizeEmitter *me, const Arg *arg) {
   struct Exp_      bin  = {
     .exp_type = ae_exp_binary,
     .type = arg->type,
-    .pos = arg->td->pos,
+    .pos = arg->var.td->tag.loc,
     .d = {
       .exp_binary = {
         .lhs = &lhs,
@@ -1569,7 +1569,7 @@ static m_bool me_cmp(MemoizeEmitter *me, const Arg *arg) {
   struct Op_Import opi  = {.op   = sym,
                           .lhs  = arg->type,
                           .rhs  = arg->type,
-                          .pos  = me->fdef->base->pos,
+                          .pos  = me->fdef->base->tag.loc,
                           .data = (uintptr_t)&bin.d};
   CHECK_BB(op_emit(emit, &opi));
   const Instr instr = emit_add_instr(emit, BranchEqInt);
@@ -1782,7 +1782,7 @@ ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary *unary) {
       const Value v = cap->orig;
       struct Exp_ exp = {
         .d = { .prim = {
-          .d = { .var = cap->xid },
+          .d = { .var = cap->tag.sym },
           .value = v,
           .prim_type = ae_prim_id
         }},
@@ -1972,10 +1972,10 @@ ANN2(1) /*static */ m_bool emit_exp(const Emitter emit, /* const */ Exp e) {
     if (exp->cast_to) CHECK_BB(emit_implicit_cast(emit, exp, exp->cast_to));
     if (isa(e->type, emit->gwion->type[et_object]) > 0 &&
         (e->cast_to ? isa(e->cast_to, emit->gwion->type[et_object]) > 0 : 1) &&
-        e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) &&
+        e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.var.td, late) &&
         exp_getuse(e) && !exp_getvar(e) &&
-        GET_FLAG(e->d.exp_decl.vd.value, late))
-    emit_fast_except(emit, e->d.exp_decl.vd.value->from, e->pos);
+        GET_FLAG(e->d.exp_decl.var.vd.value, late))
+    emit_fast_except(emit, e->d.exp_decl.var.vd.value->from, e->pos);
   } while ((exp = exp->next));
   return GW_OK;
 }
@@ -2255,11 +2255,11 @@ ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt,
   emit_memsetimm(emit, key_offset, -1);
   stmt->v->from->offset = val_offset;
 //value_addref(stmt->v);
-_nspc_add_value(emit->env->curr, stmt->sym, stmt->v);
+_nspc_add_value(emit->env->curr, stmt->tag.sym, stmt->v);
   emit_debug(emit, stmt->v);
   if (stmt->idx) {
     stmt->idx->v->from->offset = key_offset;
-_nspc_add_value(emit->env->curr, stmt->idx->sym, stmt->idx->v);
+_nspc_add_value(emit->env->curr, stmt->idx->tag.sym, stmt->idx->v);
 //value_addref(stmt->idx->v);
     emit_debug(emit, stmt->idx->v);
   }
@@ -2405,7 +2405,7 @@ ANN static inline m_bool emit_handler_list(const restrict Emitter emit,
     Handler *handler = mp_vector_at(handlers, Handler, i);
     const Instr instr = emit_add_instr(emit, HandleEffect);
     instr->m_val      = emit->status.effect = offset;
-    instr->m_val2     = (m_uint)handler->xid;
+    instr->m_val2     = (m_uint)handler->tag.sym;
     CHECK_BB(scoped_stmt(emit, handler->stmt));
     emit_try_goto(emit, v);
     instr->m_val = emit_code_size(emit);
@@ -2663,11 +2663,11 @@ ANN static inline void emit_func_def_init(const Emitter emit, const Func func) {
 ANN static void emit_func_def_args(const Emitter emit, Arg_List args) {
   for(uint32_t i = 0; i < args->len; i++) {
     Arg *arg = mp_vector_at(args, Arg, i);
-    const Type type = arg->var_decl.value->type;
+    const Type type = arg->var.vd.value->type;
     emit->code->stack_depth += type->size;
-    arg->var_decl.value->from->offset = emit_localn(emit, type);
-    emit_debug(emit, arg->var_decl.value);
-    _nspc_add_value(emit->env->curr, insert_symbol(arg->var_decl.value->name), arg->var_decl.value);
+    arg->var.vd.value->from->offset = emit_localn(emit, type);
+    emit_debug(emit, arg->var.vd.value);
+    _nspc_add_value(emit->env->curr, insert_symbol(arg->var.vd.value->name), arg->var.vd.value);
   }
 }
 
@@ -2685,9 +2685,9 @@ ANN static m_bool emit_func_def_return(const Emitter emit) {
 }
 
 ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
-  if (f->def->base->xid == insert_symbol("@dtor"))
+  if (f->def->base->tag.sym == insert_symbol("@dtor"))
     return emit->env->class_def->nspc->dtor = finalyze(emit, DTOR_EOC);
-  else if (f->def->base->xid == insert_symbol("@gack")) {
+  else if (f->def->base->tag.sym == insert_symbol("@gack")) {
     emit_regmove(emit, -SZ_INT - f->value_ref->from->owner_class->size);
     const Instr instr                       = emit_add_instr(emit, RegPushMem);
     instr->m_val                            = SZ_INT;
@@ -2721,7 +2721,7 @@ ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
 }
 
 ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
-  if (fdef->base->xid == insert_symbol("@dtor")) emit_local(emit, emit->gwion->type[et_int]);
+  if (fdef->base->tag.sym == insert_symbol("@dtor")) emit_local(emit, emit->gwion->type[et_int]);
   if (fdef->base->args) emit_func_def_args(emit, fdef->base->args);
   if (fdef->d.code) {
     if(!fdef->builtin) {
@@ -2819,6 +2819,11 @@ ANN static void emit_lambda_capture(const Emitter emit, const Func_Def fdef) {
   emit_regtomem4(emit, fdef->stack_depth, offset);
 }
 
+static INSTR(ConstGenericEOC) {
+  shred->reg -= instr->m_val;
+  memcpy((void*)instr->m_val2, shred->reg, instr->m_val);
+//a  exit(12);
+}
 ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) {
   if (tmpl_base(f->base->tmpl) && fbflag(f->base, fbflag_op)) return GW_OK;
   const Func     func   = f->base->func;
@@ -2835,18 +2840,63 @@ ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) {
   if ((vflag(func->value_ref, vflag_builtin) &&
       safe_tflag(emit->env->class_def, tflag_tmpl)) || (fdef->base->tmpl && is_new(f))) {
     const Func base =
-        nspc_lookup_func1(func->value_ref->from->owner, f->base->xid);
+        nspc_lookup_func1(func->value_ref->from->owner, f->base->tag.sym);
     builtin_func(emit->gwion, func, (f_xfun)base->code->native_func);
     return GW_OK;
   }
   const uint   global = GET_FLAG(f->base, global);
   const m_uint scope =
       !global ? emit->env->scope->depth : env_push_global(emit->env);
+  if(fdef->base->tmpl) { // check is call?
+    if(tmplarg_ntypes(fdef->base->tmpl->call) != fdef->base->tmpl->call->len) {
+emit_push_code(emit, "const-generic"); // better name?
+uint32_t size = 0;
+// create new code here
+      for(uint32_t i = 0; i < fdef->base->tmpl->call->len; i++) {
+        TmplArg *targ = mp_vector_at(fdef->base->tmpl->call, TmplArg, i);
+        if(targ->type == tmplarg_td)continue;
+        // spec could be null cause of spread ops
+        Specialized *spec = mp_vector_at(fdef->base->tmpl->list, Specialized, i);
+        if(!spec) break;
+CHECK_BB(emit_exp(emit, targ->d.exp));
+//oemit_regmove(emit, -targ->d.exp->type->size);
+//emit_regmove(emit, -SZ_INT);
+//pop_exp(emit, targ->d.exp);
+size += targ->d.exp->type->size;
+      }
+// set variables values
+// and remove code
+//emit_regmove(emit, -size);
+fdef->base->func->value_ref->type->nspc->class_data_size = size;
+fdef->base->func->value_ref->type->nspc->class_data = _mp_malloc(emit->gwion->mp, size);
+const Instr instr = emit_add_instr(emit, ConstGenericEOC);
+instr->m_val = size;
+instr->m_val2 = (m_uint)fdef->base->func->value_ref->type->nspc->class_data;
+const VM_Code code = finalyze(emit, EOC);
+//const VM_Code code = finalyze(emit, ConstGenericEOC);
+const VM_Shred shred = new_vm_shred(emit->gwion->mp, code);
+vm_add_shred(emit->gwion->vm, shred);
+//shred->info->me->ref++;
+//vm_run(emit->gwion->vm);
+//emit->gwion->vm->
+const bool loop = emit->gwion->vm->shreduler->loop;
+vm_run(emit->gwion->vm);
+// alloc space
+//fdef->base->func->value_ref->type->nspc->class_data_size = size;
+//fdef->base->func->value_ref->type->nspc->class_data = _mp_malloc(emit->gwion->mp, size);
+//memcpy(fdef->base->func->value_ref->type->nspc->class_data, shred->reg, size);
+// => copy data
+emit->gwion->vm->bbq->is_running = true;
+emit->gwion->vm->shreduler->loop = loop;
+//release(shred->info->me, emit->gwion->vm->cleaner_shred);
+//}
+    }
+  }
   emit_func_def_init(emit, func);
   if (vflag(func->value_ref, vflag_member)) stack_alloc(emit);
   emit->env->func = func;
   emit_push_scope(emit);
-  if (!strcmp(s_name(fdef->base->xid), "@gack")) {
+  if (!strcmp(s_name(fdef->base->tag.sym), "@gack")) {
     emit_local(emit, emit->gwion->type[et_int]);
     emit_memsetimm(emit, SZ_INT, 0);
   } else if(fdef->captures) emit_lambda_capture(emit, fdef);
@@ -2921,13 +2971,13 @@ static INSTR(set) {
 
 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");
+    emit_push_code(emit, "tmpl"); // make better name
     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);
+      const Value v = nspc_lookup_value1(nspc, spec.tag.sym);
       emit_pushimm(emit, (m_uint)v);
       const Instr instr = emit_add_instr(emit, set);
       instr->m_val2 = targ.d.exp->type->size;
index e5f5639e1488979513de42bb61447b7fa5c6ce65..421683e6c847b2bae3ae65b129632e7180c3fe9b 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(53);
+  assert(global == env->global_nspc);
   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 f163ddd5ccabd0e9aa4abaf7e00d62af8cb7ea17..c9926064fdcc9c26f9479fc2c1ceb384343dc1a5 100644 (file)
@@ -54,13 +54,13 @@ ANN Type find_initial(const Env env, const Symbol xid) {
 }
 #undef RETURN_TYPE
 
-ANN Type find_type(const Env env, Type_Decl *path) {
-  DECL_OO(Type, type, = find_initial(env, path->xid));
-  while ((path = path->next) && type && type->nspc) {
+ANN Type find_type(const Env env, Type_Decl *td) {
+  DECL_OO(Type, type, = find_initial(env, td->tag.sym));
+  while ((td = td->next) && type && type->nspc) {
     const Nspc nspc  = type->nspc;
-    if(!(type = find_in_parent(type, path->xid)))
-      ERR_O(path->pos, _("...(cannot find class '%s' in nspc '%s')"),
-            s_name(path->xid), nspc->name)
+    if(!(type = find_in_parent(type, td->tag.sym)))
+      ERR_O(td->tag.loc, _("...(cannot find class '%s' in nspc '%s')"),
+            s_name(td->tag.sym), nspc->name)
   }
   return type;
 }
@@ -107,11 +107,11 @@ ANN Value global_string(const Env env, const m_str str, const loc_t loc) {
   return value;
 }
 
-ANN m_bool isres(const Env env, const Symbol xid, const loc_t pos) {
+ANN m_bool isres(const Env env, const Tag tag) {
   const Map map = &env->gwion->data->id;
   for (m_uint i = 0; i < map_size(map); i++) {
-    if (xid == (Symbol)VKEY(map, i))
-      ERR_B(pos, _("%s is reserved."), s_name(xid));
+    if (tag.sym == (Symbol)VKEY(map, i))
+      ERR_B(tag.loc, _("%s is reserved."), s_name(tag.sym));
   }
   return GW_OK;
 }
index 699c4d082f2f2dc90a5be05cc25d3c4ae6b6dad7..5f11cbb68fae70d0244d260e287849f223f76e77 100644 (file)
@@ -29,9 +29,10 @@ ANN static m_bool push(struct EnvSet *es, const Type t) {
              t->info->value->from->ctx ? t->info->value->from->ctx->nspc
                                        : es->env->curr);
   env_push_type((void *)es->env, t); // do not push if is a function?
-  if (tflag(t, tflag_tmpl))
-    CHECK_BB(template_push_types(
-        es->env, t->info->cdef->base.tmpl)); // incorrect templates?
+  if (tflag(t, tflag_tmpl)) {
+    const Tmpl *tmpl = get_tmpl(t);
+    CHECK_BB(template_push_types(es->env, tmpl));
+  }
   return GW_OK;
 }
 
index d06873dd3e3a1c9185f808e4c2836baaf85bf2cd..b7840aa8a9ab1fec2186c50fb669af5113a690a7 100644 (file)
@@ -44,7 +44,7 @@ ANN void builtin_func(const Gwion gwion, const Func f, void *func_ptr) {
     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), "...")) {
+    if(!strcmp(s_name(spec->tag.sym), "...")) {
       const uint32_t len = tmplarg_ntypes(tl);
       f->code->types = new_mp_vector(gwion->mp, Type, len);
       uint32_t n = 0;
index b685f967d5eec1371fc323c891fc3711d7badd26..487e76993f3d635d03b886cc841af6382355fde2 100644 (file)
@@ -181,14 +181,15 @@ ANN void env_error_footer(const Env env) {
   bool ctor = false;
   if (env->func && env->func->def) {
      if(!is_ctor(env->func->def))
-      gwerr_secondary("in function", env->name, env->func->def->base->pos);
+      gwerr_secondary("in function", env->name, env->func->def->base->tag.loc);
     else {
-      gwerr_secondary("in class pre constructor", env->name, env->class_def->info->cdef->pos);
+      gwerr_secondary("in class pre constructor", env->name,
+        env->class_def->info->cdef->base.tag.loc);
       ctor = true;
     }
   }
   if (!ctor && env->class_def && tflag(env->class_def, tflag_cdef))
-    gwerr_secondary("in class", env->name, env->class_def->info->cdef->pos);
+    gwerr_secondary("in class", env->name, env->class_def->info->cdef->base.tag.loc);
 }
 
 ANN static void env_xxx(const Env env, const loc_t pos, const m_str fmt,
index 9473972edbb64fbc7de0595c12980eff70547b43..be1871a758d435ebfe4b94ca84b753ca2bb78799 100644 (file)
@@ -33,10 +33,10 @@ ANN2(1, 2) static void import_class_ini(const Env env, const Type t) {
 
 ANN2(1) void add_template(const Env env, const Type t) {
   nspc_push_type(env->gwion->mp, env->curr); //
-  Specialized_List sl = t->info->cdef->base.tmpl->list;
+  Specialized_List sl = get_tmpl(t)->list;
   for(uint32_t i = 0; i < sl->len; i++) {
     Specialized *spec = mp_vector_at(sl, Specialized, i);
-    nspc_add_type(env->curr, spec->xid, env->gwion->type[et_auto]);
+    nspc_add_type(env->curr, spec->tag.sym, env->gwion->type[et_auto]);
   }
 }
 
@@ -60,7 +60,7 @@ ANN static Type type_finish(const Gwi gwi, const Type t) {
   tflag(t, tflag_compound);
   gwi_add_type(gwi, t);
   import_class_ini(gwi->gwion->env, t);
-  if (t->info->cdef && t->info->cdef->base.tmpl) {
+  if (t->info->cdef && get_tmpl(t)) {
     gwi->tmpls++;
     add_template(gwi->gwion->env, t);
     set_tflag(t, tflag_cdef);
index 682031260e1f7590c07df93b82b7cce05f03547d..abb3ff8565ebe8a6e5320c0afabe28fa20a75f54 100644 (file)
@@ -75,9 +75,8 @@ ANN m_bool str2var(const Gwion gwion, Var_Decl *vd, const m_str path, const loc_
   DECL_OB(const Symbol, sym, = __str2sym(gwion, &tdc));
   struct AC ac = {.str = tdc.str, .pos = pos};
   CHECK_BB(ac_run(gwion, &ac));
-  vd->xid = sym;
+  vd->tag = MK_TAG(sym, pos);
   vd->value = NULL;
-  vd->pos = pos;
   return GW_OK;
 }
 
@@ -86,19 +85,13 @@ ANN static bool _tmpl_list(const Gwion        gwion,
                                        struct td_checker *tdc, Specialized_List *sl) {
   if(unlikely(!strncmp(tdc->str, "...", 3))) {
     tdc->str += 3;
-    Specialized spec = {
-      .xid = insert_symbol(gwion->st, "..."),
-      .pos = tdc->pos
-    };
+    Specialized spec = { .tag = MK_TAG(insert_symbol(gwion->st, "..."), tdc->pos) };
     mp_vector_add(gwion->mp, sl, Specialized, spec);
     return true;
   }
   DECL_OO(const Symbol, sym, = __str2sym(gwion, tdc));
   // TODO: handle traits?
-  Specialized spec = {
-    .xid = sym,
-    .pos = tdc->pos
-  };
+  Specialized spec = { .tag = MK_TAG(sym, tdc->pos) };
   mp_vector_add(gwion->mp, sl, Specialized, spec);
   if (*tdc->str == ',') {
     ++tdc->str;
@@ -133,6 +126,7 @@ 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) {
+  // we probably need smth better
   if(isalpha(*tdc->str)) {
     TmplArg targ = {
       .type = tmplarg_td,
@@ -145,7 +139,7 @@ ANN bool str2tl(const Gwion gwion, struct td_checker *tdc, Type_List *tl) {
       if (!str2tl(gwion, tdc, tl))
         return false;
     }
-  } else exit(6);
+  } else GWION_ERR_B(tdc->pos, "invalid character in template list");
   return true;
 }
 
@@ -190,7 +184,7 @@ ANN static Arg_List fptr_args(const Gwion gwion, struct td_checker *tdc) {
       free_arg_list(gwion->mp, args);
       return (Arg_List)GW_ERROR;
     }
-    mp_vector_add(gwion->mp, &args, Arg, (Arg){ .td = td });
+    mp_vector_add(gwion->mp, &args, Arg, (Arg){ .var = {.td = td }});
   } while(*tdc->str == ',' && tdc->str++);
   return args;
 }
@@ -298,22 +292,54 @@ ANN static void td_fullname(const Env env, GwText *text, const Type t) {
   text_add(text, t->name);
 }
 
+ANN Exp td2exp(const MemPool mp, const Type_Decl *td) {
+  Exp base = new_prim_id(mp, td->tag.sym, td->tag.loc);
+  Type_Decl *next = td->next;
+  while(next) {
+    base = new_exp_dot(mp, base, next->tag.sym, td->tag.loc);
+    next = next->next;
+  }
+  return base;
+}
+
 ANN static m_bool td_info_run(const Env env, struct td_info *info) {
+  const Gwion gwion = env->gwion;
   Type_List tl = info->tl;
   for(uint32_t i = 0; i < tl->len; i++) {
     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);
+    TmplArg *targ = mp_vector_at(tl, TmplArg, i);
+    if(targ->type == tmplarg_td) {
+      // we may need to stop errors
+      if(env->context) env->context->error = true;
+      const Type t = known_type(env, targ->d.td);
+      if(env->context) env->context->error = false;
+      if(t)
+        td_fullname(env, &info->fmt->ls->text, t);
+      else {
+        const Exp exp = td2exp(gwion->mp, targ->d.td);
+        if(traverse_exp(env, exp) > 0) {
+          if(is_class(gwion, exp->type)) {
+            td_fullname(env, &info->fmt->ls->text, exp->type);
+            free_exp(gwion->mp, exp);
+          } else gwfmt_exp(info->fmt, exp);
+        } else GWION_ERR_B(targ->d.td->tag.loc, "invalid template argument");
+      }
+    } else {
+      Exp exp = targ->d.exp;
+      if(check_exp(env, targ->d.exp)) {
+        if(!is_class(gwion, exp->type))
+          gwfmt_exp(info->fmt, exp);
+        else
+          td_fullname(env, &info->fmt->ls->text, targ->d.exp->type);
+      }
+    }
   }
   return GW_OK;
 }
 
 ANEW ANN m_str type2str(const Gwion gwion, const Type t,
                         const loc_t pos NUSED) {
-  GwText     text;
+  GwText text;
   text_init(&text, gwion->mp);
   td_fullname(gwion->env, &text, t);
   return text.str;
index 7d6adf9af4d58922326d8d6a371840434c486474..d05b46870a506108c5621cb057754d79dce57dc0 100644 (file)
@@ -32,7 +32,7 @@ ANN m_int gwi_enum_ini(const Gwi gwi, const m_str type) {
 ANN m_int gwi_enum_add(const Gwi gwi, const m_str name, const m_uint i) {
   CHECK_BB(ck_ok(gwi, ck_edef));
   DECL_OB(const Symbol, xid, = gwi_str2sym(gwi, name));
-  const EnumValue ev = { .xid = xid, .gwint = { .num = i }, .set = true};
+  const EnumValue ev = { .tag = MK_TAG(xid, gwi->loc), .gwint = { .num = i }, .set = true};
   mp_vector_add(gwi->gwion->mp, &gwi->ck->tmpl, EnumValue, ev);
   return GW_OK;
 }
index d12d20956306c33cbf8df09fd7e1cc5d664b6d09..89779089a7be6f843130ec7aee1280cafc5b1016 100644 (file)
@@ -101,7 +101,7 @@ ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t,
   DECL_OB(Type_Decl *, td, = gwi_str2td(gwi, t));
   struct Var_Decl_ var;
   if(gwi_str2var(gwi, &var, n) > 0) {
-    Arg arg = { .td = td, .var_decl = var };
+    Arg arg = { .var = MK_VAR(td, var) };
     mp_vector_add(gwi->gwion->mp, &gwi->ck->mpv, Arg, arg);
     return GW_OK;
   }
index dc18be6dc7c5155ad949a7d04df00e5a7792e2b2..882e351ab276fd2fb82aadd9eae17c50afa987d2 100644 (file)
@@ -42,7 +42,7 @@ ANN2(1)
 m_int gwi_item_end(const Gwi gwi, const ae_flag flag, union value_data addr) {
   CHECK_BB(ck_ok(gwi, ck_item));
   const Env env                     = gwi->gwion->env;
-  gwi->ck->exp->d.exp_decl.td->flag = flag;
+  gwi->ck->exp->d.exp_decl.var.td->flag = flag;
   if (gwi->gwion->data->cdoc) {
     gwfmt_indent(gwi->gwfmt);
     gwfmt_exp(gwi->gwfmt, gwi->ck->exp);
@@ -52,7 +52,7 @@ m_int gwi_item_end(const Gwi gwi, const ae_flag flag, union value_data addr) {
   if (env->class_def && tflag(env->class_def, tflag_tmpl))
     return gwi_item_tmpl(gwi);
   CHECK_BB(traverse_exp(env, gwi->ck->exp));
-  const Value value = gwi->ck->exp->d.exp_decl.vd.value;
+  const Value value = gwi->ck->exp->d.exp_decl.var.vd.value;
   value->d          = addr;
   set_vflag(value, vflag_builtin);
   if (!env->class_def) SET_FLAG(value, global);
index e648492d78dcc813972d4e389920bbfe27f896a7..9376770d6b6062ecca956063f4d297a7fe5e6c08 100644 (file)
@@ -193,6 +193,11 @@ ANN static void prim_implicit(const Env env, const Type t){
   add_op(env->gwion, &opi);
 }
 
+static OP_CHECK(opck_prim_cast) {
+  Exp_Cast *cast = data;
+  return known_type(env, cast->td);
+}
+
 ANN Type mk_primitive(const Env env, const m_str name, const m_uint size) {
   m_uint sz = SZ_INT;
   while(sz < size) sz += SZ_INT;
@@ -204,7 +209,8 @@ ANN Type mk_primitive(const Env env, const m_str name, const m_uint size) {
   scan_prim_op2(env, t);
   if(size < SZ_INT) {
     prim_op(env, t, ":=>", opck_rassign, opem_bitset);
-    prim_op(env, t, "$", NULL, opem_bitcast);
+//    prim_op(env, t, "$", NULL, opem_bitcast);
+    prim_op(env, t, "$", opck_prim_cast, opem_bitcast);
     prim_implicit(env, t);
   } else if(size == SZ_INT) {
     prim_op(env, t, ":=>", opck_rassign, (opem)dummy_func);
index 1da63f56c3647f5442db9b2932397f8ad7c940e8..ac958b7e5b66b9cd581bfa64aae28a925bd19949 100644 (file)
@@ -29,7 +29,7 @@ ANN m_int gwi_union_ini(const Gwi gwi, const m_str name) {
   CHECK_BB(ck_ini(gwi, ck_udef));
   gwi->ck->name = name;
   CHECK_BB(check_typename_def(gwi, gwi->ck));
-  gwi->ck->mpv = new_mp_vector(gwi->gwion->mp, Union_Member, 0);
+  gwi->ck->mpv = new_mp_vector(gwi->gwion->mp, Variable, 0);
   return GW_OK;
 }
 
@@ -38,9 +38,9 @@ ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type,
   CHECK_BB(ck_ok(gwi, ck_udef));
   DECL_OB(Type_Decl *, td, = str2td(gwi->gwion, type, gwi->loc));
   DECL_OB(const Symbol, xid, = str2sym(gwi->gwion, name, gwi->loc));
-  Union_Member um = { .td = td, .vd = { .xid = xid, .pos = gwi->loc } };
-  mp_vector_add(gwi->gwion->mp, &gwi->ck->list, Union_Member, um);
-//  const Union_List l = new_union_list(gwi->gwion->mp, td, xid, gwi->loc);
+  Variable um = { .td = td, .vd = { .tag = MK_TAG(xid, gwi->loc) } };
+  mp_vector_add(gwi->gwion->mp, &gwi->ck->list, Variable, um);
+//  const Variable_List l = new_variable_list(gwi->gwion->mp, td, xid, gwi->loc);
 //  l->next            = gwi->ck->list;
 //  gwi->ck->list      = l;
   return GW_OK;
@@ -70,7 +70,7 @@ ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) {
   const Union_Def udef = new_union_def(gwi->gwion->mp, gwi->ck->mpv, gwi->loc);
   gwi->ck->list        = NULL;
   udef->flag           = flag;
-  udef->xid            = gwi->ck->sym;
+  udef->tag.sym        = gwi->ck->sym;
   if (gwi->ck->tmpl) {
     udef->tmpl    = gwi_tmpl(gwi);
     gwi->ck->tmpl = NULL;
@@ -82,6 +82,6 @@ ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) {
 }
 
 ANN void ck_clean_udef(MemPool mp, ImportCK *ck) {
-  if (ck->mpv) free_mp_vector(mp, Union_Member, ck->mpv);
+  if (ck->mpv) free_mp_vector(mp, Variable, ck->mpv);
   if (ck->tmpl) free_id_list(mp, ck->tmpl);
 }
index 8b0f0a699772a67081e5449e526452ccbd01b064..589d12a3024e5bb5ee13984e14ced52f89aa40a7 100644 (file)
@@ -144,11 +144,11 @@ static OP_CHECK(opck_array_at) {
       ERR_N(exp_self(bin)->pos, _("array depths do not match."));
   }
   if (bin->rhs->exp_type == ae_exp_decl) {
-    Type_Decl *td = bin->rhs->d.exp_decl.td;
+    Type_Decl *td = bin->rhs->d.exp_decl.var.td;
     if (td->array && td->array->exp)
       ERR_N(exp_self(bin)->pos,
             _("do not provide array for 'xxx => declaration'."));
-    SET_FLAG(bin->rhs->d.exp_decl.vd.value, late);
+    SET_FLAG(bin->rhs->d.exp_decl.var.vd.value, late);
   }
   bin->rhs->ref = bin->lhs;
 //  bin->rhs->data = bin->lhs;
@@ -264,7 +264,7 @@ static OP_CHECK(opck_array_cast) {
   Type parent = t;
   while(parent) {
     if (tflag(parent, tflag_cdef) && parent->info->cdef->base.ext && parent->info->cdef->base.ext->array) {
-      ERR_N(cast->td->pos, "can only cast to simple array types");
+      ERR_N(cast->td->tag.loc, "can only cast to simple array types");
     }
     parent = parent->info->parent;
   }
@@ -816,10 +816,10 @@ static OP_CHECK(opck_array_scan) {
   const Type   type = nspc_lookup_type1(base->info->value->from->owner, sym);
   if (type) return type;
   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.ext        = type2td(env->gwion, t_array, (loc_t){});
+  cdef->base.tag.sym    = sym;
   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) {})} };
+  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;
@@ -840,8 +840,8 @@ static OP_CHECK(opck_array_scan) {
   t->array_depth     = base->array_depth + 1;
   t->info->base_type = array_base(base);
   set_tflag(t, tflag_cdef | tflag_tmpl);
-  
-  builtin_func(env->gwion, (Func)vector_at(&t->nspc->vtable, 0), get_rem(t)); 
+
+  builtin_func(env->gwion, (Func)vector_at(&t->nspc->vtable, 0), get_rem(t));
   array_func(env, t, "insert", get_insert(t));
   array_func(env, t, "size", vm_vector_size);
   array_func(env, t, "depth", vm_vector_depth);
@@ -1193,7 +1193,7 @@ ANN static bool last_is_zero(Exp e) {
 ANN2(1,2) m_bool check_array_instance(const Env env, Type_Decl *td, const Exp args) {
   if (!last_is_zero(td->array->exp)) {
     if (!args)
-      ERR_B(td->pos, "declaration of abstract type arrays needs lambda");
+      ERR_B(td->tag.loc, "declaration of abstract type arrays needs lambda");
   } else {
     if(args)
       gwerr_warn("array is empty", "no need to provide a lambda",
index 2c1754a1fd41b75954b152b435b11e3181fef90b..53b275a13ef11153bc2666bea3d92b56ef090b39 100644 (file)
@@ -77,13 +77,13 @@ static OP_CHECK(opck_fptr_call) {
 }
 
 ANN Type upvalue_type(const Env env, Capture *cap) {
-  const Value v = nspc_lookup_value1(env->curr, cap->xid);
-  if(!v) ERR_O(cap->pos, _("non existing value")); // did_you_mean
+  const Value v = nspc_lookup_value1(env->curr, cap->tag.sym);
+  if(!v) ERR_O(cap->tag.loc, _("non existing value")); // did_you_mean
   if(cap->is_ref && not_upvalue(env, v))
-    ERR_O(cap->pos, _("can't take ref of a scoped value"));
+    ERR_O(cap->tag.loc, _("can't take ref of a scoped value"));
   cap->orig = v;
   const Type base_type = !tflag(v->type, tflag_ref) ? v->type : (Type)vector_front(&v->type->info->tuple->contains);
-  return !cap->is_ref ? base_type :  ref_type(env->gwion, base_type, cap->pos);
+  return !cap->is_ref ? base_type :  ref_type(env->gwion, base_type, cap->tag.loc);
 }
 
 ANN void free_captures(const VM_Shred shred, m_bit *const caps) {
@@ -119,17 +119,17 @@ static INSTR(fptr_assign) {
 
 ANN static m_bool emit_fptr_assign(const Emitter emit, const Type lhs, const Type rhs) {
   const Instr instr = emit_add_instr(emit, fptr_assign);
-  if(rhs->info->cdef && rhs->info->cdef->base.tmpl)
+  if(rhs->info->cdef && get_tmpl(rhs))
     instr->m_val = SZ_INT * 2;
   if(!lhs->info->func) {
     const Func_Def fdef = lhs->info->func->def;
     const Capture_List captures = fdef->captures;
     if(captures) {
       uint32_t offset = 0;
-      Exp e = new_prim_id(emit->gwion->mp, fdef->base->xid, fdef->base->pos); // free me
+      Exp e = new_prim_id(emit->gwion->mp, fdef->base->tag.sym, fdef->base->tag.loc); // free me
       for(uint32_t i = 0; i < captures->len; i++) {
         Capture *const cap = mp_vector_at(captures, Capture, i);
-        e->d.prim.d.var = cap->xid;
+        e->d.prim.d.var = cap->tag.sym;
         e->d.prim.value = cap->orig;
         e->type = cap->orig->type;
         exp_setvar(e, cap->is_ref);
@@ -171,7 +171,7 @@ ANN static void _fptr_tmpl_push(const Env env, const Func f) {
     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);
+    nspc_add_type(env->curr, spec->tag.sym, t);
   }
 }
 
@@ -205,7 +205,7 @@ ANN static m_bool fptr_args(const Env env, Func_Base *base[2]) {
     if (arg0->type && arg1->type)
       CHECK_BB(isa(arg0->type, arg1->type));
     else if(!tmpl_base(base[0]->tmpl) && !tmpl_base(base[1]->tmpl)){
-      Type_Decl *td[2] = {arg0->td, arg1->td};
+      Type_Decl *td[2] = {arg0->var.td, arg1->var.td};
       CHECK_BB(td_match(env, td));
     }
   }
@@ -246,12 +246,12 @@ ANN static inline m_bool fptr_rettype(const Env env, struct FptrInfo *info) {
 ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
   const Value v     = info->lhs->value_ref;
   const Nspc  nspc  = v->from->owner;
-  const m_str c     = s_name(info->lhs->def->base->xid),
+  const m_str c     = s_name(info->lhs->def->base->tag.sym),
               stmpl = !info->rhs->def->base->tmpl ? NULL : "template";
   for (m_uint i = 0; i <= v->from->offset; ++i) {
     const Symbol sym = (!info->lhs->def->base->tmpl || i != 0)
                            ? func_symbol(env, nspc->name, c, stmpl, i)
-                           : info->lhs->def->base->xid;
+                           : info->lhs->def->base->tag.sym;
     if (!is_class(env->gwion, info->lhs->value_ref->type)) {
       if (!(info->lhs = nspc_lookup_func1(nspc, sym))) {
         const Value v = nspc_lookup_value1(nspc, insert_symbol(c));
@@ -260,7 +260,7 @@ ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
       }
     } else {
       DECL_OO(const Type, t,
-              = nspc_lookup_type1(nspc, info->lhs->def->base->xid));
+              = nspc_lookup_type1(nspc, info->lhs->def->base->tag.sym));
       info->lhs = actual_type(env->gwion, t)->info->func;
     }
     Type       type    = NULL;
@@ -287,10 +287,10 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l,
     // here move to arguments
     for(uint32_t i = 0; i < l->def->captures->len; i++) {
       Capture *cap = mp_vector_at(l->def->captures, Capture, i);
-      const Value v = nspc_lookup_value1(env->curr, cap->xid);
-      if(!v) ERR_B(cap->pos, _("unknown value in capture"));
+      const Value v = nspc_lookup_value1(env->curr, cap->tag.sym);
+      if(!v) ERR_B(cap->tag.loc, _("unknown value in capture"));
       DECL_OB(const Type, t, = upvalue_type(env, cap));
-      cap->temp = new_value(env, t, s_name(cap->xid), cap->pos);
+      cap->temp = new_value(env, t, s_name(cap->tag.sym), cap->tag.loc);
       cap->orig = v;
     }
   }
@@ -303,16 +303,17 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l,
                       .flag  = tflag_scan0};
   CHECK_BB(envset_pushv(&es, owner->info->value));
   while(owner) {
-    if(owner->info->cdef->base.tmpl)
-      template_push_types(env, owner->info->cdef->base.tmpl);
+    const Tmpl *tmpl = get_tmpl(owner);
+    if(tmpl)
+      template_push_types(env, tmpl);
     owner = owner->info->value->from->owner_class;
   }
   if(bases) {
     for(uint32_t i = 0; i < bases->len; i++) {
       Arg *base = mp_vector_at(bases, Arg, i);
       Arg *arg  = mp_vector_at(args, Arg, i);
-      DECL_OB(const Type, arg_type, = known_type(env, base->td));
-      arg->td = type2td(env->gwion, arg_type, exp_self(l)->pos);
+      DECL_OB(const Type, arg_type, = known_type(env, base->var.td));
+      arg->var.td = type2td(env->gwion, arg_type, exp_self(l)->pos);
     }
   }
   DECL_OB(const Type, ret_type, = known_type(env, fdef->base->td));
@@ -341,7 +342,7 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l,
   }
   /*Type*/ owner = fdef->base->func->value_ref->from->owner_class->info->value->from->owner_class;
   while(owner) {
-    if(owner->info->cdef->base.tmpl)
+    if(get_tmpl(owner))
     nspc_pop_type(env->gwion->mp, env->curr);
     owner = owner->info->value->from->owner_class;
   }
@@ -350,8 +351,8 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l,
     if(args) {
       for(uint32_t i = 0; i < bases->len; i++) {
         Arg *arg  = mp_vector_at(args, Arg, i);
-        free_value(arg->var_decl.value, env->gwion);
-        arg->var_decl.value = NULL;
+        free_value(arg->var.vd.value, env->gwion);
+        arg->var.vd.value = NULL;
       }
     }
   }
@@ -383,7 +384,7 @@ ANN static Type partial2auto(const Env env, const Exp_Binary *bin) {
   set_fbflag(fdef->base, fbflag_lambda);
   const Type actual = fdef->base->func->value_ref->type;
   set_fbflag(fdef->base, fbflag_lambda);
-  Var_Decl vd = bin->rhs->d.exp_decl.vd;
+  Var_Decl vd = bin->rhs->d.exp_decl.var.vd;
 exp_setvar(bin->rhs, true);
   return vd.value->type = bin->rhs->type = bin->rhs->d.exp_decl.type = actual;
 }
@@ -392,7 +393,7 @@ static OP_CHECK(opck_auto_fptr) {
   const Exp_Binary *bin = (Exp_Binary *)data;
   // we'll only deal with auto fptr declaration
   if (bin->rhs->exp_type != ae_exp_decl &&
-      bin->rhs->d.exp_decl.td->xid != insert_symbol("auto"))
+      bin->rhs->d.exp_decl.var.td->tag.sym != insert_symbol("auto"))
     ERR_N(bin->lhs->pos, "invalid {G+}function{0} {+}:=>{0} {+G}function{0} assignment");
   if (bin->lhs->exp_type == ae_exp_td)
     ERR_N(bin->lhs->pos, "can't use {/}type decl expressions{0} in auto function pointer declarations");
@@ -411,11 +412,11 @@ static OP_CHECK(opck_auto_fptr) {
             num_digit(bin->rhs->pos.first.column)];
   sprintf(name, "generated@%s@%u:%u", env->curr->name, bin->rhs->pos.first.line,
           bin->rhs->pos.first.column);
-  fptr_def->base->xid = insert_symbol(name);
+  fptr_def->base->tag.sym = insert_symbol(name);
   const m_bool ret    = traverse_fptr_def(env, fptr_def);
   const Type   t      = fptr_def->cdef->base.type;
   free_fptr_def(env->gwion->mp, fptr_def);
-  Var_Decl vd = bin->rhs->d.exp_decl.vd;
+  Var_Decl vd = bin->rhs->d.exp_decl.var.vd;
   vd.value->type = bin->rhs->type =
       bin->rhs->d.exp_decl.type                = t;
   return ret > 0 ? t : env->gwion->type[et_error];
@@ -443,7 +444,7 @@ static OP_CHECK(opck_fptr_impl) {
 
 static OP_EMIT(opem_fptr_impl) {
   struct Implicit *impl = (struct Implicit *)data;
-  if(!impl->e->type->info->func->def->base->tmpl && impl->t->info->cdef->base.tmpl) {
+  if(!impl->e->type->info->func->def->base->tmpl && get_tmpl(impl->t)) {
     const Instr instr = (Instr)vector_back(&emit->code->instr);
     instr->opcode = eRegPushImm;
     instr->m_val = (m_uint)impl->e->type->info->func;
@@ -510,14 +511,14 @@ static inline void op_impl_ensure_types(const Env env, const Func func) {
       safe_tflag(func->value_ref->from->owner_class, tflag_tmpl);
   if (owner_tmpl)
     template_push_types(
-        env, func->value_ref->from->owner_class->info->cdef->base.tmpl);
+        env, get_tmpl(func->value_ref->from->owner_class));
   const bool func_tmpl = fflag(func, fflag_tmpl);
   if (func_tmpl) template_push_types(env, func->def->base->tmpl);
 
   Arg_List args = func->def->base->args;
   for(uint32_t i = 0; i < args->len; i++) {
     Arg *arg = mp_vector_at(args, Arg, i);
-    if (!arg->type) arg->type = known_type(env, arg->td);
+    if (!arg->type) arg->type = known_type(env, arg->var.td);
   }
   if (!func->def->base->ret_type)
     func->def->base->ret_type = known_type(env, func->def->base->td);
@@ -546,12 +547,12 @@ static OP_CHECK(opck_op_impl) {
       .d        = {.prim = {.d = {.var = lhs_sym}, .prim_type = ae_prim_id}},
       .exp_type = ae_exp_primary,
       .type     = arg0->type,
-      .pos      = arg0->td->pos};
+      .pos      = arg0->var.td->tag.loc};
   struct Exp_ _rhs = {
       .d        = {.prim = {.d = {.var = rhs_sym}, .prim_type = ae_prim_id}},
       .exp_type = ae_exp_primary,
       .type     = arg1->type,
-      .pos      = arg1->td->pos};
+      .pos      = arg1->var.td->tag.loc};
   struct Exp_ self = {.pos = impl->e->pos};
   self.d.exp_binary.lhs = &_lhs;
   self.d.exp_binary.rhs = &_rhs;
@@ -586,10 +587,10 @@ static OP_CHECK(opck_op_impl) {
     }
   }
   const Arg_List args = cpy_arg_list(env->gwion->mp, func->def->base->args);
-  Arg *larg0 = (Arg*)(args->ptr);
-  Arg *larg1 = (Arg*)(args->ptr + sizeof(Arg));
-  larg0->var_decl.xid = lhs_sym;
-  larg1->var_decl.xid = rhs_sym;
+  Arg *larg0 = mp_vector_at(args, Arg, 0);
+  Arg *larg1 = mp_vector_at(args, Arg, 1);
+  larg0->var.vd.tag.sym = lhs_sym;
+  larg1->var.vd.tag.sym = rhs_sym;
   Func_Base *base =
       new_func_base(env->gwion->mp, type2td(env->gwion, t, impl->e->pos),
                     impl->e->d.prim.d.var, args, ae_flag_none, impl->e->pos);
@@ -601,9 +602,9 @@ static OP_CHECK(opck_op_impl) {
     free_mp_vector(env->gwion->mp, struct ScopeEffect, eff);
   }
   const Exp lhs =
-      new_prim_id(env->gwion->mp, larg0->var_decl.xid, impl->e->pos);
+      new_prim_id(env->gwion->mp, larg0->var.vd.tag.sym, impl->e->pos);
   const Exp rhs =
-      new_prim_id(env->gwion->mp, larg1->var_decl.xid, impl->e->pos);
+      new_prim_id(env->gwion->mp, larg1->var.vd.tag.sym, impl->e->pos);
   const Exp  bin = new_exp_binary(env->gwion->mp, lhs, impl->e->d.prim.d.var,
                                  rhs, impl->e->pos);
   Stmt_List code = new_mp_vector(env->gwion->mp, struct Stmt_, 1);
@@ -613,7 +614,7 @@ static OP_CHECK(opck_op_impl) {
     .pos = impl->e->pos
   }));
   const Func_Def  def  = new_func_def(env->gwion->mp, base, code);
-  def->base->xid       = impl->e->d.prim.d.var;
+  def->base->tag.sym   = impl->e->d.prim.d.var;
 // use envset
 // or better, some function with envset and traverse
   const m_uint scope   = env_push(env, NULL, opi.nspc);
@@ -673,17 +674,17 @@ ANN static bool is_base(const Env env, const Type_List tl) {
 static OP_CHECK(opck_closure_scan) {
   struct TemplateScan *ts   = (struct TemplateScan *)data;
   struct tmpl_info     info = {
-      .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list};
+      .base = ts->t, .td = ts->td, .list = get_tmpl(ts->t)->list};
   const Type exists = tmpl_exists(env, &info);
   if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
   const Func_Base *base = closure_def(ts->t)->base;
   const Arg_List args = base->args ? cpy_arg_list(env->gwion->mp, base->args) : NULL;
-  Func_Base *const fbase = new_func_base(env->gwion->mp, cpy_type_decl(env->gwion->mp, base->td), info.name, args, ae_flag_none, base->pos);
+  Func_Base *const fbase = new_func_base(env->gwion->mp, cpy_type_decl(env->gwion->mp, base->td), info.name, args, ae_flag_none, base->tag.loc);
   fbase->tmpl = cpy_tmpl(env->gwion->mp, base->tmpl);
   if(!is_base(env, ts->td->types))
     fbase->tmpl->call = cpy_type_list(env->gwion->mp, ts->td->types);
   const Fptr_Def fdef = new_fptr_def(env->gwion->mp, cpy_func_base(env->gwion->mp, fbase));
-  fdef->base->xid = info.name;
+  fdef->base->tag.sym = info.name;
   struct EnvSet es    = {.env   = env,
                       .data  = env,
                       .func  = (_exp_func)traverse_cdef,
index d8e9f250083041fe1bbf3b220f120b9cdfe7cd07..6875581e9482cc5ba0365849908d1c1ba040777e 100644 (file)
@@ -17,6 +17,7 @@
 #include "array.h"
 #include "looper.h"
 #include "dict.h"
+#include "template.h"
 
 #define HMAP_MIN_CAP 32
 #define HMAP_MAX_LOAD 0.75
@@ -554,19 +555,20 @@ static OP_CHECK(opck_dict_each_val) {
 
 static OP_CHECK(opck_dict_scan) {
   struct TemplateScan *ts   = (struct TemplateScan *)data;
-  if(ts->t->info->cdef->base.tmpl->call) return ts->t;
+  const Tmpl *tmpl = get_tmpl(ts->t);
+  if(tmpl->call) return ts->t;
   struct tmpl_info     info = {
-      .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list};
+      .base = ts->t, .td = ts->td, .list = tmpl->list};
   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, 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");
+    ERR_N(ts->td->tag.loc, "can't use Ref:[] in dicts");
   const Class_Def cdef  = cpy_class_def(env->gwion->mp, env->gwion->type[et_dict]->info->cdef);
-  cdef->base.ext        = type2td(env->gwion, env->gwion->type[et_dict], (loc_t) {});
-  cdef->base.xid        = info.name;
+  cdef->base.ext        = type2td(env->gwion, env->gwion->type[et_dict], (loc_t){});
+  cdef->base.tag.sym    = info.name;
   cdef->base.tmpl->call = cpy_type_list(env->gwion->mp, info.td->types);
 
   const bool is_global = tmpl_global(env, ts->td->types);
index 8148b7ac7a4001371b985b3a4b3fc2ccebebc8f9..0345d290e21f87f4b89a4c9b936fa5624b30fd8b 100644 (file)
@@ -138,6 +138,12 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
   GWI_BB(gwi_oper_end(gwi, ".", NULL))
 
+  // allow const generics in functions
+  GWI_BB(gwi_oper_ini(gwi, "function", (m_str)OP_ANY_TYPE, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_object_dot))
+  GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
+  GWI_BB(gwi_oper_end(gwi, ".", NULL))
+
   GWI_BB(gwimport_class(gwi))
 
   gwidoc(gwi, "allow static access.");
index 2b9e40096064513c92fcb616544670e0a8adb7a4..de0506075ca5b20223aaf67f78877da88929f100 100644 (file)
 ANN static Func_Def traverse_tmpl(const Emitter emit, Func_Def fdef, Func_Def fbase,
                               const Nspc nspc) {
   const Env env = emit->env;
-  const Symbol   sym  = func_symbol(env, nspc->name, s_name(fdef->base->xid),
+  const Symbol   sym  = func_symbol(env, nspc->name, s_name(fdef->base->tag.sym),
                                  "template", fbase->vt_index);
   DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym)
-                                ?: nspc_lookup_value0(nspc, fdef->base->xid));
+                                ?: nspc_lookup_value0(nspc, fdef->base->tag.sym));
   const f_xfun xfun = v->d.func_ref->def->d.dl_func_ptr;
   if (vflag(v, vflag_builtin))
     v->d.func_ref->def->d.dl_func_ptr = NULL; // why
index 77cb458e888d6e5cdaaace0a9bc56b97dbb3b99f..fa892fc6426eea6c34aae88d1db30d3d43499a15 100644 (file)
@@ -101,7 +101,7 @@ static ID_CHECK(opck_this) {
       ERR_O(exp_self(prim)->pos,
           _("keyword 'this' cannot be used inside static functions..."))
     if (!exp_getuse(exp_self(prim)) &&
-        !strcmp(s_name(env->func->def->base->xid), "@gack"))
+        !strcmp(s_name(env->func->def->base->tag.sym), "@gack"))
       return get_gack(env->class_def->info->parent); // get_gack ?
   }
   return env->class_def;
index f2fcc5b409f9c99208a22baff958c43f7cc52f4a..a359f0e65960a88f719b8248fcbb8bb3ac334b9c 100644 (file)
@@ -1,4 +1,3 @@
-
 #include "gwion_util.h"
 #include "gwion_ast.h"
 #include "gwion_env.h"
@@ -32,7 +31,7 @@ static OP_CHECK(opck_object_at) {
   if (opck_rassign(env, data) == env->gwion->type[et_error])
     return env->gwion->type[et_error];
   if (bin->rhs->exp_type == ae_exp_decl) {
-    Var_Decl vd = bin->rhs->d.exp_decl.vd;
+    Var_Decl vd = bin->rhs->d.exp_decl.var.vd;
     SET_FLAG(vd.value, late);
   }
   exp_setvar(bin->rhs, 1);
@@ -46,14 +45,14 @@ static OP_CHECK(opck_object_instance) {
   Exp rhs = bin->rhs;
   if (rhs->exp_type != ae_exp_decl)
     return NULL;
-  if (rhs->d.exp_decl.td->array)
+  if (rhs->d.exp_decl.var.td->array)
     return NULL;
   Exp lhs = bin->lhs;
   Exp e = exp_self(bin);
   Exp_Decl *const decl = &e->d.exp_decl;
   e->exp_type = ae_exp_decl;
-  decl->td = cpy_type_decl(env->gwion->mp, rhs->d.exp_decl.td);
-  decl->vd = rhs->d.exp_decl.vd;
+  decl->var.td = cpy_type_decl(env->gwion->mp, rhs->d.exp_decl.var.td);
+  decl->var.vd = rhs->d.exp_decl.var.vd;
   decl->type = rhs->type;
   decl->args = lhs;
   free_exp(env->gwion->mp, rhs);
@@ -94,7 +93,8 @@ ANN /*static*/ Type scan_class(const Env env, const Type t,
 
 static OP_CHECK(opck_struct_scan) {
   struct TemplateScan *ts = (struct TemplateScan *)data;
-  if(ts->t->info->cdef->base.tmpl->call) return ts->t;
+  const Tmpl *tmpl = get_tmpl(ts->t);
+  if(tmpl->call) return ts->t;
   return scan_class(env, ts->t, ts->td) ?: env->gwion->type[et_error];
 }
 
@@ -119,7 +119,7 @@ ANN static void emit_dottmpl(const Emitter emit, const Func f) {
   struct dottmpl_ *dt = mp_malloc(emit->gwion->mp, dottmpl);
   dt->nspc = emit->env->curr;
   dt->type = emit->env->class_def;
-  dt->tmpl_name = tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->pos);
+  dt->tmpl_name = tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->tag.loc);
   instr->m_val2 = (m_uint)dt;
 }
 
@@ -279,7 +279,7 @@ ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
   const Class_Def cdef = new_class_def(
       env->gwion->mp, c->flag, info->name,
       c->base.ext ? cpy_type_decl(env->gwion->mp, c->base.ext) : NULL,
-      NULL, c->pos);
+      NULL, c->base.tag.loc);
   if(c->body) cdef->body = cpy_ast(env->gwion->mp, c->body);
   cdef->cflag      = c->cflag;
   cdef->base.tmpl  = mk_tmpl(env, c->base.tmpl, info->td->types);
@@ -295,8 +295,8 @@ ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
 ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) {
   const Union_Def u    = info->base->info->udef;
   const Union_Def udef = new_union_def(
-      env->gwion->mp, cpy_union_list(env->gwion->mp, u->l), u->pos);
-  udef->xid  = info->name;
+      env->gwion->mp, cpy_variable_list(env->gwion->mp, u->l), u->tag.loc);
+  udef->tag.sym  = info->name;
   udef->tmpl = mk_tmpl(env, u->tmpl, info->td->types);
   // resolve the template here
   if (GET_FLAG(info->base, global)) SET_FLAG(udef, global);
@@ -320,7 +320,7 @@ ANN static Type _scan_class(const Env env, struct tmpl_info *info) {
 
 ANN Type scan_class(const Env env, const Type t, const Type_Decl *td) {
   struct tmpl_info info = {
-      .base = t, .td = td, .list = t->info->cdef->base.tmpl->list};
+      .base = t, .td = td, .list = get_tmpl(t)->list};
   const Type exists = tmpl_exists(env, &info);
   if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
   struct EnvSet es    = {.env   = env,
index 67fdd2ff40d2d8c0487d6a54134f482e450a5eef..7c869ebbba83296f389028d586a5f0a189307899 100644 (file)
@@ -128,9 +128,9 @@ OP_CHECK(opck_new) {
   }
   CHECK_BN(ensure_traverse(env, t));
   if (type_ref(t))
-    ERR_N(unary->ctor.td->pos, _("can't use 'new' on ref type '%s'\n"), t->name);
+    ERR_N(unary->ctor.td->tag.loc, _("can't use 'new' on ref type '%s'\n"), t->name);
   if (tflag(t, tflag_infer))
-    ERR_N(unary->ctor.td->pos, _("can't use 'new' on '%s'\n"),
+    ERR_N(unary->ctor.td->tag.loc, _("can't use 'new' on '%s'\n"),
           t->name);
   if (array) {
     CHECK_BN(check_subscripts(env, array, 1));
@@ -150,7 +150,7 @@ OP_CHECK(opck_new) {
   }
   if (GET_FLAG(t, abstract) &&
      (!array || (array->exp && exp_is_zero(array->exp))))
-    ERR_N(unary->ctor.td->pos, _("can't use 'new' on abstract type '%s'\n"),
+    ERR_N(unary->ctor.td->tag.loc, _("can't use 'new' on abstract type '%s'\n"),
           t->name);
   if (isa(t, env->gwion->type[et_object]) < 0)
     ERR_N(exp_self(unary)->pos, _("can't use 'new' on non-object types...\n"));
index 3a0b807621c5f1c4ccd5fb3faf2b164446af34f1..8b6f7c2af428c4b91a09030e81b72525a66c6c1e 100644 (file)
@@ -146,7 +146,7 @@ ANN static void ref2ref(Env env, const Type lhs, const Type rhs) {
 static OP_CHECK(opck_ref_scan) {
   struct TemplateScan *ts   = (struct TemplateScan *)data;
   struct tmpl_info     info = {
-      .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list};
+      .base = ts->t, .td = ts->td, .list = get_tmpl(ts->t)->list};
   const Type exists = tmpl_exists(env, &info);
   if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
   const TmplArg arg = *mp_vector_at(ts->td->types, TmplArg, 0);
index 3033d5c37f5ab840b63641b76089271fd47b6b8b..a1d387a6e98e04c2ef780b213e906fea878a2aaa 100644 (file)
@@ -43,11 +43,11 @@ ANN static inline size_t tmpl_set(struct tmpl_info *info, const m_str str) {
 
 ANN static ssize_t template_size(const Env env, struct tmpl_info *info) {
   DECL_OB(const m_str, str,
-          = tl2str(env->gwion, info->td->types, info->td->pos));
+          = tl2str(env->gwion, info->td->types, info->td->tag.loc));
   const size_t tmpl_sz = tmpl_set(info, str);
   const m_str  base    = !is_func(env->gwion, info->base)
    ? mstrdup(env->gwion->mp, info->base->name)
-   : type2str(env->gwion, info->base, info->td->pos);
+   : type2str(env->gwion, info->base, info->td->tag.loc);
   return tmpl_sz + tmpl_set(info, base) + 4;
 }
 
@@ -91,7 +91,7 @@ ANN static Type _tmpl_exists(const Env env, const Symbol name) {
 
 ANN Type tmpl_exists(const Env env, struct tmpl_info *const info) {
   if (template_match(info->list, info->td->types) < 0) // invalid template
-    ERR_N(info->td->pos, _("invalid template types number"));
+    ERR_N(info->td->tag.loc, _("invalid template types number"));
   if (!info->name)
     info->name = template_id(env, info);
   return _tmpl_exists(env, info->name);
index b65ed4018ab7ffb0f74c23a637349f91f24cff43..c02f8b94b3b4aed9ea8b27a2382c4cedbb7caa02 100644 (file)
@@ -42,7 +42,7 @@ static OP_CHECK(opck_spork) {
       for(uint32_t i = 0; i < unary->captures->len; i++) {
         Capture *const cap = mp_vector_at(unary->captures, Capture, i);
         DECL_OO(const Type, t, = upvalue_type(env, cap));
-        cap->temp = new_value(env, t, s_name(cap->xid), cap->pos);
+        cap->temp = new_value(env, t, s_name(cap->tag.sym), cap->tag.loc);
         cap->temp->from->offset = offset;
         offset += cap->temp->type->size;
       }
@@ -55,14 +55,14 @@ static OP_CHECK(opck_spork) {
     if(unary->captures) {
       for(uint32_t i = 0; i < unary->captures->len; i++) {
         Capture *const cap = mp_vector_at(unary->captures, Capture, i);
-        valid_value(env, cap->xid, cap->temp);
+        valid_value(env, cap->tag.sym, cap->temp);
       }
     }
     const Func f = env->func;
     struct Value_ value = { .type = env->gwion->type[et_function]};
     if(env->class_def)
       set_vflag(&value, vflag_member);
-    struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = &upvalues, .fbflag = fbflag_lambda, .pos = exp_self(unary)->pos};
+    struct Func_Base_ fbase = { .tag=MK_TAG(insert_symbol("in spork"), exp_self(unary)->pos), .values = &upvalues, .fbflag = fbflag_lambda};
     struct Func_Def_ fdef = { .base = &fbase};
     struct Func_ func = { .name = "in spork", .def = &fdef, .value_ref = &value};
     env->func = &func;
index 3a35d7e185460711c995d063bcc325cae59f0f33..79858f7fb1bbfa3e4c234f96066849fb8bfd44b2 100644 (file)
@@ -57,9 +57,9 @@ ANN m_bool check_subscripts(Env env, const Array_Sub array,
 
 ANN static inline m_bool check_exp_decl_parent(const Env      env,
                                                const Var_Decl *var) {
-  const Value value = find_value(env->class_def->info->parent, var->xid);
+  const Value value = find_value(env->class_def->info->parent, var->tag.sym);
   if (value) {
-    env_err(env, var->pos, _("Value defined in parent class"));
+    env_err(env, var->tag.loc, _("Value defined in parent class"));
     defined_here(value);
     return GW_ERROR;
   }
@@ -99,7 +99,7 @@ ANN static void var_effects(const Env env, const Type t, const Symbol sym, const
 ANN static m_bool check_var(const Env env, const Var_Decl *var) {
   if (env->class_def && !env->scope->depth && env->class_def->info->parent)
     CHECK_BB(check_exp_decl_parent(env, var));
-  var_effects(env, var->value->type, insert_symbol("@ctor"), var->pos);
+  var_effects(env, var->value->type, insert_symbol("@ctor"), var->tag.loc);
   return GW_OK;
 }
 
@@ -117,15 +117,15 @@ ANN static m_bool check_var_td(const Env env, const Var_Decl *var,
 }
 
 ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
-  const Var_Decl *vd = &decl->vd;
+  const Var_Decl *vd = &decl->var.vd;
   CHECK_BB(check_var(env, vd));
-  CHECK_BB(check_var_td(env, vd, decl->td));
-  if (decl->td->array && decl->td->array->exp) {
-    CHECK_BB(check_subscripts(env, decl->td->array, true));
+  CHECK_BB(check_var_td(env, vd, decl->var.td));
+  if (decl->var.td->array && decl->var.td->array->exp) {
+    CHECK_BB(check_subscripts(env, decl->var.td->array, true));
     if (GET_FLAG(array_base(decl->type), abstract))
-      CHECK_BB(check_array_instance(env, decl->td, decl->args));
+      CHECK_BB(check_array_instance(env, decl->var.td, decl->args));
   }
-  valid_value(env, vd->xid, vd->value);
+  valid_value(env, vd->tag.sym, vd->value);
   // set_vflag(var->value, vflag_used));
   return GW_OK;
 }
@@ -161,36 +161,36 @@ ANN static inline m_bool inferable(const Env env, const Type t,
 }
 
 ANN Type check_exp_decl(const Env env, Exp_Decl *const decl) {
-  if (decl->td->array && decl->td->array->exp)
-    CHECK_OO(check_exp(env, decl->td->array->exp));
+  if (decl->var.td->array && decl->var.td->array->exp)
+    CHECK_OO(check_exp(env, decl->var.td->array->exp));
   if (decl->args) {
-    const Exp e = new_exp_unary2(env->gwion->mp, insert_symbol("new"), cpy_type_decl(env->gwion->mp, decl->td), decl->args, decl->td->pos);
+    const Exp e = new_exp_unary2(env->gwion->mp, insert_symbol("new"), cpy_type_decl(env->gwion->mp, decl->var.td), decl->args, decl->var.td->tag.loc);
     CHECK_OO(check_exp(env, e));
     decl->args = e;
     e->ref = exp_self(decl);
   }
-  if (decl->td->xid == insert_symbol("auto")) { // should be better
+  if (decl->var.td->tag.sym == insert_symbol("auto")) { // should be better
     CHECK_BO(scan1_exp(env, exp_self(decl)));
     CHECK_BO(scan2_exp(env, exp_self(decl)));
   }
-  if (!decl->type) ERR_O(decl->td->pos, _("can't find type"));
+  if (!decl->type) ERR_O(decl->var.td->tag.loc, _("can't find type"));
   {
     CHECK_BO(ensure_check(env, decl->type));
-    if(inferable(env, decl->type, decl->td->pos) < 0) {
+    if(inferable(env, decl->type, decl->var.td->tag.loc) < 0) {
       if(!tflag(decl->type, tflag_check) && decl->type->ref > 1 && env->class_def && !env->scope->depth)
         type_remref(decl->type, env->gwion);
       return NULL;
    }
   }
-  const m_bool global = GET_FLAG(decl->td, global);
+  const m_bool global = GET_FLAG(decl->var.td, global);
   const m_uint scope  = !global ? env->scope->depth : env_push_global(env);
   const m_bool ret    = check_decl(env, decl);
   if (global) {
     env_pop(env, scope);
-    set_vflag(decl->vd.value, vflag_direct);
+    set_vflag(decl->var.vd.value, vflag_direct);
   }
   env_weight(env, 1 + isa(decl->type, env->gwion->type[et_object]) > 0);
-  return ret > 0 ? decl->vd.value->type : NULL;
+  return ret > 0 ? decl->var.vd.value->type : NULL;
 }
 
 ANN static m_bool check_collection(const Env env, Type type, const Exp e,
@@ -287,6 +287,18 @@ ANN m_bool not_from_owner_class(const Env env, const Type t, const Value v,
 ANN static inline Value get_value(const Env env, const Symbol sym) {
   const Value value = nspc_lookup_value1(env->curr, sym);
   if(value) {
+if(value->from->owner_class && is_func(env->gwion, value->from->owner_class)) {
+/*
+
+set_tflag(value->from->owner_class, tflag_check);
+set_tflag(value->from->owner_class, tflag_scan0);
+set_tflag(value->from->owner_class, tflag_scan1);
+set_tflag(value->from->owner_class, tflag_scan2);
+set_tflag(value->from->owner_class, tflag_check);
+*/
+return value;
+}
+
     if (!value->from->owner_class || isa(env->class_def, value->from->owner_class) > 0)
       return value;
     if(env->class_def) {
@@ -364,6 +376,8 @@ ANN static Type prim_owned(const Env env, const Symbol *data) {
   const Value v    = exp->d.prim.value;
   if(is_class(env->gwion, v->type) && env->class_def == v->type->info->base_type) // write it better
     return v->type->info->base_type;
+//  if(v->from->owner_class && is_func(env->gwion, v->from->owner_class))
+//    return v->type;
   const m_str name = !GET_FLAG(v, static) ? "this" : v->from->owner_class->name;
   const Exp   base =
       new_prim_id(env->gwion->mp, insert_symbol(name), prim_pos(data));
@@ -529,7 +543,7 @@ static ANN Type check_exp_slice(const Env env, const Exp_Slice *range) {
 // without the mangling
 ANN static inline Type type_list_base_func(const Type type) {
   const Nspc owner = type->info->value->from->owner;
-  const Symbol xid = type->info->func->def->base->xid;
+  const Symbol xid = type->info->func->def->base->tag.sym;
   return nspc_lookup_type0(owner, xid);
 }
 
@@ -545,8 +559,9 @@ ANN static Type_Decl*  mk_td(const Env env, Type_Decl *td,
   return type2td(env->gwion, t, pos);
 }
 
-ANN static Type tmpl_arg_match(const Env env, const Symbol xid, const Symbol tgt, const Type t) {
+ANN static Type tmplarg_match(const Env env, const Symbol xid, const Symbol tgt, const Type t) {
   if (xid == tgt) return t;
+//  Tmpl *tmpl = get_tmpl(t);//tflag(t, tflag_cdef) ? t->info->cdef->base.tmpl
   Tmpl *tmpl = tflag(t, tflag_cdef) ? t->info->cdef->base.tmpl
        : tflag(t, tflag_udef) ? t->info->udef->tmpl
        : NULL;
@@ -554,8 +569,8 @@ ANN static Type tmpl_arg_match(const Env env, const Symbol xid, const Symbol tgt
   const uint32_t len = mp_vector_len(tmpl->list);
   for(uint32_t i = 0; i < len; i++) {
     Specialized *spec = mp_vector_at(tmpl->list, Specialized, i);
-    const Type base = nspc_lookup_type1(t->nspc, spec->xid);
-    const Type t = tmpl_arg_match(env, xid, spec->xid, base);
+    const Type base = nspc_lookup_type1(t->nspc, spec->tag.sym);
+    const Type t = tmplarg_match(env, xid, spec->tag.sym, base);
     if(t) return t;
   }
   return NULL;
@@ -587,7 +602,7 @@ static Func find_func_match_actual(const Env env, const Func f, const Exp exp,
       if (arg->type == env->gwion->type[et_auto]) {
         const Type owner = func->value_ref->from->owner_class;
         if (owner) CHECK_BO(template_push(env, owner));
-        arg->type = known_type(env, arg->td);
+        arg->type = known_type(env, arg->var.td);
         if (owner) nspc_pop_type(env->gwion->mp, env->curr);
         CHECK_OO(arg->type);
       }
@@ -616,7 +631,7 @@ ANN static Func call2ufcs(const Env env, Exp_Call *call, const Value v) {
 }
 
 ANN static Func ufcs(const Env env, const Func up, Exp_Call *const call) {
-  const Value v = nspc_lookup_value1(env->curr, up->def->base->xid);
+  const Value v = nspc_lookup_value1(env->curr, up->def->base->tag.sym);
   if (v && is_func(env->gwion, v->type) && !v->from->owner_class) // is_callable
     return call2ufcs(env, call, v);
   return NULL;
@@ -657,10 +672,10 @@ ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) {
 ANN static m_bool check_func_args(const Env env, Arg_List args) {
   for(uint32_t i = 0; i < args->len; i++) {
     Arg *arg = mp_vector_at(args, Arg, i);
-    const Var_Decl *decl = &arg->var_decl;
+    const Var_Decl *decl = &arg->var.vd;
     const Value    v    = decl->value;
-    if(decl->xid) CHECK_BB(already_defined(env, decl->xid, decl->pos));
-    valid_value(env, decl->xid, v);
+    if(decl->tag.sym) CHECK_BB(already_defined(env, decl->tag.sym, decl->tag.loc));
+    valid_value(env, decl->tag.sym, v);
   }
   return GW_OK;
 }
@@ -753,16 +768,17 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp,
   const uint32_t len = sl->len - spread;
   Type_List    tl = new_mp_vector(env->gwion->mp, TmplArg, len);
   m_uint       args_number = 0;
-
+// infer template types from args
+// should not work with const generic
   if(exp->other) {
     for(uint32_t i = 0; i < len; i++) {
       Specialized *spec = mp_vector_at(sl, Specialized, i);
-      if (tmpl_arg_match(env, spec->xid, fdef->base->td->xid, fdef->base->ret_type)) {
+      if (tmplarg_match(env, spec->tag.sym, fdef->base->td->tag.sym, fdef->base->ret_type)) {
         CHECK_OO(check_exp(env, exp->other));
          if(!is_func(env->gwion, exp->other->type)) {
            TmplArg targ = {
              .type = tmplarg_td,
-             .d = { .td = type2td(env->gwion, exp->other->type, fdef->base->td->pos) }
+             .d = { .td = type2td(env->gwion, exp->other->type, fdef->base->td->tag.loc) }
            };
            mp_vector_set(tl, TmplArg, 0, targ);
          } else {
@@ -772,7 +788,7 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp,
                Arg *arg = mp_vector_at(func->def->base->args, Arg, 0);
                TmplArg targ = {
                  .type = tmplarg_td,
-                 .d = { .td = cpy_type_decl(env->gwion->mp, arg->td) }
+                 .d = { .td = cpy_type_decl(env->gwion->mp, arg->var.td) }
                };
                mp_vector_set(tl, TmplArg, 0, targ);
                break;
@@ -792,10 +808,10 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp,
     uint32_t count = 0;
     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)) {
+      if (tmplarg_match(env, spec->tag.sym, arg->var.td->tag.sym, template_arg->type)) {
         TmplArg targ = {
           .type = tmplarg_td,
-          .d = { .td = mk_td(env, arg->td, template_arg->type, fdef->base->pos) }
+          .d = { .td = mk_td(env, arg->var.td, template_arg->type, fdef->base->tag.loc) }
         };
         mp_vector_set(tl, TmplArg, args_number, targ);
         ++args_number;
@@ -875,12 +891,12 @@ ANN static Exp check_lambda_captures(const Env env, const Func_Def fdef) {
       if(args) free_exp(env->gwion->mp, args);
       return NULL;
     }
-    Arg arg = {
-      .td = type2td(env->gwion, t, cap->pos),
-      .var_decl = { .xid = cap->xid }
-    };
+    Arg arg = { .var = MK_VAR(
+        type2td(env->gwion, t, cap->tag.loc),
+        (Var_Decl){ .tag = MK_TAG(cap->tag.sym, cap->tag.loc) }
+    )};
     mp_vector_add(env->gwion->mp, &fdef->base->args, Arg, arg);
-    const Exp exp = new_prim_id(env->gwion->mp, cap->xid, cap->pos);
+    const Exp exp = new_prim_id(env->gwion->mp, cap->tag.sym, cap->tag.loc);
     if(args) tmp = tmp->next = exp;
     else args = tmp = exp;
   }
@@ -1078,7 +1094,7 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) {
   CHECK_OO(check_exp(env, bin->rhs));
   if (is_auto) {
     assert(bin->rhs->type == bin->lhs->type);
-    set_vflag(bin->rhs->d.exp_decl.vd.value, vflag_assigned);
+    set_vflag(bin->rhs->d.exp_decl.var.vd.value, vflag_assigned);
   }
   struct Op_Import opi = {.op   = bin->op,
                           .lhs  = bin->lhs->type,
@@ -1089,7 +1105,7 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) {
   exp_setuse(bin->rhs, 1);
   const Type ret = op_check(env, &opi);
   if (!ret && is_auto && exp_self(bin)->exp_type == ae_exp_binary)
-    bin->rhs->d.exp_decl.vd.value->type = env->gwion->type[et_auto];
+    bin->rhs->d.exp_decl.var.vd.value->type = env->gwion->type[et_auto];
   return ret;
 }
 
@@ -1126,7 +1142,7 @@ ANN static m_bool predefined_call(const Env env, const Type t,
   free_mstr(env->gwion->mp, str);
   if (tflag(t, tflag_typedef)) {
     gwerr_secondary("from definition:", env->name,
-                    t->info->func->def->base->pos);
+                    t->info->func->def->base->tag.loc);
   }
   return GW_ERROR;
 }
@@ -1259,13 +1275,13 @@ ANN static Type check_exp_dot(const Env env, Exp_Dot *member) {
 ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
   if (tdef->when) {
     set_tflag(tdef->type, tflag_contract);
-    struct Var_Decl_ decl = { .xid = insert_symbol("self"), .pos = tdef->when->pos };
+    struct Var_Decl_ decl = { .tag = MK_TAG(insert_symbol("self"), tdef->when->pos) };
     Type_Decl *td = cpy_type_decl(env->gwion->mp, tdef->ext);
     Arg_List args = new_mp_vector(env->gwion->mp, Arg, 1);
-    mp_vector_set(args, Arg, 0, ((Arg) { .td = td, .var_decl = decl }));
+    mp_vector_set(args, Arg, 0, ((Arg) { .var = MK_VAR(td, decl)}));
     Func_Base *fb = new_func_base(
-        env->gwion->mp, type2td(env->gwion, tdef->type, tdef->pos),
-        insert_symbol("@implicit"), args, ae_flag_none, tdef->pos);
+        env->gwion->mp, type2td(env->gwion, tdef->type, tdef->tag.loc),
+        insert_symbol("@implicit"), args, ae_flag_none, tdef->tag.loc);
     set_fbflag(fb, fbflag_op);
     const Exp helper = new_prim_id(env->gwion->mp, insert_symbol("@predicate"),
                                    tdef->when->pos);
@@ -1293,14 +1309,14 @@ ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
                   "use `{/+}bool{0}`", env->name, when->pos, 0);
       char from[strlen(tdef->type->name) + 39];
       sprintf(from, "in `{/+}%s{0}` definition", tdef->type->name);
-      gwerr_secondary(from, env->name, tdef->pos);
+      gwerr_secondary(from, env->name, tdef->tag.loc);
       env_set_error(env, true);
       return GW_ERROR;
     }
     // we handle the return after, so that we don't get *cant' use implicit
     // casting while defining it*
     const Exp ret_id = new_prim_id(env->gwion->mp, insert_symbol("self"), when->pos);
-    ret_id->d.prim.value = new_value(env, tdef->type, "self", tdef->pos);
+    ret_id->d.prim.value = new_value(env, tdef->type, "self", tdef->tag.loc);
     struct Stmt_ ret = {
       .stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = ret_id }},
       .pos = when->pos
@@ -1348,7 +1364,7 @@ ANN m_bool check_enum_def(const Env env, const Enum_Def edef) {
   ID_List list = edef->list;
   for(uint32_t i = 0; i < list->len; i++) {
     EnumValue ev= *mp_vector_at(list, EnumValue, i);
-    decl_static(env, nspc_lookup_value0(env->curr, ev.xid));
+    decl_static(env, nspc_lookup_value0(env->curr, ev.tag.sym));
   }
   env_pop(env, scope);
   return GW_OK;
@@ -1386,8 +1402,8 @@ ANN static inline m_bool for_empty(const Env env, const Stmt_For stmt) {
 }
 
 ANN static void check_idx(const Env env, const Type base, struct EachIdx_ *const idx) {
-  idx->v = new_value(env, base, s_name(idx->sym), idx->pos);
-  valid_value(env, idx->sym, idx->v);
+  idx->v = new_value(env, base, s_name(idx->tag.sym), idx->tag.loc);
+  valid_value(env, idx->tag.sym, idx->v);
   SET_FLAG(idx->v, const);
 }
 
@@ -1398,7 +1414,7 @@ ANN static m_bool check_each_idx(const Env env, const Exp exp, struct EachIdx_ *
     .lhs = exp->type,
     .op  = insert_symbol("@each_idx"),
     .data = (m_uint)exp,
-    .pos = idx->pos
+    .pos = idx->tag.loc
   };
   DECL_OB(const Type, t, = op_check(env, &opi));
   check_idx(env, t, idx);
@@ -1422,8 +1438,8 @@ ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
   if (stmt->idx)
     CHECK_BB(check_each_idx(env, stmt->exp, stmt->idx));
   DECL_OB(const Type, ret, = check_each_val(env, stmt->exp));
-  stmt->v = new_value(env, ret, s_name(stmt->sym), stmt->vpos);
-  valid_value(env, stmt->sym, stmt->v);
+  stmt->v = new_value(env, ret, s_name(stmt->tag.sym), stmt->tag.loc);
+  valid_value(env, stmt->tag.sym, stmt->v);
   return check_conts(env, stmt_self(stmt), stmt->body);
 }
 
@@ -1487,7 +1503,7 @@ ANN static m_bool check_stmt_return(const Env env, const Stmt_Exp stmt) {
           ret_type->name);
   if (stmt->val) {
     Arg *arg = mp_vector_at(env->func->def->base->args, Arg, 0);
-    if (env->func->def->base->xid == insert_symbol("@implicit") &&
+    if (env->func->def->base->tag.sym == insert_symbol("@implicit") &&
         ret_type == arg->type)
       ERR_B(stmt_self(stmt)->pos,
             _("can't use implicit casting while defining it"))
@@ -1522,7 +1538,7 @@ ANN static m_bool check_stmt_exp(const Env env, const Stmt_Exp stmt) {
   if(stmt->val) {
     CHECK_OB(check_exp(env, stmt->val));
     if(stmt->val->exp_type == ae_exp_lambda) {
-     const loc_t loc = stmt->val->d.exp_lambda.def->base->pos;
+     const loc_t loc = stmt->val->d.exp_lambda.def->base->tag.loc;
      env_warn(env, loc, _("Partial application not used"));
     }
   }
@@ -1640,8 +1656,8 @@ ANN static inline m_bool check_handler_list(const restrict Env env,
 ANN static inline bool find_handler(const Handler_List handlers, const Symbol xid) {
   for(uint32_t i = 0; i < handlers->len; i++) {
     Handler *handler = mp_vector_at(handlers, Handler, i);
-    if(xid == handler->xid) return true;
-    if(!handler->xid) return true;
+    if(xid == handler->tag.sym) return true;
+    if(!handler->tag.sym) return true;
   }
   return false;
 }
@@ -1729,13 +1745,13 @@ ANN m_bool check_stmt_list(const Env env, Stmt_List l) {
 ANN static m_bool check_signature_match(const Env env, const Func_Def fdef,
                                         const Func parent) {
   if (GET_FLAG(parent->def->base, final))
-    ERR_B(fdef->base->td->pos, _("can't override final function '%s'\n"),
+    ERR_B(fdef->base->td->tag.loc, _("can't override final function '%s'\n"),
           parent->name)
   if (GET_FLAG(parent->def->base, static) != GET_FLAG(fdef->base, static)) {
     const m_str c_name = fdef->base->func->value_ref->from->owner_class->name;
     const m_str p_name = parent->value_ref->from->owner_class->name;
-    const m_str f_name = s_name(fdef->base->xid);
-    ERR_B(fdef->base->td->pos,
+    const m_str f_name = s_name(fdef->base->tag.sym);
+    ERR_B(fdef->base->td->tag.loc,
           _("function '%s.%s' ressembles '%s.%s' but cannot override...\n"
             "  ...(reason: '%s.%s' is declared as 'static')"),
           c_name, f_name, p_name, c_name,
@@ -1772,7 +1788,7 @@ ANN static m_bool check_parent_match(const Env env, const Func_Def fdef) {
   const Type parent = env->class_def->info->parent;
   if (!env->curr->vtable.ptr) vector_init(&env->curr->vtable);
   if (parent) {
-    const Value v = find_value(parent, fdef->base->xid);
+    const Value v = find_value(parent, fdef->base->tag.sym);
     if (v && is_func(env->gwion, v->type)) {
       const m_bool match = parent_match_actual(env, fdef, v->d.func_ref);
       if (match) return match;
@@ -1786,7 +1802,7 @@ ANN static m_bool check_parent_match(const Env env, const Func_Def fdef) {
 ANN static inline Func get_overload(const Env env, const Func_Def fdef,
                                     const m_uint i) {
   const Symbol sym =
-      func_symbol(env, env->curr->name, s_name(fdef->base->xid), NULL, i);
+      func_symbol(env, env->curr->name, s_name(fdef->base->tag.sym), NULL, i);
   return nspc_lookup_func1(env->curr, sym);
 }
 
@@ -1803,10 +1819,10 @@ ANN static m_bool check_func_overload(const Env env, const Func_Def fdef) {
               fbflag(f2->def->base, fbflag_unary) &&
           fbflag(f1->def->base, fbflag_postfix) ==
               fbflag(f2->def->base, fbflag_postfix))
-        ERR_B(f2->def->base->pos,
+        ERR_B(f2->def->base->tag.loc,
               _("global function '%s' already defined"
                 " for those arguments"),
-              s_name(fdef->base->xid))
+              s_name(fdef->base->tag.sym))
     }
   }
   return GW_OK;
@@ -1827,13 +1843,13 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef,
   const Func func = fdef->base->func;
   if (env->class_def && env->class_def->info->parent) {
     const Value override =
-        find_value(env->class_def->info->parent, fdef->base->xid);
+        find_value(env->class_def->info->parent, fdef->base->tag.sym);
     if (override && override->from->owner_class &&
         !is_func(env->gwion, override->type))
-      ERR_B(fdef->base->pos,
+      ERR_B(fdef->base->tag.loc,
             _("function name '%s' conflicts with previously defined value...\n"
               "  from super class '%s'..."),
-            s_name(fdef->base->xid), override->from->owner_class->name)
+            s_name(fdef->base->tag.sym), override->from->owner_class->name)
     *ov = override;
   }
   if (func->value_ref->from->offset &&
@@ -1845,8 +1861,8 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef,
 ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) {
   MP_Vector *v = (MP_Vector*)vector_back(&env->scope->effects);
   if (v) {
-    if (fdef->base->xid == insert_symbol("@dtor"))
-      ERR_B(fdef->base->pos, _("can't use effects in destructors"));
+    if (fdef->base->tag.sym == insert_symbol("@dtor"))
+      ERR_B(fdef->base->tag.loc, _("can't use effects in destructors"));
     const Vector base = &fdef->base->effects;
     if (!base->ptr) vector_init(base);
     for (uint32_t i = 0; i < v->len; i++) {
@@ -1859,23 +1875,69 @@ ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) {
   return GW_OK;
 }
 
+ANN static void fdef_const_generic_value(const Env env, const Type owner, const Type t, const Tag tag) {
+  const Value v = new_value(env, t, s_name(tag.sym), tag.loc);
+  SET_FLAG(v, static|ae_flag_const);
+  valid_value(env, tag.sym, v);
+  nspc_add_value_front(owner->nspc, tag.sym, v);
+  v->from->owner = owner->nspc;
+  v->from->owner_class = owner;
+}
+
+ANN static m_bool fdef_const_generic_typecheck(const Env env, const Specialized *spec, const TmplArg *targ) {
+  CHECK_OB(check_exp(env, targ->d.exp));
+  // check implicits?
+  const Type target = known_type(env, spec->td);
+  if(isa(targ->d.exp->type, target) < 0) {
+    char msg[256];
+    tcol_snprintf(msg, 255, "expected {G+}%s{0}", target->name);
+    gwerr_basic("invalid type for const generic argument", msg, NULL, env->name, spec->tag.loc, 0);
+    tcol_snprintf(msg, 255, "got {G+}%s{0}", targ->d.exp->type->name);
+    gwerr_secondary(msg, env->name, targ->d.exp->pos);
+    return GW_ERROR;
+  }
+  return GW_OK;
+}
+
+ANN static m_bool check_fdef_const_generic(const Env env, const Func_Def fdef) {
+  const Tmpl *tmpl = fdef->base->tmpl;
+  if(tmplarg_ntypes(tmpl->call) == tmpl->call->len) return GW_OK;
+  const Type t = fdef->base->func->value_ref->type;
+  assert(!t->nspc);
+  t->nspc = new_nspc(env->gwion->mp, t->name);
+
+  for(uint32_t i = 0; i < fdef->base->tmpl->call->len; i++) {
+    const TmplArg *targ = mp_vector_at(fdef->base->tmpl->call, TmplArg, i);
+    if(targ->type == tmplarg_td)continue;
+    // spec could be null cause of spread ops
+    const Specialized *spec = mp_vector_at(fdef->base->tmpl->list, Specialized, i);
+    if(!spec) break;
+    CHECK_BB(fdef_const_generic_typecheck(env, spec, targ));
+    fdef_const_generic_value(env, t, targ->d.exp->type, spec->tag);
+  }
+  return GW_OK;
+}
+
+ANN static m_bool check_fdef_code(const Env env, const Func_Def fdef) {
+  const bool ctor = is_ctor(fdef);
+  if(!ctor) {
+    nspc_push_value(env->gwion->mp, env->curr);
+    env->scope->depth++;
+  }
+  const m_bool ret = check_stmt_list(env, fdef->d.code);
+  if(!ctor) {
+    env->scope->depth--;
+    nspc_pop_value(env->gwion->mp, env->curr);
+  }
+  CHECK_BB(check_fdef_effects(env, fdef));
+  return ret;
+}
+
 ANN m_bool check_fdef(const Env env, const Func_Def fdef) {
   if (fdef->base->args) CHECK_BB(check_func_args(env, fdef->base->args));
-  if(fdef->builtin) return GW_OK;
-  if (fdef->d.code && fdef->d.code) {
-    const bool ctor = is_ctor(fdef);
-    if(!ctor) {
-      env->scope->depth++;
-      nspc_push_value(env->gwion->mp, env->curr);
-    }
-    const m_bool ret = check_stmt_list(env, fdef->d.code);
-    if(!ctor) {
-      nspc_pop_value(env->gwion->mp, env->curr);
-      env->scope->depth--;
-    }
-    CHECK_BB(check_fdef_effects(env, fdef));
-    return ret;
-  }
+  if (fdef->base->tmpl) CHECK_BB(check_fdef_const_generic(env, fdef));
+  if (fdef->builtin) return GW_OK;
+  if (fdef->d.code) CHECK_BB(check_fdef_code(env, fdef));
   return GW_OK;
 }
 
@@ -1888,10 +1950,9 @@ ANN static m_bool check_ctor(const Env env, const Func func) {
       const Type parent = env->class_def->info->parent;
       const Value v = nspc_lookup_value0(parent->nspc, insert_symbol("new"));
       if(v && !GET_FLAG(v->d.func_ref->def->base, abstract))
-        ERR_B(func->def->base->pos, "missing call to parent constructor");
+        ERR_B(func->def->base->tag.loc, "missing call to parent constructor");
     }
   }
-
   return GW_OK;
 }
 
@@ -1913,6 +1974,7 @@ ANN m_bool _check_func_def(const Env env, const Func_Def f) {
   const Func former = env->func;
   env->func         = func;
   nspc_push_value(env->gwion->mp, env->curr);
+//  env->scope->depth++;
   struct Op_Import opi = {};
   if (fbflag(fdef->base, fbflag_op)) {
     func_operator(f, &opi);
@@ -1922,7 +1984,7 @@ ANN m_bool _check_func_def(const Env env, const Func_Def f) {
     uint32_t offset = fdef->stack_depth;
     for(uint32_t i = 0; i < fdef->captures->len; i++) {
       Capture *cap = mp_vector_at(fdef->captures, Capture, i);
-      valid_value(env, cap->xid, cap->temp);
+      valid_value(env, cap->tag.sym, cap->temp);
       cap->temp->from->offset = offset;
       offset += cap->temp->type->size;
     }
@@ -1932,13 +1994,14 @@ ANN m_bool _check_func_def(const Env env, const Func_Def f) {
   vector_pop(&env->scope->effects);
   if (fbflag(fdef->base, fbflag_op)) operator_resume(&opi);
   nspc_pop_value(env->gwion->mp, env->curr);
+//  env->scope->depth--;
   env->func = former;
   if (ret > 0) {
     if (env->class_def && fdef->base->effects.ptr &&
         (override &&
          !check_effect_overload(&fdef->base->effects, override->d.func_ref)))
-      ERR_B(fdef->base->pos, _("too much effects in override."),
-            s_name(fdef->base->xid))
+      ERR_B(fdef->base->tag.loc, _("too much effects in override."),
+            s_name(fdef->base->tag.sym))
       if(is_new(f) && !tflag(env->class_def, tflag_struct))
         CHECK_BB(check_ctor(env, func));
   }
@@ -1961,7 +2024,7 @@ ANN m_bool check_func_def(const Env env, const Func_Def fdef) {
 ANN bool check_trait_requests(const Env env, const Type t, const ID_List list, const ValueFrom *from);
 ANN static m_bool check_extend_def(const Env env, const Extend_Def xdef) {
   const Type t = xdef->type;
-  ValueFrom from = { .filename = env->name, .loc=xdef->td->pos, .ctx=env->context,
+  ValueFrom from = { .filename = env->name, .loc=xdef->td->tag.loc, .ctx=env->context,
       .owner = env->curr, .owner_class = env->class_def
   };
   const bool ret = check_trait_requests(env, t, xdef->traits, &from);
@@ -1984,7 +2047,7 @@ ANN static m_bool check_extend_def(const Env env, const Extend_Def xdef) {
 }
 
 ANN static m_bool _check_trait_def(const Env env, const Trait_Def pdef) {
-  const Trait trait = nspc_lookup_trait1(env->curr, pdef->xid);
+  const Trait trait = nspc_lookup_trait1(env->curr, pdef->tag.sym);
   Ast         ast   = pdef->body;
   if(!ast) return GW_OK;
   for(m_uint i = 0; i < ast->len; i++) {
@@ -1996,7 +2059,7 @@ ANN static m_bool _check_trait_def(const Env env, const Trait_Def pdef) {
     const Stmt stmt = mp_vector_at(l, struct Stmt_, i);
         if (stmt->stmt_type == ae_stmt_exp) {
           CHECK_BB(traverse_exp(env, stmt->d.stmt_exp.val));
-          Var_Decl vd = stmt->d.stmt_exp.val->d.exp_decl.vd;
+          Var_Decl vd = stmt->d.stmt_exp.val->d.exp_decl.var.vd;
           const Value value = vd.value;
           valuefrom(env, value->from);
           if (!trait->var)
@@ -2053,7 +2116,7 @@ ANN m_bool check_abstract(const Env env, const Class_Def cdef) {
         gwerr_basic(_("missing function definition"),
                     _("must be declared 'abstract'"),
                     _("provide an implementation for the following:"),
-                    env->name, cdef->pos, 0);
+                    env->name, cdef->base.tag.loc, 0);
       }
       ValueFrom *from = f->value_ref->from;
       gwerr_secondary_from("implementation missing", from);
@@ -2067,7 +2130,7 @@ ANN static bool class_def_has_body(Ast ast) {
   const Section *section = mp_vector_at(ast, Section, 0);
   if(section->section_type != ae_section_func) return false;
   Func_Def f = section->d.func_def;
-  if(strcmp(s_name(f->base->xid), "@ctor"))return false;
+  if(strcmp(s_name(f->base->tag.sym), "@ctor"))return false;
   Stmt_List l = f->d.code;
   for(m_uint i = 0; i < l->len; i++) {
     const Stmt stmt = mp_vector_at(l, struct Stmt_, i);
@@ -2076,8 +2139,8 @@ ANN static bool class_def_has_body(Ast ast) {
       const Exp exp = stmt->d.stmt_exp.val;
       if (!exp) continue;
       if (exp->exp_type != ae_exp_decl) return true;
-      if (GET_FLAG(exp->d.exp_decl.td, late)) continue;
-      Var_Decl vd = exp->d.exp_decl.vd;
+      if (GET_FLAG(exp->d.exp_decl.var.td, late)) continue;
+      Var_Decl vd = exp->d.exp_decl.var.vd;
       if (GET_FLAG(vd.value, late)) continue;
       if (tflag(vd.value->type, tflag_compound))
         return true;
@@ -2097,7 +2160,7 @@ ANN static bool recursive_value(const Env env, const Type t, const Value v) {
   if(type_is_recurs(t, tgt)) {
     env_err(env, v->from->loc, _("recursive type"));
     env_set_error(env,  false);
-    gwerr_secondary("in class", t->name, t->info->cdef->base.pos);
+    gwerr_secondary("in class", t->name, t->info->cdef->base.tag.loc);
 
     const Type first = tgt->info->value->from->loc.first.line < t->info->value->from->loc.first.line ?
       v->type : t;
@@ -2169,17 +2232,13 @@ ANN static m_bool check_class_tmpl(const Env env, const Tmpl *tmpl, const Nspc n
       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);
+      const Value v = new_value(env, targ.d.exp->type, s_name(spec.tag.sym), 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);
+      nspc_add_value(nspc, spec.tag.sym, v);
       SET_FLAG(v, const| ae_flag_static);
       set_vflag(v, vflag_builtin);
-
-      // set value type
     }
   }
   return GW_OK;
index e06d08ba194b7bb4e4e4dd31cebd38b3fba8f66a..91063e6a0772c051d4af6a378573b0251567bb29 100644 (file)
@@ -52,7 +52,7 @@ ANN static bool check_trait_variables(const Env env, const Type t,
 }
 
 ANN static bool trait_inherit(const Env env, const Type t, const Func_Def req) {
-  const bool global = type_global(env, t) || !!nspc_lookup_value1(env->curr->parent, req->base->xid);
+  const bool global = type_global(env, t) || !!nspc_lookup_value1(env->curr->parent, req->base->tag.sym);
   nspc_push_type(env->gwion->mp, env->curr);
   nspc_add_type(env->curr, insert_symbol("Self"), t);
   const Func_Def cpy   = cpy_func_def(env->gwion->mp, req);
@@ -70,12 +70,12 @@ ANN static bool check_trait_args(const Env env, const Func f, const Func_Base *r
   if (mp_vector_len(f->def->base->args) + m != mp_vector_len(req->args)) return false;
   if(m) {
     const Arg *r = mp_vector_at(req->args, Arg, 0);
-    if(strcmp(s_name(r->td->xid), "Self"))
+    if(strcmp(s_name(r->var.td->tag.sym), "Self"))
     return false;
   }
   for(m_uint i = m; i < req->args->len; i++) {
     const Arg *r = mp_vector_at(req->args, Arg, i + m);
-    const Type t = known_type(env, r->td);
+    const Type t = known_type(env, r->var.td);
     const Arg *arg = mp_vector_at(f->def->base->args, Arg, i);
     if(arg->type != t) return false;
   }
@@ -84,7 +84,7 @@ ANN static bool check_trait_args(const Env env, const Func f, const Func_Base *r
 
 ANN static bool request_found(const Env env, const Type t,
                             const Func_Def request) {
-  const Value v = nspc_lookup_value0(t->nspc, request->base->xid);
+  const Value v = nspc_lookup_value0(t->nspc, request->base->tag.sym);
   if (!v) return false;
   if (!is_func(env->gwion, v->type)) {
     gwerr_basic_from("is not a function", NULL, NULL, v->from, 0);
@@ -124,7 +124,7 @@ ANN static bool ufcs_match(const Env env, const Value v,
 
 ANN static bool trait_ufcs(const Env env, const Type t,
                             const Func_Def request) {
-  const Value v = nspc_lookup_value1(env->curr, request->base->xid);
+  const Value v = nspc_lookup_value1(env->curr, request->base->tag.sym);
   if(v) {
     const bool global = type_global(env, t) || from_global_nspc(env, v->from->owner);
     nspc_push_type(env->gwion->mp, env->curr);
@@ -142,16 +142,16 @@ ANN static bool request_fun(const Env env, const Type t,
   if (trait_ufcs(env, t, request)) return true;
   if (!GET_FLAG(request->base, abstract))
     return trait_inherit(env, t, request);
-  const Value parent = nspc_lookup_value1(env->global_nspc, request->base->xid);
+  const Value parent = nspc_lookup_value1(env->global_nspc, request->base->tag.sym);
   if(parent) {
-    const Value v = nspc_lookup_value1(env->curr, request->base->xid);
+    const Value v = nspc_lookup_value1(env->curr, request->base->tag.sym);
     if(!env->context->error) {
       gwerr_basic_from("is missing {+G}global{0}", NULL, NULL, v->from, 0);
-      gwerr_secondary("from requested func", env->name, request->base->pos);
+      gwerr_secondary("from requested func", env->name, request->base->tag.loc);
       env_set_error(env, true);
     }
   } else gwerr_basic("missing requested function", NULL, NULL, env->name,
-              request->base->pos, 0);
+              request->base->tag.loc, 0);
   return false;
 }
 
index 682644365c62c13820b1c3fe1561fb26d8aae8ed..aa74c15f84275dbb9c2e6fc91dda40451beaefeb 100644 (file)
@@ -8,7 +8,7 @@
 ANN2(1,2) static Exp base_args(const MemPool p, const Arg_List args, Exp next, const uint32_t min) {
   for(uint32_t i = min; i--;) {
     Arg *arg = mp_vector_at(args, Arg, i);
-    const Exp exp = new_prim_id(p, arg->var_decl.xid, arg->var_decl.pos);
+    const Exp exp = new_prim_id(p, arg->var.vd.tag.sym, arg->var.vd.tag.loc);
     exp->next = next;
     next = exp;
   }
@@ -46,23 +46,23 @@ ANN static Stmt_List code(const MemPool p, const Exp func, const Arg_List lst,
 
 ANN static Stmt_List std_code(const Env env, Func_Base *base, const uint32_t max) {
   const MemPool p = env->gwion->mp;
-  const Exp func = new_prim_id(p, base->xid, base->pos);
+  const Exp func = new_prim_id(p, base->tag.sym, base->tag.loc);
   return code(p, func, base->args, max, ae_stmt_return);
 }
 
 ANN static Stmt_List new_code(const Env env, Func_Base *base, const uint32_t max) {
   const MemPool p = env->gwion->mp;
   SymTable *st = env->gwion->st;
-  const Exp dbase  = new_prim_id(p, insert_symbol(st, "this"), base->pos);
+  const Exp dbase  = new_prim_id(p, insert_symbol(st, "this"), base->tag.loc);
   const Symbol sym = insert_symbol(st, "new");
-  const Exp func  = new_exp_dot(p, dbase, sym, base->pos);
+  const Exp func  = new_exp_dot(p, dbase, sym, base->tag.loc);
   return code(p, func, base->args, max, ae_stmt_exp);
 }
 
 
 ANN Func_Def default_args(const Env env, Func_Base *fb, Ast *acc, uint32_t max) {
   Func_Base *const base = cpy_func_base(env->gwion->mp, fb);
-  Stmt_List code = strcmp(s_name(base->xid), "new")
+  Stmt_List code = strcmp(s_name(base->tag.sym), "new")
       ? std_code(env, fb, max)
       : new_code(env, fb, max);
   const Func_Def  fdef  = new_func_def(env->gwion->mp, base, code);
index a9984d9bff2ac4c5d54f33c308914d42b67c89a9..a3bc20d1105e3447487f4521869e1b7fccc657f7 100644 (file)
@@ -8,19 +8,19 @@
 #include "operator.h"
 
 ANN void func_operator(const Func_Def fdef, struct Op_Import *opi) {
-  opi->op         = fdef->base->xid;
-  const m_str str = s_name(fdef->base->xid);
+  opi->op         = fdef->base->tag.sym;
+  const m_str str = s_name(fdef->base->tag.sym);
   const uint  is_unary =
       fbflag(fdef->base, fbflag_unary) +
       (!strcmp(str, "@conditional") || !strcmp(str, "@unconditional"));
   const Arg_List args = fdef->base->args;
   Arg *arg0 = args ? mp_vector_at(args, Arg, 0) : NULL;
   Arg *arg1 = (args && args->len >= 2) ? mp_vector_at(args, Arg, 1) : NULL;
-  opi->lhs = is_unary ? NULL : args ? arg0->var_decl.value->type : NULL;
+  opi->lhs = is_unary ? NULL : args ? arg0->var.vd.value->type : NULL;
   if (strcmp(str, "@implicit"))
 //    opi->rhs = args ? is_unary ? arg0->var_decl->value->type
-    opi->rhs = args ? is_unary ? (arg0 ? arg0->var_decl.value->type : NULL)
-                               : (arg1 ? arg1->var_decl.value->type : NULL)
+    opi->rhs = args ? is_unary ? (arg0 ? arg0->var.vd.value->type : NULL)
+                               : (arg1 ? arg1->var.vd.value->type : NULL)
                     : NULL;
   else
     opi->rhs = fdef->base->ret_type;
index f2ef19cb4d3163f73f85bcccb76212ef5959f9aa..4aa3f346fd373032757c79221b9f9f2387f94e0f 100644 (file)
@@ -77,7 +77,7 @@ ANN static Func fptr_match(const Env env, struct ResolverArgs *ra) {
   const Tmpl tmpl = {.list = base->base->tmpl->list, .call = ra->types};
   CHECK_BO(template_push_types(env, &tmpl));
   Func_Base *const fbase = cpy_func_base(env->gwion->mp, base->base);
-  fbase->xid             = sym;
+  fbase->tag.sym         = sym;
   fbase->tmpl->call      = cpy_type_list(env->gwion->mp, ra->types);
   const Fptr_Def fptr    = new_fptr_def(env->gwion->mp, fbase);
   const Func     m_func  = ensure_fptr(env, ra, fptr);
@@ -110,12 +110,11 @@ ANN static Func create_tmpl(const Env env, struct ResolverArgs *ra,
       char c[256];
       sprintf(c, "arg%u", idx);
       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*/ }};
+      Arg arg = { .var = MK_VAR(cpy_type_decl(env->gwion->mp, targ.d.td), (Var_Decl){ .tag = MK_TAG(insert_symbol(c), fdef->base->tag.loc)})};
       mp_vector_add(env->gwion->mp, &args, Arg, arg);
     }
     fdef->base->args = args;
   }
-
   const Func func        = ensure_tmpl(env, fdef, ra->e, ra->v->from->filename);
   if (func && func->def->builtin) {
     builtin_func(env->gwion, func, (void*)ra->v->d.func_ref->code->native_func);
@@ -151,14 +150,14 @@ ANN static Func find_tmpl(const Env env, const Value v, Exp_Call *const exp,
       .v = v, .e = exp, .tmpl_name = tmpl_name, .types = types};
   CHECK_BO(envset_pushv(&es, v));
   (void)env_push(env, v->from->owner_class, v->from->owner);
-  const bool in_tmpl = v->from->owner_class && v->from->owner_class->info->cdef &&
-      v->from->owner_class->info->cdef->base.tmpl;
-  if(in_tmpl)
-    (void)template_push_types(env, v->from->owner_class->info->cdef->base.tmpl);
+  const Tmpl *tmpl = v->from->owner_class && v->from->owner_class->info->cdef ?
+      get_tmpl(v->from->owner_class) : NULL;
+  if(tmpl)
+    (void)template_push_types(env, tmpl);
   const bool is_clos = isa(exp->func->type, env->gwion->type[et_closure]) > 0;
   const Func m_func = !is_clos ? func_match(env, &ra)
                                : fptr_match(env, &ra);
-  if(in_tmpl)
+  if(tmpl)
     nspc_pop_type(env->gwion->mp, env->curr);
   env_pop(env, scope);
   envset_pop(&es, v->from->owner_class);
@@ -184,13 +183,21 @@ ANN static Func _find_template_match(const Env env, const Value v,
     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
+      if(unlikely(arg.type == tmplarg_td))
+        ERR_O(exp_self(exp)->pos, "expected contant, not type");
+      // check argument in call exp
       continue;
 
+    } else {
+      if(unlikely(arg.type == tmplarg_exp)) {
+        ERR_O(exp_self(exp)->pos, "expected type, not constant");
+        // 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;
     }
-    DECL_OO(const Type, t, = known_type(env, arg.d.td));
-    if(t->info->traits && miss_traits(t, spec))
-      return NULL;
   }
   return f;
 }
@@ -211,7 +218,7 @@ ANN Func find_template_match(const Env env, const Value value,
   while (t && t->nspc) {
     const Func_Def fdef = value->d.func_ref ? value->d.func_ref->def
                                             : value->type->info->func->def;
-    const Value    v    = nspc_lookup_value0(t->nspc, fdef->base->xid);
+    const Value    v    = nspc_lookup_value0(t->nspc, fdef->base->tag.sym);
     if (v) {
       const Func f = _find_template_match(env, v, exp);
       if (f) return f;
index 022ac4c92c2b64d3e23125de88101bdce89202bd..feb57286a029b090be906d336439dc8305645e38 100644 (file)
@@ -194,7 +194,7 @@ ANN static Type op_check_inner(const Env env, struct OpChecker *ock,
 ANN static bool op_template_type(const Symbol xid, const Specialized_List sl) {
   for(uint32_t i = 0; i < sl->len; i++) {
     Specialized *spec = mp_vector_at(sl, Specialized, i);
-    if (xid == spec->xid) return true;
+    if (xid == spec->tag.sym) return true;
   }
   return false;
 }
@@ -202,7 +202,7 @@ ANN static bool op_template_type(const Symbol xid, const Specialized_List sl) {
 //! check if type matches for template operator
 ANN2(1,2,3) bool _tmpl_match(const Env env, const Type t, Type_Decl *const td,
                     Specialized_List sl) {
-  if (!td->next && !td->types && op_template_type(td->xid, sl))
+  if (!td->next && !td->types && op_template_type(td->tag.sym, sl))
     return true;
   const Type base = known_type(env, td);
   return base ? isa(t, base) > 0 : false;
@@ -216,14 +216,14 @@ ANN bool tmpl_match(const Env env, const struct Op_Import *opi,
   Arg *arg0 = mp_vector_at(args, Arg, 0);
   Arg *arg1 = args->len > 1 ? mp_vector_at(args, Arg, 1) : NULL;
   if (opi->lhs) {
-    if (!_tmpl_match(env, opi->lhs, arg0->td, sl)) return false;
+    if (!_tmpl_match(env, opi->lhs, arg0->var.td, sl)) return false;
     if (fbflag(base, fbflag_postfix)) return !!opi->rhs;
     if (!fbflag(base, fbflag_unary)) {
       if (!opi->rhs) return false;
-      if (!_tmpl_match(env, opi->rhs, arg1->td, sl)) return false;
+      if (!_tmpl_match(env, opi->rhs, arg1->var.td, sl)) return false;
     } else if (opi->rhs) return false;
   } else if (!fbflag(base, fbflag_unary) ||
-        !_tmpl_match(env, opi->rhs, arg0->td, sl))
+        !_tmpl_match(env, opi->rhs, arg0->var.td, sl))
       return false;
   return true;
 }
@@ -261,7 +261,7 @@ ANN static Type op_check_tmpl(const Env env, struct Op_Import *opi) {
     const Vector v = &nspc->operators->tmpl;
     for (m_uint i = vector_size(v) + 1; --i;) {
       const Func_Def fdef = (Func_Def)vector_at(v, i - 1);
-      if (opi->op != fdef->base->xid) continue;
+      if (opi->op != fdef->base->tag.sym) continue;
       if (!tmpl_match(env, opi, fdef->base)) continue;
       return op_def(env, opi, fdef);
     }
@@ -380,10 +380,10 @@ ANN static m_bool handle_instr(const Emitter emit, const M_Operator *mo) {
     emit_pushfunc(emit, mo->func);
     CHECK_BB(emit_exp_call1(emit, mo->func,
           mo->func->def->base->ret_type->size, true));
-    if (mo->func->def->base->xid ==
+    if (mo->func->def->base->tag.sym ==
         insert_symbol(emit->gwion->st, "@conditional"))
       emit_add_instr(emit, BranchEqInt);
-    else if (mo->func->def->base->xid ==
+    else if (mo->func->def->base->tag.sym ==
              insert_symbol(emit->gwion->st, "@unconditional"))
       emit_add_instr(emit, BranchNeqInt);
     return GW_OK;
index 158e1f0579107b399b014b7bd2ffe27c19dbdfde..f4ee2a995a0356c91a174cb7c3d576affb772a8a 100644 (file)
@@ -22,8 +22,8 @@ ANN static Arg_List partial_arg_list(const Env env, const Arg_List base, const E
       char c[256];
       sprintf(c, "@%u", args->len);
       const Arg *src = mp_vector_at(base, Arg, i);
-      Type_Decl *td = src->td ? cpy_type_decl(env->gwion->mp, src->td) : NULL;
-      Arg arg = { .td = td, .var_decl = { .xid = insert_symbol(c) }};
+      Type_Decl *td = src->var.td ? cpy_type_decl(env->gwion->mp, src->var.td) : NULL;
+      Arg arg = { .var = MK_VAR(td, (Var_Decl){ .tag = MK_TAG(insert_symbol(c), src->var.vd.tag.loc)})};
       mp_vector_add(env->gwion->mp, &args, Arg, arg);
     }
     i++;
@@ -49,7 +49,7 @@ ANN static Exp partial_exp(const Env env, Arg_List args, Exp e, const uint i) {
     char c[256];
     sprintf(c, "@%u", i);
     const Exp exp = new_prim_id(env->gwion->mp, insert_symbol(c), e->pos);
-    exp->type = known_type(env, mp_vector_at(args, Arg, i)->td);
+    exp->type = known_type(env, mp_vector_at(args, Arg, i)->var.td);
     exp->d.prim.value = new_value(env, exp->type, c, e->pos);
     valid_value(env, insert_symbol(c), exp->d.prim.value);
     return exp;
@@ -117,7 +117,7 @@ ANN static void print_arg(Arg_List args) {
   for(uint32_t i = 0; i < args->len; i++) {
     Arg *arg = mp_vector_at(args, Arg, i);
     gw_err("{G}%s{0} {/}%s{0}", arg->type ? arg->type->name : NULL,
-           arg->var_decl.xid ? s_name(arg->var_decl.xid) : "");
+           arg->var.vd.tag.sym ? s_name(arg->var.vd.tag.sym) : "");
     if(i < args->len - 1) gw_err(", ");
   }
 }
index 9f8e18b4bbc97efd6309706e08db7473fe54cb89..9626183ef3539dc7849be9ad970421910d5957e8 100644 (file)
@@ -17,22 +17,21 @@ static inline void add_type(const Env env, const Nspc nspc, const Type t) {
   nspc_add_type_front(nspc, insert_symbol(t->name), t);
 }
 
-ANN static inline m_bool scan0_defined(const Env env, const Symbol s,
-                                       const loc_t pos) {
-  if (nspc_lookup_type1(env->curr, s))
-    ERR_B(pos, _("type '%s' already defined"), s_name(s));
-  return already_defined(env, s, pos);
+ANN static inline m_bool scan0_defined(const Env env, const Tag tag) {
+  if (nspc_lookup_type1(env->curr, tag.sym))
+    ERR_B(tag.loc, _("type '%s' already defined"), s_name(tag.sym));
+  return already_defined(env, tag.sym, tag.loc);
 }
 
 ANN static Arg_List fptr_arg_list(const Env env, const Fptr_Def fptr) {
   if(env->class_def && !GET_FLAG(fptr->base, static)) {
-    Arg arg = { .td = type2td(env->gwion, env->class_def, fptr->base->td->pos) };
+    Arg arg = { .var = {.td = type2td(env->gwion, env->class_def, fptr->base->td->tag.loc)}};
     const uint32_t len = mp_vector_len(fptr->base->args);
     Arg_List args = new_mp_vector(env->gwion->mp, Arg, len + 1);
     mp_vector_set(args, Arg, 0, arg);
     for(uint32_t i = 0; i < len; i++) {
       Arg *base  = mp_vector_at(fptr->base->args, Arg, i);
-      Arg arg = { .td = cpy_type_decl(env->gwion->mp, base->td) };
+      Arg arg = { .var = {.td = cpy_type_decl(env->gwion->mp, base->var.td)}};
       mp_vector_set(args, Arg, i+1, arg);
     }
     return args;
@@ -55,9 +54,9 @@ ANN static inline m_bool scan0_global(const Env env, const ae_flag flag,
 }
 
 ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) {
-  const loc_t loc = fptr->base->td->pos;
+  const loc_t loc = fptr->base->td->tag.loc;
   CHECK_BB(env_access(env, fptr->base->flag, loc));
-  CHECK_BB(scan0_defined(env, fptr->base->xid, loc));
+  CHECK_BB(scan0_defined(env, fptr->base->tag));
   const Arg_List args = fptr_arg_list(env, fptr);
   Func_Base *const fbase = new_func_base(env->gwion->mp, cpy_type_decl(env->gwion->mp, fptr->base->td),
     insert_symbol("func"), args, ae_flag_static | ae_flag_private, loc);
@@ -65,7 +64,7 @@ ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) {
   Ast body = new_mp_vector(env->gwion->mp, Section, 1);
   mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef));
   Type_Decl* td = new_type_decl(env->gwion->mp, insert_symbol(env->gwion->type[et_closure]->name), loc);
-  const Class_Def cdef = new_class_def(env->gwion->mp, ae_flag_final, fptr->base->xid, td, body, loc);
+  const Class_Def cdef = new_class_def(env->gwion->mp, ae_flag_final, fptr->base->tag.sym, td, body, loc);
   if(GET_FLAG(fptr->base, global)) {
     SET_FLAG(cdef, global);
     UNSET_FLAG(fptr->base, global);
@@ -126,7 +125,7 @@ ANN static void scan0_explicit_distinct(const Env env, const Type lhs,
 
 ANN static void typedef_simple(const Env env, const Type_Def tdef,
                                const Type base) {
-  const Type t    = new_type(env->gwion->mp, s_name(tdef->xid), base);
+  const Type t    = new_type(env->gwion->mp, s_name(tdef->tag.sym), base);
   t->size         = base->size;
   const Nspc nspc = (!env->class_def && GET_FLAG(tdef->ext, global))
                         ? env->global_nspc
@@ -148,9 +147,9 @@ ANN static void typedef_simple(const Env env, const Type_Def tdef,
 ANN static m_bool typedef_complex(const Env env, const Type_Def tdef,
                                   const Type base) {
   const ae_flag   flag = base->info->cdef ? base->info->cdef->flag : 0;
-  const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->xid,
+  const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->tag.sym,
                                        cpy_type_decl(env->gwion->mp, tdef->ext),
-                                       NULL, tdef->ext->pos);
+                                       NULL, tdef->ext->tag.loc);
   const bool final = GET_FLAG(base, final);
   if(final) UNSET_FLAG(base, final);
   CHECK_BB(scan0_class_def(env, cdef));
@@ -162,14 +161,14 @@ ANN static m_bool typedef_complex(const Env env, const Type_Def tdef,
 }
 
 ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
-  CHECK_BB(env_access(env, tdef->ext->flag, tdef->ext->pos));
+  CHECK_BB(env_access(env, tdef->ext->flag, tdef->ext->tag.loc));
   DECL_OB(const Type, base, = known_type(env, tdef->ext));
-  CHECK_BB(scan0_defined(env, tdef->xid, tdef->ext->pos));
-  DECL_BB(const m_bool, global, = scan0_global(env, tdef->ext->flag, tdef->ext->pos));
+  CHECK_BB(scan0_defined(env, tdef->tag));
+  DECL_BB(const m_bool, global, = scan0_global(env, tdef->ext->flag, tdef->ext->tag.loc));
   if (!tdef->ext->types && (!tdef->ext->array || !tdef->ext->array->exp))
     typedef_simple(env, tdef, base);
   else CHECK_BB(typedef_complex(env, tdef, base));
-  mk_class(env, tdef->type, tdef->pos);
+  mk_class(env, tdef->type, tdef->tag.loc);
   if (tdef->when) set_tflag(tdef->type, tflag_contract);
   if (tdef->type != base && !tdef->distinct && !tdef->when)
     scan0_implicit_similar(env, base, tdef->type);
@@ -192,16 +191,16 @@ ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
 
 ANN static Type enum_type(const Env env, const Enum_Def edef) {
   const Type   t    = type_copy(env->gwion->mp, env->gwion->type[et_enum]);
-  t->name           = s_name(edef->xid);
+  t->name           = s_name(edef->tag.sym);
   t->info->parent   = env->gwion->type[et_enum];
   add_type(env, env->curr, t);
-  mk_class(env, t, edef->pos);
+  mk_class(env, t, edef->tag.loc);
   return t;
 }
 
 ANN m_bool scan0_enum_def(const Env env, const Enum_Def edef) {
-  CHECK_BB(scan0_defined(env, edef->xid, edef->pos));
-  DECL_BB(const m_bool, global, = scan0_global(env, edef->flag, edef->pos));
+  CHECK_BB(scan0_defined(env, edef->tag));
+  DECL_BB(const m_bool, global, = scan0_global(env, edef->flag, edef->tag.loc));
   edef->type = enum_type(env, edef);
   if (global) env_pop(env, 0);
   return GW_OK;
@@ -280,9 +279,9 @@ ANN static void union_tmpl(const Env env, const Union_Def udef) {
 }
 
 ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
-  DECL_BB(const m_bool, global, = scan0_global(env, udef->flag, udef->pos));
-  CHECK_BB(scan0_defined(env, udef->xid, udef->pos));
-  udef->type   = union_type(env, udef->xid, udef->pos);
+  DECL_BB(const m_bool, global, = scan0_global(env, udef->flag, udef->tag.loc));
+  CHECK_BB(scan0_defined(env, udef->tag));
+  udef->type   = union_type(env, udef->tag.sym, udef->tag.loc);
   SET_ACCESS(udef, udef->type);
   if (udef->tmpl) union_tmpl(env, udef);
   if (global) env_pop(env, 0);
@@ -300,7 +299,7 @@ ANN static Type get_parent_base(const Env env, Type_Decl *td) {
   Type owner = env->class_def;
   while (owner) {
     if (t == owner)
-      ERR_O(td->pos, _("'%s' as parent inside itself\n."), owner->name);
+      ERR_O(td->tag.loc, _("'%s' as parent inside itself\n."), owner->name);
     owner = owner->info->value->from->owner_class;
   }
   return t;
@@ -308,7 +307,7 @@ ANN static Type get_parent_base(const Env env, Type_Decl *td) {
 
 ANN static inline Type scan0_final(const Env env, Type_Decl *td) {
   const Type t = known_type(env, td);
-  if(!t) ERR_O(td->pos, _("can't find parent class %s\n."), s_name(td->xid));
+  if(!t) ERR_O(td->tag.loc, _("can't find parent class %s\n."), s_name(td->tag.sym));
   return t;
 }
 
@@ -343,16 +342,16 @@ ANN static m_bool find_traits(const Env env, ID_List traits, const loc_t pos) {
 }
 
 ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
-  CHECK_BO(scan0_defined(env, cdef->base.xid, cdef->pos));
+  CHECK_BO(scan0_defined(env, cdef->base.tag));
   DECL_OO(const Type, parent, = cdef_parent(env, cdef));
   if(GET_FLAG(cdef, global) && isa(parent, env->gwion->type[et_closure]) < 0 && !type_global(env, parent)) {
-    gwerr_basic(_("parent type is not global"), NULL, NULL, env->name, cdef->base.ext ? cdef->base.ext->pos : cdef->base.pos, 0);
+    gwerr_basic(_("parent type is not global"), NULL, NULL, env->name, cdef->base.ext ? cdef->base.ext->tag.loc : cdef->base.tag.loc, 0);
     declared_here(parent->info->value);
     env_set_error(env,  true);
     return NULL;
   }
-  if (cdef->traits) CHECK_BO(find_traits(env, cdef->traits, cdef->pos));
-  const Type t = new_type(env->gwion->mp, s_name(cdef->base.xid), parent);
+  if (cdef->traits) CHECK_BO(find_traits(env, cdef->traits, cdef->base.tag.loc));
+  const Type t = new_type(env->gwion->mp, s_name(cdef->base.tag.sym), parent);
   if (cflag(cdef, cflag_struct)) {
     t->size = 0;
     set_tflag(t, tflag_struct);
@@ -371,7 +370,7 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
 ANN static m_bool _spread_tmpl(const Env env, const Type t, const Spread_Def spread) {
   if(t->info->value->from->owner_class)
     CHECK_BB(_spread_tmpl(env, t->info->value->from->owner_class, spread));
-  const Tmpl *tmpl = t->info->cdef->base.tmpl;
+  const Tmpl *tmpl = get_tmpl(t);
   if(!tmpl || !tmpl->call) return GW_OK;
   if(is_spread_tmpl(tmpl))
     CHECK_BB(spread_ast(env, spread, tmpl));
@@ -394,7 +393,7 @@ ANN static bool spreadable(const Env env) {
     return true;
   Type t = env->class_def;
   while(t) {
-    const Tmpl *tmpl = t->info->cdef->base.tmpl;
+    const Tmpl *tmpl = get_tmpl(t);
     if(tmpl && is_spread_tmpl(tmpl))
       return true;
     t = t->info->value->from->owner_class;
@@ -426,7 +425,7 @@ ANN m_bool scan0_func_def(const Env env, const Func_Def fdef) {
   if(!fdef->base->tmpl || !fdef->base->tmpl->call) return GW_OK;
   if(env->context) {
     if(fdef->base->tmpl && fdef->base->tmpl->call && is_spread_tmpl(fdef->base->tmpl)) {
-    struct Func_ fake = {.name = s_name(fdef->base->xid), .def = fdef }, *const former =
+    struct Func_ fake = {.name = s_name(fdef->base->tag.sym), .def = fdef }, *const former =
                                                             env->func;
     env->func = &fake;
     if(!fdef->builtin && fdef->d.code)
@@ -448,7 +447,7 @@ ANN static m_bool scan0_extend_def(const Env env, const Extend_Def xdef) {
       if(!global) {
         const Trait trait = nspc_lookup_trait1(env->curr, xid);
         gwerr_basic("trait should be declared global", NULL, NULL, trait->filename, trait->loc, 0);
-        gwerr_secondary("from the request ", env->name, xdef->td->pos);
+        gwerr_secondary("from the request ", env->name, xdef->td->tag.loc);
         env_set_error(env, true);
       }
     }
@@ -458,13 +457,13 @@ ANN static m_bool scan0_extend_def(const Env env, const Extend_Def xdef) {
 }
 
 ANN static m_bool _scan0_trait_def(const Env env, const Trait_Def pdef) {
-  CHECK_BB(scan0_defined(env, pdef->xid, pdef->pos));
-  DECL_BB(const m_bool, global, = scan0_global(env, pdef->flag, pdef->pos));
-  const Trait trait = new_trait(env->gwion->mp, pdef->pos);
-  trait->loc        = pdef->pos;
-  trait->name       = s_name(pdef->xid);
+  CHECK_BB(scan0_defined(env, pdef->tag));
+  DECL_BB(const m_bool, global, = scan0_global(env, pdef->flag, pdef->tag.loc));
+  const Trait trait = new_trait(env->gwion->mp, pdef->tag.loc);
+  trait->loc    = pdef->tag.loc;
+  trait->name       = s_name(pdef->tag.sym);
   trait->filename   = env->name;
-  nspc_add_trait(env->curr, pdef->xid, trait);
+  nspc_add_trait(env->curr, pdef->tag.sym, trait);
   if(global) env_pop(env, 0);
   Ast ast = pdef->body;
   if(!ast) return GW_OK; // ???
@@ -474,7 +473,7 @@ ANN static m_bool _scan0_trait_def(const Env env, const Trait_Def pdef) {
       const Func_Def fdef = section->d.func_def;
       if (fdef->base->flag != ae_flag_none &&
           fdef->base->flag != (ae_flag_none | ae_flag_abstract))
-        ERR_B(fdef->base->pos, "Trait function must be declared without qualifiers");
+        ERR_B(fdef->base->tag.loc, "Trait function must be declared without qualifiers");
       if (!trait->fun) trait->fun = new_mp_vector(env->gwion->mp, Func_Def, 0);
       mp_vector_add(env->gwion->mp, &trait->fun, Func_Def, fdef);
     } else if (section->section_type == ae_section_stmt) {
@@ -485,33 +484,33 @@ ANN static m_bool _scan0_trait_def(const Env env, const Trait_Def pdef) {
         ERR_B(stmt->pos, "trait can only contains variable requests and functions");
       }
     } else
-        ERR_B(pdef->pos, "invalid section for trait definition");
+        ERR_B(pdef->tag.loc, "invalid section for trait definition");
   }
   return GW_OK;
 }
 
 ANN static m_bool scan0_trait_def(const Env env, const Trait_Def pdef) {
-  const Symbol s      = pdef->xid;
+  const Symbol s      = pdef->tag.sym;
   const Trait  exists = nspc_lookup_trait1(env->curr, s);
   if (exists) {
-    gwerr_basic("trait already defined", NULL, NULL, env->name, pdef->pos, 0);
+    gwerr_basic("trait already defined", NULL, NULL, env->name, pdef->tag.loc, 0);
     gwerr_secondary("defined here", env->name, exists->loc);
     env_set_error(env, true);
-    return already_defined(env, s, pdef->pos);
+    return already_defined(env, s, pdef->tag.loc);
   }
-  if (pdef->traits) CHECK_BB(find_traits(env, pdef->traits, pdef->pos));
+  if (pdef->traits) CHECK_BB(find_traits(env, pdef->traits, pdef->tag.loc));
   _scan0_trait_def(env, pdef);
   return GW_OK;
 }
 
 ANN m_bool scan0_prim_def(const Env env, const Prim_Def pdef) {
-  const loc_t loc = pdef->loc;
+  const loc_t loc = pdef->tag.loc;
   CHECK_BB(env_access(env, pdef->flag, loc));
-  CHECK_BB(scan0_defined(env, pdef->name, loc));
+  CHECK_BB(scan0_defined(env, pdef->tag));
   DECL_BB(const m_bool, global, = scan0_global(env, pdef->flag, loc));
-  const Type t = mk_primitive(env, s_name(pdef->name), pdef->size);
+  const Type t = mk_primitive(env, s_name(pdef->tag.sym), pdef->size);
   add_type(env, env->curr, t);
-  mk_class(env, t, pdef->loc);
+  mk_class(env, t, pdef->tag.loc);
   t->flag = pdef->flag;
   if(global) env_pop(env, 0);
   return GW_OK;
@@ -520,11 +519,11 @@ ANN m_bool scan0_prim_def(const Env env, const Prim_Def pdef) {
 HANDLE_SECTION_FUNC(scan0, m_bool, Env)
 
 ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
-  CHECK_BB(isres(env, cdef->base.xid, cdef->pos));
+  CHECK_BB(isres(env, cdef->base.tag));
   CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef)));
   cdef->base.type->info->traits = cdef->traits; // should we copy the traits?
   set_tflag(cdef->base.type, tflag_scan0);
-  (void)mk_class(env, cdef->base.type, cdef->pos);
+  (void)mk_class(env, cdef->base.type, cdef->base.tag.loc);
   add_type(env, cdef->base.type->info->value->from->owner, cdef->base.type);
   const m_bool ret = cdef->body ? env_body(env, cdef, scan0_section) : GW_OK;
   return ret;
@@ -533,7 +532,7 @@ ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
 ANN Ast spread_class(const Env env, const Ast body);
 
 ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
-  DECL_BB(const m_bool, global, = scan0_global(env, c->flag, c->pos));
+  DECL_BB(const m_bool, global, = scan0_global(env, c->flag, c->base.tag.loc));
   const Ast old_extend = env->context ? env->context->extend : NULL;
   const int       cpy  = tmpl_base(c->base.tmpl) || GET_FLAG(c, global);
   const Class_Def cdef = !cpy ? c : cpy_class_def(env->gwion->mp, c);
index 2eab1fe29ab17cddc85a73ea85a56d5c8b1b53ee..a3a3bd4bb2d88a57005c74afcaf62e4776ebbe65 100644 (file)
@@ -20,14 +20,15 @@ ANN static inline m_bool type_cyclic(const Env env, const Type t,
     Type parent = t;
     do {
       if (parent == owner)
-        ERR_B(td->pos, _("%s declared inside %s"), t->name, owner->name);
+        ERR_B(td->tag.loc, _("%s declared inside %s"), t->name, owner->name);
     } while ((parent = parent->info->parent));
   } while ((owner = owner->info->value->from->owner_class));
   return GW_OK;
 }
 
 ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
-  if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
+//  if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
+  if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_union)))
     return GW_OK;
   struct EnvSet es = {.env   = env,
                       .data  = env,
@@ -64,15 +65,15 @@ ANN static Type scan1_type(const Env env, Type_Decl *td) {
 ANN static Type void_type(const Env env, Type_Decl *td) {
   DECL_OO(const Type, type, = scan1_type(env, td));
   if (type->size) return type;
-  ERR_O(td->pos, _("cannot declare variables of size '0' (i.e. 'void')..."))
+  ERR_O(td->tag.loc, _("cannot declare variables of size '0' (i.e. 'void')..."))
 }
 
 ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl *decl) {
   if (decl->type) return decl->type;
-  DECL_OO(const Type, t, = void_type(env, decl->td));
-  if(env->class_def && type_global(env, env->class_def) && !check_global(env, t, decl->td->pos))
+  DECL_OO(const Type, t, = void_type(env, decl->var.td));
+  if(env->class_def && type_global(env, env->class_def) && !check_global(env, t, decl->var.td->tag.loc))
       return NULL;
-  if (decl->td->xid == insert_symbol("auto") && decl->type) return decl->type;
+  if (decl->var.td->tag.sym == insert_symbol("auto") && decl->type) return decl->type;
   if (GET_FLAG(t, private) && t->info->value->from->owner != env->curr)
     ERR_O(exp_self(decl)->pos, _("can't use private type %s"), t->name)
   if (GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0))
@@ -86,11 +87,11 @@ static inline m_bool scan1_defined(const Env env, const Var_Decl *var) {
   const Value v = ((!env->class_def || !GET_FLAG(env->class_def, final) ||
         env->scope->depth)
            ? nspc_lookup_value1
-           : nspc_lookup_value2)(env->curr, var->xid);
+           : nspc_lookup_value2)(env->curr, var->tag.sym);
   if(v && (!v->from->owner_class || isa(env->class_def, v->from->owner_class) > 0))
-    ERR_B(var->pos,
+    ERR_B(var->tag.loc,
           _("variable %s has already been defined in the same scope..."),
-          s_name(var->xid))
+          s_name(var->tag.sym))
   return GW_OK;
 }
 
@@ -105,30 +106,30 @@ ANN m_bool abstract_array(const Env env, const Array_Sub array) {
 }
 
 ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) {
-  const bool decl_ref = decl->td->array && !decl->td->array->exp;
-  Var_Decl *const vd = &decl->vd;
-  CHECK_BB(isres(env, vd->xid, exp_self(decl)->pos));
+  const bool decl_ref = decl->var.td->array && !decl->var.td->array->exp;
+  Var_Decl *const vd = &decl->var.vd;
+  CHECK_BB(isres(env, vd->tag));
   Type t = decl->type;
   CHECK_BB(scan1_defined(env, vd));
   const Type base = array_base_simple(t);
-  if(decl->td->array) {
-    if (!GET_FLAG(decl->td, late) && !decl->td->array->exp)
-      ERR_B(decl->td->pos, _("arrays with no expressions should be declared `late`"));
-    if (GET_FLAG(decl->td, late) && decl->td->array->exp)
-      ERR_B(decl->td->array->exp->pos, _("late array should have no size"));
-    if (!decl->args && GET_FLAG(base, abstract)) CHECK_BB(abstract_array(env, decl->td->array));
+  if(decl->var.td->array) {
+    if (!GET_FLAG(decl->var.td, late) && !decl->var.td->array->exp)
+      ERR_B(decl->var.td->tag.loc, _("arrays with no expressions should be declared `late`"));
+    if (GET_FLAG(decl->var.td, late) && decl->var.td->array->exp)
+      ERR_B(decl->var.td->array->exp->pos, _("late array should have no size"));
+    if (!decl->args && GET_FLAG(base, abstract)) CHECK_BB(abstract_array(env, decl->var.td->array));
   }
   const Value v = vd->value =
-      vd->value ?: new_value(env, t, s_name(vd->xid), vd->pos);
-  if (GET_FLAG(t, abstract) && !decl->args && !GET_FLAG(decl->td, late)) SET_FLAG(v, late);
+      vd->value ?: new_value(env, t, s_name(vd->tag.sym), vd->tag.loc);
+  if (GET_FLAG(t, abstract) && !decl->args && !GET_FLAG(decl->var.td, late)) SET_FLAG(v, late);
   v->type = t;
   if (decl_ref) SET_FLAG(v, late);
-  v->flag |= decl->td->flag;
+  v->flag |= decl->var.td->flag;
   if (!env->scope->depth) {
     valuefrom(env, v->from);
     if (env->class_def) {
       if (env->class_def->info->tuple) tuple_contains(env, v);
-      if (!GET_FLAG(decl->td, static)) {
+      if (!GET_FLAG(decl->var.td, static)) {
         set_vflag(v, vflag_member);
         if(tflag(t, tflag_release))
           set_tflag(env->class_def, tflag_release);
@@ -139,23 +140,23 @@ ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) {
           env->class_def->size += t->size;
         }
       }
-    } else if (GET_FLAG(decl->td, global))
+    } else if (GET_FLAG(decl->var.td, global))
       SET_FLAG(v, global);
     else if(env->context)
     set_vflag(v, vflag_fglobal); // file global
-  } else if (GET_FLAG(decl->td, global))
+  } else if (GET_FLAG(decl->var.td, global))
     SET_FLAG(v, global);
-  nspc_add_value(env->curr, vd->xid, v);
-  ((Exp_Decl *)decl)->type = decl->vd.value->type;
+  nspc_add_value(env->curr, vd->tag.sym, v);
+  ((Exp_Decl *)decl)->type = decl->var.vd.value->type;
   return GW_OK;
 }
 
 ANN m_bool scan1_exp_decl(const Env env, Exp_Decl *const decl) {
-  CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos));
+  CHECK_BB(env_storage(env, decl->var.td->flag, exp_self(decl)->pos));
   ((Exp_Decl *)decl)->type = scan1_exp_decl_type(env, (Exp_Decl *)decl);
   CHECK_OB(decl->type);
   if(decl->args) CHECK_BB(scan1_exp(env, decl->args));
-  const bool global = GET_FLAG(decl->td, global);
+  const bool global = GET_FLAG(decl->var.td, global);
   if (global) {
     if (env->context) env->context->global = true;
     if (!type_global(env, decl->type))
@@ -301,12 +302,12 @@ ANN static inline m_bool scan1_stmt_try(const restrict Env env,
 
 ANN static inline m_bool stmt_each_defined(const restrict Env env,
                                            const Stmt_Each    stmt) {
-  if (nspc_lookup_value1(env->curr, stmt->sym))
+  if (nspc_lookup_value1(env->curr, stmt->tag.sym))
     ERR_B(stmt_self(stmt)->pos, _("foreach value '%s' is already defined"),
-          s_name(stmt->sym))
-  if (stmt->idx && nspc_lookup_value1(env->curr, stmt->idx->sym))
-    ERR_B(stmt->idx->pos, _("foreach index '%s' is already defined"),
-          s_name(stmt->idx->sym))
+          s_name(stmt->tag.sym))
+  if (stmt->idx && nspc_lookup_value1(env->curr, stmt->idx->tag.sym))
+    ERR_B(stmt->idx->tag.loc, _("foreach index '%s' is already defined"),
+          s_name(stmt->idx->tag.sym))
   return GW_OK;
 }
 
@@ -320,25 +321,23 @@ ANN static inline m_bool shadow_err(const Env env, const Value v,
   return GW_ERROR;
 }
 
-ANN static inline m_bool shadow_arg(const Env env, const Symbol sym,
-                                    const loc_t loc) {
+ANN static inline m_bool shadow_arg(const Env env, const Tag tag) {
   Nspc nspc = env->curr;
   do {
-    const Value v = nspc_lookup_value0(nspc, sym);
+    const Value v = nspc_lookup_value0(nspc, tag.sym);
     if (v && !env->func->def->builtin) {
       const Type owner = v->from->owner_class;
       if (owner && env->class_def && isa(env->class_def, owner) < 0)
         continue;
-      return shadow_err(env, v, loc);
+      return shadow_err(env, v, tag.loc);
     }
   } while ((nspc = nspc->parent));
   return GW_OK;
 }
 
-ANN static inline m_bool shadow_var(const Env env, const Symbol sym,
-                                    const loc_t loc) {
-  const Value v = nspc_lookup_value1(env->curr, sym);
-  return !v ? GW_OK : shadow_err(env, v, loc);
+ANN static inline m_bool shadow_var(const Env env, const Tag tag){
+  const Value v = nspc_lookup_value1(env->curr, tag.sym);
+  return !v ? GW_OK : shadow_err(env, v, tag.loc);
 }
 
 #define describe_ret_nspc(name, type, prolog, exp)                             \
@@ -351,7 +350,7 @@ describe_ret_nspc(for, Stmt_For,, !(scan1_stmt(env, stmt->c1) < 0 ||
     scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
 describe_ret_nspc(each, Stmt_Each,, !(stmt_each_defined(env, stmt) < 0 || scan1_exp(env, stmt->exp) < 0 ||
     scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
-describe_ret_nspc(loop, Stmt_Loop,, !( (!stmt->idx ? GW_OK : shadow_var(env, stmt->idx->sym, stmt->idx->pos)) < 0 ||
+describe_ret_nspc(loop, Stmt_Loop,, !( (!stmt->idx ? GW_OK : shadow_var(env, stmt->idx->tag)) < 0 ||
     scan1_exp(env, stmt->cond) < 0 ||
     scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
 
@@ -400,11 +399,11 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
   m_int last = 0;
   for(uint32_t i = 0; i < list->len; i++) {
     EnumValue ev = *mp_vector_at(list, EnumValue, i);
-    const Value v = new_value(env, t, s_name(ev.xid), edef->pos);
+    const Value v = new_value(env, t, s_name(ev.tag.sym), ev.tag.loc);
     v->d.num = (ev.set ? ev.gwint.num : last);
     last = v->d.num + 1;
     valuefrom(env, v->from);
-    nspc_add_value(env->curr, ev.xid, v);
+    nspc_add_value(env->curr, ev.tag.sym, v);
     SET_FLAG(v, static | ae_flag_const);
     SET_ACCESS(edef, v)
     SET_ACCESS(edef, t)
@@ -415,28 +414,28 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
 }
 
 ANN static Value arg_value(const Env env, Arg *const arg) {
-  const Var_Decl *vd = &arg->var_decl;
+  const Var_Decl *vd = &arg->var.vd;
   const Value    v   = new_value(env, arg->type,
-                            vd->xid ? s_name(vd->xid) : (m_str) __func__, arg->var_decl.pos);
-  if (arg->td)
-    v->flag = arg->td->flag;
+                            vd->tag.sym ? s_name(vd->tag.sym) : (m_str) __func__, arg->var.vd.tag.loc);
+  if (arg->var.td)
+    v->flag = arg->var.td->flag;
   return v;
 }
 
 ANN static m_bool scan1_args(const Env env, Arg_List args) {
   for(uint32_t i = 0; i < args->len; i++) {
     Arg *arg = mp_vector_at(args, Arg, i);
-    Var_Decl *const vd = &arg->var_decl;
-    if (vd->xid) CHECK_BB(isres(env, vd->xid, vd->pos));
-    if (arg->td) {
-      SET_FLAG(arg->td, late);
-      CHECK_OB((arg->type = void_type(env, arg->td)));
+    Var_Decl *const vd = &arg->var.vd;
+    if (vd->tag.sym) CHECK_BB(isres(env, vd->tag));
+    if (arg->var.td) {
+      SET_FLAG(arg->var.td, late);
+      CHECK_OB((arg->type = void_type(env, arg->var.td)));
       if (GET_FLAG(env->func->def->base, global) && !type_global(env, arg->type))
-        ERR_B(arg->td->pos, "is not global");
-      UNSET_FLAG(arg->td, late);
+        ERR_B(arg->var.td->tag.loc, "is not global");
+      UNSET_FLAG(arg->var.td, late);
     }
     vd->value = arg_value(env, arg);
-    if (vd->xid) nspc_add_value(env->curr, vd->xid, vd->value);
+    if (vd->tag.sym) nspc_add_value(env->curr, vd->tag.sym, vd->value);
   }
   return GW_OK;
 }
@@ -445,14 +444,14 @@ ANN static Type scan1_noret(const Env env, const Func_Base *base) {
   assert(base->td);
   DECL_OO(const Type, t, = known_type(env, base->td));
   if (!tflag(t, tflag_noret)) return t;
-  ERR_O(base->pos, _("Can't use type `{+G}%s{0}` for return"), t->name);
+  ERR_O(base->tag.loc, _("Can't use type `{+G}%s{0}` for return"), t->name);
 }
 
 ANN static m_bool _scan1_fbase_tmpl(const Env env, Func_Base *base) {
   Specialized_List sl = base->tmpl->list;
   for(uint32_t i = 0; i < sl->len; i++) {
     Specialized *spec = mp_vector_at(sl, Specialized, i);
-    nspc_add_type(env->curr, spec->xid, env->gwion->type[et_auto]);
+    nspc_add_type(env->curr, spec->tag.sym, env->gwion->type[et_auto]);
   }
   CHECK_OB((base->ret_type = scan1_noret(env, base)));
   return GW_OK;
@@ -477,7 +476,7 @@ ANN static bool spec_acc_has(const MemPool mp, MP_Vector **acc, const Symbol xid
 ANN static bool find_op_template_type(const MemPool mp, const Symbol xid, const Specialized_List sl, MP_Vector **acc) {
   for(uint32_t i = 0; i < sl->len; i++) {
     Specialized *spec = mp_vector_at(sl, Specialized, i);
-    if (xid == spec->xid) {
+    if (xid == spec->tag.sym) {
       spec_acc_has(mp, acc, xid);
       return true;
     }
@@ -493,13 +492,13 @@ ANN static m_bool scan1_fdef_base_tmpl(const Env env, const Func_Def fdef) {
   MP_Vector *acc = new_mp_vector(env->gwion->mp, Symbol, 0);
   for(uint32_t i = 0; i < args->len; i++) {
     Arg *arg = mp_vector_at(args, Arg, i);
-    if (!arg->td->next) {
-      find_op_template_type(env->gwion->mp, arg->td->xid, sl, &acc);
+    if (!arg->var.td->next) {
+      find_op_template_type(env->gwion->mp, arg->var.td->tag.sym, sl, &acc);
     }
   }
   const uint32_t len = acc->len;
   free_mp_vector(env->gwion->mp, Symbol, acc);
-  if (len < sl->len) ERR_B(base->pos, "too many template types for operator");
+  if (len < sl->len) ERR_B(base->tag.loc, "too many template types for operator");
   if (!env->curr->operators)
   env->curr->operators = mp_calloc(env->gwion->mp, NspcOp);
   const Vector v = &env->curr->operators->tmpl;
@@ -519,7 +518,7 @@ ANN m_bool scan1_fptr_def(const Env env, const Fptr_Def fptr) {
 ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
   if (tdef->when) CHECK_BB(scan1_exp(env, tdef->when));
   if(tflag(tdef->type->info->parent, tflag_ref))
-    ERR_B(tdef->pos, "can't typedef a reference type");
+    ERR_B(tdef->tag.loc, "can't typedef a reference type");
   if (tflag(tdef->type, tflag_cdef))
     return scan1_class_def(env, tdef->type->info->cdef);
   return tdef->type->info->cdef ? scan1_cdef(env, tdef->type) : GW_OK;
@@ -528,22 +527,22 @@ ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
 ANN static inline m_bool scan1_union_def_inner_loop(const Env env,
                                                     Union_Def udef) {
   nspc_allocdata(env->gwion->mp, udef->type->nspc);
-  Union_List  l  = udef->l;
+  Variable_List  l  = udef->l;
   m_uint      sz = 0;
-  const Value v = new_value(env, env->gwion->type[et_int], "@index", udef->pos);
+  const Value v = new_value(env, env->gwion->type[et_int], "@index", udef->tag.loc);
   nspc_add_value_front(env->curr, insert_symbol("@index"), v);
   valuefrom(env, v->from);
   for(uint32_t i = 0; i < l->len; i++) {
-    Union_Member *um = mp_vector_at(l, Union_Member, i);
+    Variable *um = mp_vector_at(l, Variable, i);
     DECL_OB(const Type, t, = known_type(env, um->td));
-    if (nspc_lookup_value0(env->curr, um->vd.xid))
-      ERR_B(um->vd.pos, _("'%s' already declared in union"), s_name(um->vd.xid))
+    if (nspc_lookup_value0(env->curr, um->vd.tag.sym))
+      ERR_B(um->vd.tag.loc, _("'%s' already declared in union"), s_name(um->vd.tag.sym))
     if(tflag(t, tflag_ref))
-      ERR_B(um->vd.pos, _("can't declare ref type in union"));
-    const Value v = new_value(env, t, s_name(um->vd.xid), um->vd.pos);
+      ERR_B(um->vd.tag.loc, _("can't declare ref type in union"));
+    const Value v = new_value(env, t, s_name(um->vd.tag.sym), um->vd.tag.loc);
     tuple_contains(env, v);
     valuefrom(env, v->from);
-    nspc_add_value_front(env->curr, um->vd.xid, v);
+    nspc_add_value_front(env->curr, um->vd.tag.sym, v);
     if (t->size > sz) sz = t->size;
   }
   udef->type->nspc->offset = SZ_INT + sz;
@@ -635,11 +634,11 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) {
 ANN static m_bool class_internal(const Env env, const Func_Base *base) {
   assert(base->td);
   if (!env->class_def)
-    ERR_B(base->td->pos, _("'%s' must be in class def!!"), s_name(base->xid))
+    ERR_B(base->td->tag.loc, _("'%s' must be in class def!!"), s_name(base->tag.sym))
   if (base->args)
-    ERR_B(base->td->pos, _("'%s' must not have args"), s_name(base->xid))
+    ERR_B(base->td->tag.loc, _("'%s' must not have args"), s_name(base->tag.sym))
   if (base->ret_type != env->gwion->type[et_void])
-    ERR_B(base->td->pos, _("'%s' must return 'void'"), s_name(base->xid))
+    ERR_B(base->td->tag.loc, _("'%s' must return 'void'"), s_name(base->tag.sym))
   return GW_OK;
 }
 
@@ -647,8 +646,8 @@ ANN static inline m_bool scan_internal_arg(const Env        env,
                                            const Func_Base *base) {
   if (mp_vector_len(base->args) == 1) return GW_OK;
   assert(base->td);
-  ERR_B(base->td->pos, _("'%s' must have one (and only one) argument"),
-        s_name(base->xid))
+  ERR_B(base->td->tag.loc, _("'%s' must have one (and only one) argument"),
+        s_name(base->tag.sym))
 }
 
 ANN static inline m_bool scan_internal_int(const Env        env,
@@ -656,14 +655,14 @@ ANN static inline m_bool scan_internal_int(const Env        env,
   assert(base->td);
   CHECK_BB(scan_internal_arg(env, base));
   if (isa(base->ret_type, env->gwion->type[et_int]) > 0) return GW_OK;
-  ERR_B(base->td->pos, _("'%s' must return 'int'"), s_name(base->xid))
+  ERR_B(base->td->tag.loc, _("'%s' must return 'int'"), s_name(base->tag.sym))
 }
 
 ANN static m_bool scan_internal(const Env env, const Func_Base *base) {
-  const Symbol op = base->xid;
+  const Symbol op = base->tag.sym;
   if (op == insert_symbol("@dtor")) {
     if(safe_tflag(env->class_def, tflag_struct))
-      ERR_B(base->pos, "can't use '@dtor' for structures");
+      ERR_B(base->tag.loc, "can't use '@dtor' for structures");
     return class_internal(env, base);
   }
   if (op == insert_symbol("@gack"))
@@ -678,14 +677,14 @@ ANN static m_bool scan_internal(const Env env, const Func_Base *base) {
      op == insert_symbol("@each_init")  ||
      op == insert_symbol("@each_val")   ||
      op == insert_symbol("@partial"))
-      ERR_B(base->pos, "operator '%s' not allowed", s_name(op));
+      ERR_B(base->tag.loc, "operator '%s' not allowed", s_name(op));
   return GW_OK;
 }
 
 ANN static m_bool scan1_fdef_args(const Env env, Arg_List args) {
   for(uint32_t i = 0; i < args->len; i++) {
     Arg *arg = mp_vector_at(args, Arg, i);
-    CHECK_BB(shadow_arg(env, arg->var_decl.xid, arg->var_decl.pos));
+    CHECK_BB(shadow_arg(env, arg->var.vd.tag));
   }
   return GW_OK;
 }
@@ -716,40 +715,40 @@ ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) {
 
 ANN static inline m_bool scan1_fdef_defined(const Env      env,
                                             const Func_Def fdef) {
-  const Value v = nspc_lookup_value1(env->curr, fdef->base->xid);
+  const Value v = nspc_lookup_value1(env->curr, fdef->base->tag.sym);
   if (!v) return GW_OK;
   if (is_func(env->gwion, actual_type(env->gwion, v->type))) return GW_OK; // is_callable
   if(fdef->builtin) return GW_OK;
   if ((!env->class_def || !GET_FLAG(env->class_def, final)) &&
-      !nspc_lookup_value0(env->curr, fdef->base->xid))
-    ERR_B(fdef->base->pos,
+      !nspc_lookup_value0(env->curr, fdef->base->tag.sym))
+    ERR_B(fdef->base->tag.loc,
           _("function '%s' has already been defined in the same scope..."),
-          s_name(fdef->base->xid))
+          s_name(fdef->base->tag.sym));
   return GW_OK;
 }
 
 ANN static m_bool _scan1_func_def(const Env env, const Func_Def fdef) {
   if(GET_FLAG(fdef->base, abstract) && !env->class_def)
-    ERR_B(fdef->base->pos, "file scope function can't be abstract");
-  CHECK_BB(env_storage(env, fdef->base->flag, fdef->base->pos));
+    ERR_B(fdef->base->tag.loc, "file scope function can't be abstract");
+  CHECK_BB(env_storage(env, fdef->base->flag, fdef->base->tag.loc));
   CHECK_BB(scan1_fdef_defined(env, fdef));
   const bool   global = GET_FLAG(fdef->base, global);
   const m_uint scope  = !global ? env->scope->depth : env_push_global(env);
   if (tmpl_base(fdef->base->tmpl)) return scan1_fdef_base_tmpl(env, fdef);
-  struct Func_ fake = {.name = s_name(fdef->base->xid), .def = fdef }, *const former =
+  struct Func_ fake = {.name = s_name(fdef->base->tag.sym), .def = fdef }, *const former =
                                                              env->func;
   env->func = &fake;
   const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)scan1_fdef);
   env->func = former;
   if (global) env_pop(env, scope);
-  if ((strcmp(s_name(fdef->base->xid), "@implicit") || fbflag(fdef->base, fbflag_internal)) && !fdef->builtin && fdef->base->ret_type &&
+  if ((strcmp(s_name(fdef->base->tag.sym), "@implicit") || fbflag(fdef->base, fbflag_internal)) && !fdef->builtin && fdef->base->ret_type &&
        fdef->base->ret_type != env->gwion->type[et_void] && fdef->d.code &&
        !fake.memoize)
-     ERR_B(fdef->base->td->pos,
+     ERR_B(fdef->base->td->tag.loc,
            _("missing return statement in a non void function"));
-  if (fdef->base->xid == insert_symbol("@gack") && !fake.weight) {
+  if (fdef->base->tag.sym == insert_symbol("@gack") && !fake.weight) {
     gwerr_basic(_("`@gack` operator does not print anything"), NULL,
-      _("use `<<<` `>>>` in the function"), env->name, fdef->base->pos, 0);
+      _("use `<<<` `>>>` in the function"), env->name, fdef->base->tag.loc, 0);
     env_set_error(env,  true);
     return GW_ERROR;
   }
@@ -774,19 +773,20 @@ ANN static Type scan1_get_parent(const Env env, const Type_Def tdef) {
   Type t = parent;
   do
     if (tdef->type == t)
-      ERR_O(tdef->ext->pos, _("recursive (%s <= %s) class declaration."),
+      ERR_O(tdef->ext->tag.loc, _("recursive (%s <= %s) class declaration."),
             tdef->type->name, t->name)
   while ((t = t->info->parent));
   return parent;
 }
 
 ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
-  const loc_t pos = cdef->base.ext->pos;
+  const loc_t pos = cdef->base.ext->tag.loc;
   if (cdef->base.ext->array && cdef->base.ext->array->exp)
     CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp));
   DECL_OB(const Type, parent, = scan1_get_parent(env, &cdef->base));
   if (isa(parent, env->gwion->type[et_object]) < 0 &&
-      !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_udef)))
+//      !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_udef)))
+      !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_union)))
     ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name)
   if (type_ref(parent)) ERR_B(pos, _("can't use ref type in class extend"))
   return GW_OK;
@@ -795,7 +795,7 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
 ANN static inline Type scan1_final(const Env env, Type_Decl *td, const bool tdef) {
   DECL_OO(const Type, t, = known_type(env, td));
   if (!GET_FLAG(t, final) || tdef) return t;
-  ERR_O(td->pos, _("can't inherit from final parent class '%s'\n."), t->name);
+  ERR_O(td->tag.loc, _("can't inherit from final parent class '%s'\n."), t->name);
 }
 
 ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
@@ -824,9 +824,9 @@ ANN static m_bool scan1_class_def_body(const Env env, const Class_Def cdef) {
         }
       } else mp_vector_add(mp, &body, Section, section);
     }
-    Type_Decl *td = type2td(env->gwion, env->gwion->type[et_void], cdef->base.pos);
+    Type_Decl *td = type2td(env->gwion, env->gwion->type[et_void], cdef->base.tag.loc);
     Symbol sym = insert_symbol("@ctor");
-    Func_Base *fb = new_func_base(mp, td, sym, NULL, ae_flag_none, cdef->base.pos);
+    Func_Base *fb = new_func_base(mp, td, sym, NULL, ae_flag_none, cdef->base.tag.loc);
     Func_Def  fdef = new_func_def(mp, fb, ctor);
     mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef));
     free_mp_vector(mp, Section, base);
index 6d473406d10e39c41a2f3903661f84a292d0fa47..74bbffe5b4c7f8c4a95a1ad957fb0ef2676ffabf 100644 (file)
@@ -31,14 +31,14 @@ ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
 ANN static m_bool scan2_decl(const Env env, const Exp_Decl *decl) {
   const Type t = decl->type;
   CHECK_BB(ensure_scan2(env, t));
-  const Var_Decl vd   = decl->vd;
-  nspc_add_value(env->curr, vd.xid, vd.value);
+  const Var_Decl vd   = decl->var.vd;
+  nspc_add_value(env->curr, vd.tag.sym, vd.value);
   return GW_OK;
 }
 
 ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl *decl) {
   if(decl->args) CHECK_BB(scan2_exp(env, decl->args));
-  const bool   global = GET_FLAG(decl->td, global);
+  const bool   global = GET_FLAG(decl->var.td, global);
   const m_uint scope  = !global ? env->scope->depth : env_push_global(env);
   const m_bool ret    = scan2_decl(env, decl);
   if (global) env_pop(env, scope);
@@ -49,7 +49,7 @@ ANN static m_bool scan2_args(const Func_Def f) {
   Arg_List   args   = f->base->args;
   for(uint32_t i = 0; i < args->len; i++) {
     Arg *arg = mp_vector_at(args, Arg, i);
-    const Value v   = arg->var_decl.value;
+    const Value v   = arg->var.vd.value;
     v->from->offset = f->stack_depth;
     f->stack_depth += v->type->size;
     set_vflag(v, vflag_arg);
@@ -278,22 +278,22 @@ ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f,
                                           const Value overload) {
   if (!is_func(env->gwion, overload->type)) {
     if (!fbflag(f->base, fbflag_internal))
-      ERR_B(f->base->pos,
+      ERR_B(f->base->tag.loc,
             _("function name '%s' is already used by another value"),
             overload->name)
   }
   const Func obase = overload->d.func_ref;
   if (GET_FLAG(obase->def->base, final) && (!env->class_def || (obase->value_ref->from->owner_class != env->class_def))) {
-    env_err(env, f->base->pos, _("can't overload final function `{G}%s{0}`"), s_name(f->base->xid));
+    env_err(env, f->base->tag.loc, _("can't overload final function `{G}%s{0}`"), s_name(f->base->tag.sym));
     declared_here(obase->value_ref);
     return GW_ERROR;
   }
   const m_bool base = tmpl_base(f->base->tmpl);
   const m_bool tmpl = fflag(obase, fflag_tmpl);
   if ((!tmpl && base) || (tmpl && !base && !f->base->tmpl))
-    ERR_B(f->base->pos, _("must overload template function with template"))
+    ERR_B(f->base->tag.loc, _("must overload template function with template"))
   if (GET_FLAG(f->base, global) != GET_FLAG(obase->def->base, global))
-    ERR_B(f->base->pos, _("function is declared global")) // improve me
+    ERR_B(f->base->tag.loc, _("function is declared global")) // improve me
   return GW_OK;
 }
 
@@ -321,20 +321,20 @@ ANN static Type func_type(const Env env, const Func func) {
 ANN static void func_no_overload(const Env env, const Func f, const Value v) {
   const Type t = v->type;
   value_addref(v);
-  nspc_add_value_front(env->curr, f->def->base->xid, v);
+  nspc_add_value_front(env->curr, f->def->base->tag.sym, v);
 
   const Type newt  = type_copy(env->gwion->mp, t);
   t->info->parent  = newt;
-  newt->name       = s_name(f->def->base->xid);
+  newt->name       = s_name(f->def->base->tag.sym);
   newt->info->func = f;
-  nspc_add_type_front(env->curr, f->def->base->xid, newt);
+  nspc_add_type_front(env->curr, f->def->base->tag.sym, newt);
   newt->info->value = v;
 }
 
 ANN2(1, 2)
 static Value func_value(const Env env, const Func f, const Value overload) {
   const Type  t = func_type(env, f);
-  const Value v = t->info->value = new_value(env, t, t->name, f->def->base->pos);
+  const Value v = t->info->value = new_value(env, t, t->name, f->def->base->tag.loc);
   valuefrom(env, v->from);
   CHECK_OO(scan2_func_assign(env, f->def, f, v));
   if (!overload)
@@ -351,7 +351,7 @@ static Value func_value(const Env env, const Func f, const Value overload) {
 ANN2(1, 2)
 static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f,
                               const Value overload) {
-  const m_str name  = s_name(f->base->xid);
+  const m_str name  = s_name(f->base->tag.sym);
   const Func  func  = scan_new_func(env, f, name);
   const Value value = func_value(env, func, overload);
   set_fflag(func, fflag_tmpl);
@@ -362,7 +362,7 @@ static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f,
   Nspc nspc = env->curr;
   uint i    = 0;
   do {
-    const Value v = nspc_lookup_value0(nspc, f->base->xid);
+    const Value v = nspc_lookup_value0(nspc, f->base->tag.sym);
     if (v) {
       Func ff = v->d.func_ref;
       if (!ff) continue;
@@ -373,14 +373,14 @@ static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f,
         }
         if (compat_func(ff->def, f) > 0) {
           if (ff->value_ref->from->owner == env->curr)
-            ERR_B(f->base->pos,
+            ERR_B(f->base->tag.loc,
                   "template function '%s' already defined with those arguments "
                   "in this namespace",
                   name)
           const Symbol sym =
               func_symbol(env, env->curr->name, name, "template", ff->def->vt_index);
           nspc_add_value(env->curr, sym, value);
-          if (!overload) nspc_add_value(env->curr, f->base->xid, value);
+          if (!overload) nspc_add_value(env->curr, f->base->tag.sym, value);
           nspc_add_func(env->curr, sym, func);
           func->def->vt_index = ff->def->vt_index;
           return GW_OK;
@@ -392,17 +392,17 @@ static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f,
   const Symbol sym = func_symbol(env, env->curr->name, name, "template", i);
   nspc_add_value(env->curr, sym, value);
   nspc_add_func(env->curr, sym, func);
-  if (!overload) nspc_add_value(env->curr, f->base->xid, value);
+  if (!overload) nspc_add_value(env->curr, f->base->tag.sym, value);
   else func->def->vt_index = ++overload->from->offset;
   return GW_OK;
 }
 
 ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f) {
-  const m_str      str    = s_name(f->base->xid);
+  const m_str      str    = s_name(f->base->tag.sym);
   struct Op_Func   opfunc = {.ck = strcmp(str, "@implicit") ? 0
                                                             : opck_usr_implicit};
   struct Op_Import opi    = {.ret  = f->base->ret_type,
-                          .pos  = f->base->pos,
+                          .pos  = f->base->tag.loc,
                           .data = (uintptr_t)f->base->func,
                           .func = &opfunc};
   func_operator(f, &opi);
@@ -430,14 +430,14 @@ ANN static m_bool scan2_func_def_code(const Env env, const Func_Def f) {
 
 ANN static void scan2_func_def_flag(const Env env, const Func_Def f) {
   set_fflag(f->base->func, fflag_pure);
-  if (f->base->xid == insert_symbol("@dtor"))
+  if (f->base->tag.sym == insert_symbol("@dtor"))
     set_tflag(env->class_def, tflag_dtor);
 }
 
 
 ANN static m_str func_tmpl_name(const Env env, const Func_Def f) {
-  const m_str      name = s_name(f->base->xid);
-  m_str tmpl_name = tl2str(env->gwion, f->base->tmpl->call, f->base->pos); 
+  const m_str      name = s_name(f->base->tag.sym);
+  m_str tmpl_name = tl2str(env->gwion, f->base->tmpl->call, f->base->tag.loc);
   const Symbol sym = func_symbol(env, env->curr->name, name, tmpl_name,
                                  (m_uint)f->vt_index);
   return s_name(sym);
@@ -457,7 +457,7 @@ static Value func_create(const Env env, const Func_Def f, const Value overload,
 ANN2(1, 2)
 static m_str func_name(const Env env, const Func_Def f, const Value v) {
   if (!f->base->tmpl) {
-    const Symbol sym = func_symbol(env, env->curr->name, s_name(f->base->xid),
+    const Symbol sym = func_symbol(env, env->curr->name, s_name(f->base->tag.sym),
                                    NULL, v ? ++v->from->offset : 0);
     return s_name(sym);
   }
@@ -483,7 +483,7 @@ m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value overload) {
 
 //! use function from parent class as next.
 ANN static void upfunction(const Env env, const Func_Base *fb) {
-  const Value v = find_value(env->class_def->info->parent, fb->xid);
+  const Value v = find_value(env->class_def->info->parent, fb->tag.sym);
   if (!v) return;
   Func func = fb->func;
   while (func->next && func->next->value_ref->from->owner == env->curr)
@@ -492,7 +492,7 @@ ANN static void upfunction(const Env env, const Func_Base *fb) {
 }
 
 ANN m_bool scan2_fdef(const Env env, const Func_Def fdef) {
-  const Value overload = nspc_lookup_value2(env->curr, fdef->base->xid);
+  const Value overload = nspc_lookup_value2(env->curr, fdef->base->tag.sym);
   if (overload) CHECK_BB(scan2_func_def_overload(env, fdef, overload));
   CHECK_BB((!tmpl_base(fdef->base->tmpl) ? scan2_fdef_std : scan2_fdef_tmpl)(
       env, fdef, overload));
@@ -519,7 +519,7 @@ ANN m_bool _scan2_func_def(const Env env, const Func_Def fdef) {
     return GW_OK;
   if(is_new(fdef)) {
     if(!env->class_def)
-      ERR_B(fdef->base->pos, _("{G+}new{0} operator must be set inside {C+}class{0}"));
+      ERR_B(fdef->base->tag.loc, _("{G+}new{0} operator must be set inside {C+}class{0}"));
     SET_FLAG(env->class_def, abstract);
     if(!fdef->base->ret_type)
 //      fdef->base->ret_type = env->class_def;
index 923efdf305f49e0b8bd1107d34ff4722a5a96554..7e2321962204ae262d1e219226a809ad4b950948 100644 (file)
@@ -22,8 +22,8 @@ ANN m_bool spread_ast(const Env env, const Spread_Def spread, const Tmpl *tmpl)
     // 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, targ.d.td->pos);
-    sprintf(c, "%s=%s", s_name(spread->xid), type);
+    const m_str type = type2str(env->gwion, t, targ.d.td->tag.loc);
+    sprintf(c, "%s=%s", s_name(spread->tag.sym), type);
     free_mstr(env->gwion->mp, type);
     pparg_add(env->gwion->ppa, c);
     for(uint32_t j = 0; j < spread->list->len; j++) {
@@ -32,8 +32,8 @@ ANN m_bool spread_ast(const Env env, const Spread_Def spread, const Tmpl *tmpl)
       sprintf(c, "%s=%s%u", name, name, i);
       pparg_add(env->gwion->ppa, c);
     }
-    Ast ast = parse_pos(&arg, spread->pos);
-    pparg_rem(env->gwion->ppa, s_name(spread->xid));
+    Ast ast = parse_pos(&arg, spread->tag.loc.first);
+    pparg_rem(env->gwion->ppa, s_name(spread->tag.sym));
     for(uint32_t j = 0; j < spread->list->len;j++) {
       const Symbol sym = *mp_vector_at(spread->list, Symbol, j);
       m_str name = s_name(sym);
index c44a7977ca1bfc564e42b98ed259613f26dc78f6..bea9160a6f80edb2d90d2b091a9ad19d97f44ecf 100644 (file)
@@ -4,6 +4,7 @@
 #include "vm.h"
 #include "traverse.h"
 #include "template.h"
+#include "tmp_resolve.h"
 #include "vm.h"
 #include "parse.h"
 #include "gwion.h"
@@ -19,7 +20,7 @@ ANN static m_bool _push_types(const Env env, const Nspc nspc,
   Type_List        tl = tmpl->call;
   Specialized *spec = mp_vector_at(sl, Specialized, sl->len - 1);
 
-  const uint32_t len = strcmp(s_name(spec->xid), "...") ? sl->len : sl->len-1;
+  const uint32_t len = strcmp(s_name(spec->tag.sym), "...") ? sl->len : sl->len-1;
   if(!tl) return GW_OK;
   for(uint32_t i = 0; i < len; i++) {
     if (i >= tl->len) return GW_OK;
@@ -27,7 +28,7 @@ ANN static m_bool _push_types(const Env env, const Nspc nspc,
     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);
+    nspc_add_type(nspc, spec->tag.sym, t);
   };
   if(len != sl->len) return GW_OK;
   return tl->len == sl->len ? GW_OK : GW_ERROR;
@@ -50,9 +51,9 @@ ANN static m_bool push_types(const Env env, const Nspc nspc, const Tmpl *tmpl) {
 ANN static m_bool _template_push(const Env env, const Type t) {
   if (t->info->value->from->owner_class)
     CHECK_BB(template_push(env, t->info->value->from->owner_class));
-  if (tflag(t, tflag_tmpl))
-    return push_types(env, t->nspc, t->info->cdef->base.tmpl); // incorrect
-  return GW_OK;
+  return tflag(t, tflag_tmpl)
+     ? push_types(env, t->nspc, get_tmpl(t))
+     : GW_OK;
 }
 
 ANN m_bool template_push(const Env env, const Type t) {
@@ -61,24 +62,37 @@ ANN m_bool template_push(const Env env, const Type t) {
 }
 
 #include <ctype.h>
+ANN Exp td2exp(const MemPool mp, const Type_Decl *td);
 ANN void check_call(const Env env, const Tmpl *tmpl) {
   for(uint32_t i = 0; i < tmpl->call->len; i++) {
     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");
+//if(targ->type != tmplarg_td) exit(16);
+if(targ->type == tmplarg_td) {
+    if(spec && strcmp(s_name(spec->tag.sym), "...")) {
+if(unlikely(spec->td)) {
+if(targ->type == tmplarg_td) {
+targ->type = tmplarg_exp;
+const Exp exp = td2exp(env->gwion->mp, targ->d.td);
+targ->d.exp = exp;
+
+}
+}
+else      if(spec->tag.sym == targ->d.td->tag.sym) {
+        if (!nspc_lookup_type1(env->curr, spec->tag.sym))
+          targ->d.td->tag.sym = 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);
+           const Type t = nspc_lookup_type1(env->curr, spec->tag.sym);
+           Type_Decl *td = type2td(env->gwion, t, targ->d.td->tag.loc);
            free_type_decl(env->gwion->mp, targ->d.td);
            targ->d.td = td;
         }
-      }
+      } else { // normal case?r
+//exit(11 + !!spec->xid);
+   }
+}
     } else {
       //if(targ->type == tmplarg_td)
       //  targ->d.td->xid = insert_symbol("auto");
@@ -101,7 +115,7 @@ ANN Tmpl *mk_tmpl(const Env env, const Tmpl *tm, const Type_List types) {
 }
 
 static ANN Type scan_func(const Env env, const Type t, const Type_Decl *td) {
-  DECL_OO(const m_str, tl_name, = tl2str(env->gwion, td->types, td->pos));
+  DECL_OO(const m_str, tl_name, = tl2str(env->gwion, td->types, td->tag.loc));
   const Symbol sym = func_symbol(env, t->info->value->from->owner->name,
                                  t->info->func->name, tl_name, 0);
   free_mstr(env->gwion->mp, tl_name);
@@ -119,7 +133,7 @@ static ANN Type scan_func(const Env env, const Type t, const Type_Decl *td) {
   const Func_Def def  = cpy_func_def(env->gwion->mp, t->info->func->def);
   const Func     func = ret->info->func =
       new_func(env->gwion->mp, s_name(sym), def);
-  const Value value = new_value(env, ret, s_name(sym), def->base->pos);
+  const Value value = new_value(env, ret, s_name(sym), def->base->tag.loc);
   func->flag        = def->base->flag;
   if (vflag(t->info->func->value_ref, vflag_member))
     set_vflag(value, vflag_member);
@@ -141,7 +155,7 @@ static ANN Type scan_func(const Env env, const Type t, const Type_Decl *td) {
 static ANN Type maybe_func(const Env env, const Type t, const Type_Decl *td) {
   if (is_func(env->gwion, t) && t->info->func->def->base->tmpl) // is_callable needs type
     return scan_func(env, t, td);
-  ERR_O(td->pos,
+  ERR_O(td->tag.loc,
         _("type '%s' is not template. You should not provide template types"),
         t->name)
 }
@@ -149,51 +163,40 @@ static ANN Type maybe_func(const Env env, const Type t, const Type_Decl *td) {
 static ANN bool is_single_variadic(const MP_Vector *v) {
   if(v->len != 1) return false;
   const Specialized *spec = mp_vector_at(v, Specialized, 0);
-  return !strcmp(s_name(spec->xid), "...");
+  return !strcmp(s_name(spec->tag.sym), "...");
 }
 
-ANN2(1,2) static m_bool check_tmpl(const Env env, const Type_List tl, const Specialized_List sl, const loc_t pos, const bool is_spread) {
+ANN2(1,2) m_bool check_tmpl(const Env env, const Type_List tl, const Specialized_List sl, const loc_t pos, const bool is_spread) {
   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++) {
     TmplArg *arg = mp_vector_at(tl, TmplArg, i);
     Specialized *spec = mp_vector_at(sl, Specialized, i);
     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");
+       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);
+         if(t) {
+           arg->type = tmplarg_exp;
+           Exp e = new_exp_td(env->gwion->mp, base, base->tag.loc);
+           arg->d.exp = new_exp_dot(env->gwion->mp, e, last->tag.sym, base->tag.loc);
+           free_type_decl(env->gwion->mp, last);
+           i--;
+           continue;
+         }
+         next->next = last;
+       }
+      ERR_B(pos, "template type argument mismatch. expected %s",
+          spec->td ? "constant" : "type");
       }
 
       DECL_OB(const Type, t, = known_type(env, arg->d.td));
@@ -205,20 +208,15 @@ i--;continue;
         }
       }
     } else {
-        if(!spec->td) {
-          ERR_B(pos, "template const argument mismatch. expected %s",
-              spec->td ? "constant" : "type");
+      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");
+      CHECK_OB(check_exp(env, arg->d.exp));
+      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);
     }
   }
   return GW_OK;
@@ -227,15 +225,16 @@ if(isa(arg->d.exp->type,t) < 0)
 ANN static Type _scan_type(const Env env, const Type t, Type_Decl *td) {
   if (tflag(t, tflag_tmpl) && !is_func(env->gwion, t)) { // is_callable
     if (tflag(t, tflag_ntmpl) && !td->types) return t;
-    const bool single_variadic = is_single_variadic(t->info->cdef->base.tmpl->list);
+    Tmpl *tmpl = get_tmpl(t);
+    const bool single_variadic = is_single_variadic(tmpl->list);
     if(!td->types) {
-      const Type new_type = nspc_lookup_type1(env->curr, td->xid);
-      Type_Decl *new_td = type2td(env->gwion, new_type, td->pos);
+      const Type new_type = nspc_lookup_type1(env->curr, td->tag.sym);
+      Type_Decl *new_td = type2td(env->gwion, new_type, td->tag.loc);
       Type_Decl *d = new_td;
       while(d->next) d = d->next;
       if(!d->types) {
         if(!single_variadic)
-          ERR_O(td->pos, _("you must provide template types for type '%s'"), t->name);
+          ERR_O(td->tag.loc, _("you must provide template types for type '%s'"), t->name);
         d->types = new_mp_vector(env->gwion->mp, TmplArg, 0);
       }
       const Type ret = _scan_type(env, t, d);
@@ -244,14 +243,14 @@ ANN static Type _scan_type(const Env env, const Type t, Type_Decl *td) {
     }
     struct TemplateScan ts = {.t = t, .td = td};
     Type_List           tl = td->types;
-    Specialized_List    sl = t->info->cdef->base.tmpl
-        ? t->info->cdef->base.tmpl->list : NULL;
-    const bool is_spread = is_spread_tmpl(t->info->cdef->base.tmpl);
-    if(!single_variadic) CHECK_BO(check_tmpl(env, tl, sl, td->pos, is_spread));
+    Specialized_List    sl = tmpl
+        ? tmpl->list : NULL;
+    const bool is_spread = is_spread_tmpl(tmpl);
+    if(!single_variadic) CHECK_BO(check_tmpl(env, tl, sl, td->tag.loc, is_spread));
     struct Op_Import opi = {.op   = insert_symbol("class"),
                             .lhs  = t,
                             .data = (uintptr_t)&ts,
-                            .pos  = td->pos};
+                            .pos  = td->tag.loc};
     return op_check(env, &opi);
   } else if (td->types)
     return maybe_func(env, t, td);
@@ -266,7 +265,7 @@ ANN Type scan_type(const Env env, const Type t, Type_Decl *td) {
     const Type owner       = array_base_simple(maybe_array);
     td->next               = next;
     CHECK_OO(owner);
-    if (!owner->nspc) ERR_O(td->pos, "type '%s' has no namespace", owner->name)
+    if (!owner->nspc) ERR_O(td->tag.loc, "type '%s' has no namespace", owner->name)
     struct EnvSet es = {.env   = env,
                         .data  = env,
                         .scope = env->scope->depth,
index a95f1ed30a60ae2e14b8c6db345e2390c74ff107..c243598848a83af5df3e3e5da9957f60dee51236 100644 (file)
@@ -15,8 +15,7 @@ ANN static Type _option(const Env env, Type_Decl *td, const uint8_t n) {
   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};
+  Type_Decl         tmp = { .tag = MK_TAG(insert_symbol("Option"), td->tag.loc), .types = tl };
   const Type t = !(n - 1) ? known_type(env, &tmp) : _option(env, &tmp, n - 1);
   free_mp_vector(env->gwion->mp, TmplArg, tl);
   td->array = array;
@@ -35,7 +34,7 @@ ANN static Type _ref(const Env env, Type_Decl *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};
+  Type_Decl tmp = {.tag = MK_TAG(insert_symbol("Ref"), td->tag.loc), .types = tl};
   const Type t = known_type(env, &tmp);
   free_mp_vector(env->gwion->mp, TmplArg, tl);
   return t;
@@ -53,7 +52,7 @@ ANN static Symbol symname(const Env env, Func_Base *const base, bool *global) {
   text_init(&text, env->gwion->mp);
   text_add(&text, "(");
   DECL_OO(const Type, t, = known_type(env, base->td));
-  DECL_OO(const m_str, name, = type2str(env->gwion, t, base->td->pos));
+  DECL_OO(const m_str, name, = type2str(env->gwion, t, base->td->tag.loc));
   text_add(&text, name);
   free_mstr(env->gwion->mp, name);
        text_add(&text, "(");
@@ -62,8 +61,8 @@ ANN static Symbol symname(const Env env, Func_Base *const base, bool *global) {
     for(uint32_t i = 0; i < base->args->len; i++) {
       if(i) text_add(&text, ",");
       Arg *arg = mp_vector_at(base->args, Arg, i);
-      DECL_OO(const Type, t, = known_type(env, arg->td));
-      DECL_OO(const m_str, name, = type2str(env->gwion, t, arg->td->pos));
+      DECL_OO(const Type, t, = known_type(env, arg->var.td));
+      DECL_OO(const m_str, name, = type2str(env->gwion, t, arg->var.td->tag.loc));
       text_add(&text, name);
       free_mstr(env->gwion->mp, name);
       if(*global)
@@ -72,15 +71,15 @@ ANN static Symbol symname(const Env env, Func_Base *const base, bool *global) {
   }
   text_add(&text, ")");
   text_add(&text, ")");
-  base->xid = insert_symbol(text.str);
+  base->tag.sym = insert_symbol(text.str);
   text_release(&text);
-  return base->xid;
+  return base->tag.sym;
 }
 
 ANN static inline Type find(const Env env, Type_Decl *td) {
   if (!td->fptr) return find_type(env, td);
   bool global = false;
-  CHECK_OO((td->xid = symname(env, td->fptr->base, &global)));
+  CHECK_OO((td->tag.sym = symname(env, td->fptr->base, &global)));
   const Fptr_Def fptr = td->fptr;
   td->fptr = NULL;
   const Type exists = find_type(env, td);
@@ -109,7 +108,7 @@ ANN static Type resolve(const Env env, Type_Decl *td) {
   while (last->next) last = last->next;
   DECL_OO(const Type, base, = find(env, td));
   const Context ctx = base->info->value->from->ctx;
-  if (ctx && ctx->error) ERR_O(td->pos, _("type '%s' is invalid"), base->name)
+  if (ctx && ctx->error) ERR_O(td->tag.loc, _("type '%s' is invalid"), base->name)
   DECL_OO(const Type, type, = find1(env, base, td));
   DECL_OO(const Type, t,    = !td->ref ? type : ref(env, td));
   DECL_OO(const Type, ret,  = !td->option ? t : option(env, td));
@@ -118,7 +117,7 @@ ANN static Type resolve(const Env env, Type_Decl *td) {
 }
 
 ANN static inline void *type_unknown(const Env env, const Type_Decl *td) {
-  env_err(env, td->pos, _("unknown type '%s'"), s_name(td->xid));
+  env_err(env, td->tag.loc, _("unknown type '%s'"), s_name(td->tag.sym));
   return NULL;
 }
 
index 78a2259449e3c330c11b56c293c8d4f513ae7bf7..7bcede9c496f479f01cb9f2a7550570ba0517578 100644 (file)
@@ -2,8 +2,6 @@
 #include "gwion_ast.h"
 #include "gwion_env.h"
 #include "vm.h"
-#include "plug.h"
-#include "driver.h"
 #include "gwion.h"
 
 static DRVRUN(simple_driver_run) {
index d3b6ca2f1e66192959e3261c95896346f59d905e..64b3d840b46f1710593bccf5790973b364e62c8d 100644 (file)
@@ -1,4 +1,4 @@
-#! [contains] unknown type
+#! [contains] Invalid variable unknown_type
 fun void my_function:[A]() { <<< "test" >>>; }
 
 my_function:[unknown_type]();
index c560ebdc74ee8daf5bed99981499cb0c33579ec9..93e646096f13caeb54c8004f1f49ae937b320810 100644 (file)
@@ -1,3 +1,4 @@
+#! [contains] can't declare ref type in union
 union U {
   &int i;
 }
index 032cd6b88495fe32972733de36ebcfeb2bc46830..0ce3d07dfe7c0068802599b20735346127f4a0a6 100644 (file)
@@ -1,3 +1,3 @@
-operator int --- :[A,C] (A i, C j) { return i;}
+operator int --- :[A,C] (A i, C j) { var C  c; return i;}
 <<< 1 --- 2 >>>;
 <<< 2 --- 2 >>>;