]> Nishi Git Mirror - gwion.git/commitdiff
:art: Add template unions
authorfennecdjay <astor.jeremie@wanadoo.fr>
Thu, 23 May 2019 08:51:38 +0000 (10:51 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Thu, 23 May 2019 08:51:38 +0000 (10:51 +0200)
15 files changed:
ast
include/parse.h
src/emit/emit.c
src/lib/prim.c
src/oo/switch.c
src/oo/type.c
src/parse/check.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/scanx.c
src/parse/template.c
src/parse/type_decl.c
src/parse/type_utils.c
util

diff --git a/ast b/ast
index 2f8759c59db171ce3d4737c7912b3b57d1d6dec6..8072d3e7711680521b71fee4f8a9d41363a9f1ce 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 2f8759c59db171ce3d4737c7912b3b57d1d6dec6
+Subproject commit 8072d3e7711680521b71fee4f8a9d41363a9f1ce
index 42dbcd68fb777201fd6a45e9593f6d3e416e672d..0eee67712a5f8f0f879e532e2a0f0e78ff12bdcf 100644 (file)
@@ -79,4 +79,18 @@ static inline ANN m_bool env_ext(const Env env, const Class_Def cdef, const _exp
 
 ANN m_bool scanx_parent(const Type t, const _exp_func f, void *d);
 #define scanx_parent(a,b,c) scanx_parent(a, (_exp_func)b, c)
+
+
+ANN m_bool scanx_cdef(const Env, void *,const Class_Def,
+  const _exp_func f_cdef, const _exp_func f_union);
+
+#define xxx_cdef(prefix)                                                  \
+static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
+  return scanx_cdef(env, env, cdef,                                       \
+      (_exp_func)prefix##_class_def, (_exp_func)prefix##_stmt_union);     \
+}
+xxx_cdef(scan1)
+xxx_cdef(scan2)
+xxx_cdef(check)
+xxx_cdef(traverse)
 #endif
index c2dcb514781d75ef035de2655a2682989a380295..b1158112df51e482861b184a8dfad263e014f4c1 100644 (file)
@@ -607,10 +607,11 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_de
 }
 
 ANN static m_bool emit_class_def(const Emitter, const Class_Def);
+ANN static m_bool emit_cdef(const Emitter, const Class_Def);
 
 ANN static m_bool emit_parent_inner(const Emitter emit, const Class_Def cdef) {
-  CHECK_BB(traverse_class_def(emit->env, cdef))
-  return emit_class_def(emit, cdef);
+  CHECK_BB(traverse_cdef(emit->env, cdef))
+  return emit_cdef(emit, cdef);
 }
 
 ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) {
@@ -1378,6 +1379,8 @@ ANN static inline void union_allocdata(MemPool mp, const Stmt_Union stmt) {
 }
 
 ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) {
+  if(stmt->tmpl)
+    return GW_OK;
   Decl_List l = stmt->l;
   m_uint scope = emit->env->scope->depth;
   const m_bool global = GET_FLAG(stmt, global);
@@ -1724,6 +1727,11 @@ ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) {
   return scanx_parent(parent, emit_parent_inner, emit);
 }
 
+ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
+  return scanx_cdef(emit->env, emit, cdef,
+      (_exp_func)emit_class_def, (_exp_func)emit_stmt_union);
+}
+
 ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
   const Type type = cdef->base.type;
   const Nspc nspc = type->nspc;
index 629c75e1d2e489041201135466618fa194779602..e33e05c0897ebaaf6bcf1e210e825c9f5ed9dfaf 100644 (file)
@@ -12,6 +12,7 @@
 #include "emit.h"
 #include "operator.h"
 #include "driver.h"
+#include "traverse.h"
 #include "parse.h"
 
 #define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func)
index 11a5485c9032f3c176acdbf0961854ed3f2cdb65..888f12a0e4367b9ecc9d7592647f0fbeb709da1c 100644 (file)
@@ -11,6 +11,7 @@
 #include "type.h"
 #include "context.h"
 #include "nspc.h"
+#include "traverse.h"
 #include "parse.h"
 #include "switch.h"
 
index 2c6b0b2815dcc540f070cfe38817a0a141d4f0d9..2505fab7a4c8e9f8d38396e9b10e15a3fb2838da 100644 (file)
@@ -6,12 +6,25 @@
 #include "type.h"
 #include "nspc.h"
 #include "vm.h"
+#include "traverse.h"
 #include "parse.h"
 #include "gwion.h"
 
 ANN static void free_type(Type a, Gwion gwion) {
-  if(GET_FLAG(a, template))
+  if(GET_FLAG(a, template)) {
+    if(GET_FLAG(a, union)) {
+      if(a->e->def->stmt) {
+      if(GET_FLAG(a, pure))
+        free_decl_list(gwion->mp, a->e->def->list);
+      else {
+          UNSET_FLAG(&a->e->def->stmt->d.stmt_union, global);
+          free_stmt(gwion->mp, a->e->def->stmt);
+        }
+      }
+      a->e->def->stmt = NULL;
+    }
     free_class_def(gwion->mp, a->e->def);
+  }
   if(a->nspc)
     REM_REF(a->nspc, gwion);
   mp_free(gwion->mp, Type, a);
index 0c57604ef644ab97b441b5b919eac33fdd40da25..8ec65bec0dc2e1a3d853d0d1e1fb927890da26cf 100644 (file)
@@ -105,7 +105,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
       ERR_O(td_pos(decl->td), "can't infer type.");
   if(GET_FLAG(decl->type , template)) {
     if(!GET_FLAG(decl->type, check))
-      CHECK_BO(traverse_class_def(env, decl->type->e->def))
+      CHECK_BO(traverse_cdef(env, decl->type->e->def))
   }
   const m_bool global = GET_FLAG(decl->td, global);
   const m_uint scope = !global ? env->scope->depth : env_push_global(env);
@@ -943,6 +943,8 @@ ANN static m_bool check_stmt_jump(const Env env, const Stmt_Jump stmt) {
 }
 
 ANN m_bool check_stmt_union(const Env env, const Stmt_Union stmt) {
+  if(stmt->tmpl)
+    return GW_OK;
   if(stmt->xid) {
     if(env->class_def)
       (!GET_FLAG(stmt, static) ? decl_member : decl_static)(env->curr, stmt->value);
@@ -959,8 +961,9 @@ ANN m_bool check_stmt_union(const Env env, const Stmt_Union stmt) {
   do {
     CHECK_OB(check_exp(env, l->self))
     if(isa(l->self->type, t_object) > 0) {
-        if(!GET_FLAG(l->self->d.exp_decl.td, ref))
+        if(!GET_FLAG(l->self->d.exp_decl.td, ref) && !GET_FLAG(stmt->type, template))
       ERR_B(l->self->pos, "In union, Objects must be declared as reference (use '@')")
+      SET_FLAG(l->self->d.exp_decl.td, ref);
       Var_Decl_List list = l->self->d.exp_decl.list;
       do SET_FLAG(list->self->value, pure);
       while((list = list->next));
@@ -1157,7 +1160,8 @@ ANN static m_bool check_class_parent(const Env env, const Class_Def cdef) {
   const Type_Decl *td = cdef->base.ext;
   if(td->array)
     CHECK_BB(check_exp_array_subscripts(env, td->array->exp))
-  CHECK_BB(scanx_parent(parent, traverse_class_def, env))
+  if(parent->e->def)
+    CHECK_BB(scanx_parent(parent, traverse_class_def, env))
   if(GET_FLAG(parent, typedef))
     SET_FLAG(cdef->base.type, typedef);
   return GW_OK;
@@ -1176,7 +1180,7 @@ ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
   const Type type = cdef->base.type;
   if(type->e->parent == t_undefined) {
     type->e->parent = check_td(env, cdef->base.ext);
-    return traverse_class_def(env, cdef);
+    return traverse_cdef(env, cdef);
   }
   if(cdef->base.ext)
     CHECK_BB(env_ext(env, cdef, check_class_parent))
index 10ac806946f9c55351a3bfe70fe20d0e53939dd3..fc56c533c11b39f2a707cc406e9ba9e43a54312d 100644 (file)
@@ -8,9 +8,9 @@
 #include "func.h"
 #include "nspc.h"
 #include "vm.h"
-#include "parse.h"
 #include "traverse.h"
 #include "template.h"
+#include "parse.h"
 
 ANN static Value mk_class(const Env env, const Type base) {
   const Type t = type_copy(env->gwion->mp, t_class);
@@ -113,6 +113,8 @@ ANN static Type union_type(const Env env, const Nspc nspc, const Symbol s, const
 
 ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) {
   CHECK_BB(env_storage(env, stmt->flag, stmt_self(stmt)->pos))
+  const m_uint scope = !GET_FLAG(stmt, global) ? env->scope->depth :
+      env_push_global(env);
   if(stmt->xid) {
     CHECK_BB(scan0_defined(env, stmt->xid, stmt_self(stmt)->pos))
     const Nspc nspc = !GET_FLAG(stmt, global) ?
@@ -131,6 +133,7 @@ ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) {
     if(!stmt->type_xid)
       SET_FLAG(t, op);
   } else if(stmt->type_xid) {
+    CHECK_BB(scan0_defined(env, stmt->type_xid, stmt_self(stmt)->pos))
     const Nspc nspc = !GET_FLAG(stmt, global) ?
       env->curr : env->global_nspc;
     stmt->type = union_type(env, nspc, stmt->type_xid, 1);
@@ -144,8 +147,23 @@ ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) {
     stmt->value->owner = nspc;
     nspc_add_value(nspc, stmt->xid, stmt->value);
     SET_FLAG(stmt->value, checked | stmt->flag);
-
   }
+  if(stmt->tmpl) {
+    if(tmpl_base(stmt->tmpl)) {
+      const Class_Def cdef = new_class_def(env->gwion->mp, stmt->flag, stmt->type_xid,
+          NULL, (Class_Body)stmt->l, stmt_self(stmt)->pos);
+      stmt->type->e->def = cdef;
+      cdef->base.tmpl = stmt->tmpl;
+      cdef->base.type = stmt->type;
+      cdef->list = stmt->l;
+      SET_FLAG(stmt->type, pure);
+      SET_FLAG(stmt, template);
+      SET_FLAG(stmt->type, template);
+    }
+    SET_FLAG(stmt->type, union);
+  }
+  if(GET_FLAG(stmt, global))
+    env_pop(env, scope);
   return GW_OK;
 }
 
index 88ae8fca8b755132b20efd2f118bc16e5cebfdda..4fa0b6bec6e1663e53c76099ae22c5483166fd93 100644 (file)
@@ -5,11 +5,11 @@
 #include "type.h"
 #include "nspc.h"
 #include "value.h"
-#include "optim.h"
+#include "func.h"
 #include "vm.h"
-#include "parse.h"
 #include "traverse.h"
 #include "template.h"
+#include "parse.h"
 
 ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
 ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
@@ -35,15 +35,16 @@ ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) {
     ERR_O(exp_self(decl)->pos, "can't use protected type %s", t->name)
   if(env->class_def) {
     if(!env->scope->depth) {
-      if(!env->func && !GET_FLAG(decl->td, static))
-        SET_FLAG(decl->td, member);
       if(!GET_FLAG(decl->td, ref) && t == env->class_def)
         ERR_O(exp_self(decl)->pos, "...(note: object of type '%s' declared inside itself)", t->name)
+      if(!GET_FLAG(decl->td, static))
+        SET_FLAG(decl->td, member);
     }
   }
   decl->base = t->e->def;
   return decl->type = t;
 }
+
 ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
   CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
   Var_Decl_List list = decl->list;
@@ -53,10 +54,10 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
   const m_uint scope = !global ? env->scope->depth : env_push_global(env);
   const Nspc nspc = !global ? env->curr : env->global_nspc;
   do {
-    Type t = decl->type;
     const Var_Decl var = list->self;
-    const Value former = nspc_lookup_value0(env->curr, var->xid);
     CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
+    Type t = decl->type;
+    const Value former = nspc_lookup_value0(env->curr, var->xid);
     if(former && !decl->td->exp &&
         (!env->class_def || !(GET_FLAG(env->class_def, template) || GET_FLAG(env->class_def, scan1))))
       ERR_B(var->pos, "variable %s has already been defined in the same scope...",
@@ -65,17 +66,17 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
       if(var->array->exp) {
         if(GET_FLAG(decl->td, ref))
           ERR_B(td_pos(decl->td), "ref array must not have array expression.\n"
-            "e.g: int @my_array[];\nnot: int my_array[2];")
+            "e.g: int @my_array[];\nnot: @int my_array[2];")
         CHECK_BB(scan1_exp(env, var->array->exp))
       }
       t = array_type(env, decl->type, var->array->depth);
     }
-    const Value v = var->value = former ? former : new_value(env->gwion->mp, t, s_name(var->xid));
+    const Value v = var->value = former ?: new_value(env->gwion->mp, t, s_name(var->xid));
     nspc_add_value(nspc, var->xid, v);
     v->flag = decl->td->flag;
     if(var->array && !var->array->exp)
       SET_FLAG(v, ref);
-    if(!env->func && !env->scope->depth && !env->class_def)
+    if(!env->scope->depth && !env->class_def)
       SET_FLAG(v, global);
     v->type = t;
     v->d.ptr = var->addr;
@@ -137,9 +138,8 @@ ANN static m_bool scan1_exp_if(const Env env, const Exp_If* exp_if) {
 }
 
 ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary *unary) {
-  if((unary->op == op_spork || unary->op == op_fork) && unary->code) {
-    RET_NSPC(scan1_stmt(env, unary->code))
-  }
+  if((unary->op == op_spork || unary->op == op_fork) && unary->code)
+    { RET_NSPC(scan1_stmt(env, unary->code)) }
   return unary->exp ? scan1_exp(env, unary->exp) : GW_OK;
 }
 
@@ -168,9 +168,8 @@ describe_ret_nspc(if, Stmt_If,, !(scan1_exp(env, stmt->cond) < 0 ||
     (stmt->else_body && scan1_stmt(env, stmt->else_body) < 0)) ? 1 : -1)
 
 ANN static inline m_bool scan1_stmt_code(const Env env, const Stmt_Code stmt) {
-  if(stmt->stmt_list) {
-    RET_NSPC(scan1_stmt_list(env, stmt->stmt_list))
-  }
+  if(stmt->stmt_list)
+    { RET_NSPC(scan1_stmt_list(env, stmt->stmt_list)) }
   return GW_OK;
 }
 
@@ -201,7 +200,7 @@ ANN m_bool scan1_stmt_enum(const Env env, const Stmt_Enum stmt) {
   } while((list = list->next));
   return GW_OK;
 }
-#include "func.h"
+
 ANN static m_bool scan1_args(const Env env, Arg_List list) {
   do {
     const Var_Decl var = list->var_decl;
@@ -227,6 +226,8 @@ ANN m_bool scan1_stmt_type(const Env env, const Stmt_Type stmt) {
 }
 
 ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union stmt) {
+  if(stmt->tmpl)
+    return GW_OK;
   if(!stmt->value)
     CHECK_BB(scan0_stmt_union(env, stmt))
   Decl_List l = stmt->l;
@@ -288,19 +289,19 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) {
     CHECK_BB(env_storage(env, fdef->flag, td_pos(fdef->base->td)))
   if(tmpl_base(fdef->base->tmpl))
     return GW_OK;
+  if(GET_FLAG(fdef, dtor) && !env->class_def)
+    ERR_B(td_pos(fdef->base->td), "dtor must be in class def!!")
+  if(GET_FLAG(fdef, op) && env->class_def)
+    SET_FLAG(fdef, static);
   struct Func_ fake = { .name=s_name(fdef->base->xid) }, *const former = env->func;
   env->func = &fake;
   ++env->scope->depth;
-  if(GET_FLAG(fdef, dtor) && !env->class_def)
-    ERR_B(td_pos(fdef->base->td), "dtor must be in class def!!")
   if(fdef->base->td)
     CHECK_OB((fdef->base->ret_type = known_type(env, fdef->base->td)))
   if(fdef->base->args)
     CHECK_BB(scan1_args(env, fdef->base->args))
   if(!GET_FLAG(fdef, builtin))
     CHECK_BB(scan1_stmt_code(env, &fdef->d.code->d.stmt_code))
-  if(GET_FLAG(fdef, op) && env->class_def)
-    SET_FLAG(fdef, static);
   env->func = former;
   --env->scope->depth;
   return GW_OK;
@@ -315,14 +316,14 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent = known_type(env, cdef->base.ext);
   CHECK_OB(parent)
   Type t = parent;
-  while(t) {
+  do {
     if(cdef->base.type == t)
       ERR_B(pos, "recursive (%s <= %s) class declaration.", cdef->base.type->name, t->name);
-    t = t->e->parent;
-  }
+  } while((t = t->e->parent));
   if(isa(parent, t_object) < 0)
     ERR_B(pos, "cannot extend primitive type '%s'", parent->name)
-  CHECK_BB(scanx_parent(parent, scan1_class_def, env))
+  if(parent->e->def)
+    CHECK_BB(scanx_parent(parent, scan1_class_def, env))
   if(type_ref(parent))
     ERR_B(pos, "can't use ref type in class extend")
   return GW_OK;
index 254967f1bc8a8407629c6a8d4d8cf4f71b84ad33..bc4e999ec46ff967a27124062160e2b582ea18f5 100644 (file)
@@ -8,20 +8,19 @@
 #include "value.h"
 #include "func.h"
 #include "template.h"
+#include "traverse.h"
 #include "optim.h"
 #include "parse.h"
 #include "nspc.h"
 #include "operator.h"
 
-ANN /* static */ m_bool scan2_exp(const Env, const Exp);
+//ANN /* static */ m_bool scan2_exp(const Env, const Exp);
 ANN static m_bool scan2_stmt(const Env, const Stmt);
 ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
-extern ANN m_bool scan1_class_def(const Env, const Class_Def);
-ANN m_bool scan2_class_def(const Env, const Class_Def);
 
 ANN static m_bool scan2_exp_decl_template(const Env env, const Exp_Decl* decl) {
-  CHECK_BB(scan1_class_def(env, decl->type->e->def))
-  CHECK_BB(scan2_class_def(env, decl->type->e->def))
+  CHECK_BB(scan1_cdef(env, decl->type->e->def))
+  CHECK_BB(scan2_cdef(env, decl->type->e->def))
   return GW_OK;
 }
 
@@ -270,6 +269,8 @@ ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) {
 }
 
 ANN m_bool scan2_stmt_union(const Env env, const Stmt_Union stmt) {
+  if(stmt->tmpl)
+    return GW_OK;
   const m_uint scope = union_push(env, stmt);
   Decl_List l = stmt->l;
   do CHECK_BB(scan2_exp(env, l->self))
@@ -450,7 +451,7 @@ ANN static m_str func_tmpl_name(const Env env, const Func_Def f) {
     vector_add(&v, (vtype)t);
     tlen += strlen(t->name);
   } while((id = id->next) && ++tlen);
-  char tmpl_name[tlen + 1];
+  char tmpl_name[tlen + 2];
   m_str str = tmpl_name;
   for(m_uint i = 0; i < vector_size(&v); ++i) {
     const m_str s = ((Type)vector_at(&v, i))->name;
@@ -548,7 +549,8 @@ DECL_SECTION_FUNC(scan2)
 
 ANN static m_bool scan2_class_parent(const Env env, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent;
-  CHECK_BB(scanx_parent(parent, scan2_class_def, env))
+  if(parent->e->def)
+    CHECK_BB(scanx_parent(parent, scan2_cdef, env))
   if(cdef->base.ext->array)
     CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
   return GW_OK;
index e722b0869a7ca80b2b4ca9b4894f7f768133ffc7..492478fafbf904ea4ff76477bbadc5dd4e6939a1 100644 (file)
@@ -6,8 +6,9 @@
 #include "type.h"
 #include "nspc.h"
 #include "vm.h"
-#include "parse.h"
 #include "template.h"
+#include "traverse.h"
+#include "parse.h"
 
 ANN static inline m_bool _body(const Env e, Class_Body b, const _exp_func f) {
   do CHECK_BB(f(e, b->section))
@@ -24,10 +25,10 @@ ANN static inline m_bool tmpl_push(const Env env, const Tmpl* tmpl) {
 }
 
 ANN static inline m_int _push(const Env env, const Class_Def c) {
-  const m_uint scope = env_push_type(env, c->base.type);
-  if(c->base.tmpl && !tmpl_push(env, c->base.tmpl))
-    return GW_ERROR;
-  return scope;
+  const m_int scope = env_push_type(env, c->base.type);
+  CHECK_BB(scope)
+  return (!c->base.tmpl || tmpl_push(env, c->base.tmpl)) ?
+    scope : GW_ERROR;
 }
 
 ANN static inline void _pop(const Env e, const Class_Def c, const m_uint s) {
@@ -36,6 +37,7 @@ ANN static inline void _pop(const Env e, const Class_Def c, const m_uint s) {
   env_pop(e, s);
 }
 
+// TODO: 'v' should be 2° argument
 ANN m_bool
 scanx_body(const Env e, const Class_Def c, const _exp_func f, void* d) {
   const m_int scope = _push(e, c);
@@ -67,27 +69,18 @@ static inline Class_Def get_type_def(const Type t) {
 
 ANN m_bool
 scanx_parent(const Type t, const _exp_func f, void* d) {
+  if(t->e->parent == t_union)
+    return GW_OK;
   const Class_Def def = get_type_def(t);
   return def ? f(d, def) : GW_OK;
 }
-/*
-struct Parent_ {
-  void* ptr;
-  const Type t;
-  m_bool (*f)(void*, void*);
-  const ae_flag flag;
-};
-ANN m_bool scanx_parent_actual(void* ptr, const Type t, m_bool (*f)(void*, void*), const ae_flag flag) {
-  if(t->e->def && (t->flag & flag) != flag)
-    return f(ptr, t->e->def);
-  return GW_OK;
-}
 
-ANN m_bool scanx_parent(void* ptr, const Type t, m_bool (*f)(void*, void*), const ae_flag flag) {
-  if(t->array_depth)
-     CHECK_BB(f(ptr, array_base(t)))
-  else
-     CHECK_BB(f(ptr, t))
-  return GW_OK;
+ANN m_bool scanx_cdef(const Env env, void* opt, const Class_Def cdef,
+    const _exp_func f_cdef, const _exp_func f_union) {
+  if(cdef->base.type->e->parent !=  t_union)
+     return f_cdef(opt, cdef);
+  CHECK_BB(template_push_types(env, cdef->base.tmpl))
+  const m_bool ret = f_union(opt, &cdef->stmt->d.stmt_union);
+  nspc_pop_type(env->gwion->mp, env->curr);
+  return ret;
 }
-*/
index f2511a58604d148fcf166b95a6058fc41058b35b..5be9e0a341903c27d15beab29e92ae7ca75fc4a2 100644 (file)
@@ -6,6 +6,7 @@
 #include "env.h"
 #include "type.h"
 #include "nspc.h"
+#include "traverse.h"
 #include "template.h"
 #include "vm.h"
 #include "parse.h"
@@ -70,9 +71,10 @@ ANN static inline size_t tmpl_set(struct tmpl_info* info, const Type t) {
 
 ANN static size_t template_size(const Env env, struct tmpl_info* info) {
   ID_List base = info->cdef->base.tmpl->list;
+  Type_List call = info->call;
   size_t size = tmpl_set(info, info->cdef->base.type);
-  do size += tmpl_set(info, type_decl_resolve(env, info->call->td));
-  while((info->call = info->call->next) && (base = base->next) && ++size);
+  do size += tmpl_set(info, type_decl_resolve(env, call->td));
+  while((call = call->next) && (base = base->next) && ++size);
   return size + 16 + 3;
 }
 
@@ -82,7 +84,7 @@ ANN static inline m_str tmpl_get(struct tmpl_info* info, m_str str) {
   return str += vector_at(&info->size, info->index);
 }
 
-ANN static void template_name(const Env env, struct tmpl_info* info, m_str s) {
+ANN static void template_name(struct tmpl_info* info, m_str s) {
   m_str str = s;
   str = tmpl_get(info, str);
   *str++ = '<';
@@ -91,10 +93,7 @@ ANN static void template_name(const Env env, struct tmpl_info* info, m_str s) {
     str = tmpl_get(info, str);
     *str++ = (info->index < size - 1) ? ',' : '>';
    }
-  if(info->cdef->base.type->e->owner == env->global_nspc)
-    sprintf(str, "%p", (void*)env->curr);
-  else
-    *str = '\0';
+   *str = '\0';
 }
 
 ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_List call) {
@@ -102,7 +101,7 @@ ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_
   vector_init(&info.type);
   vector_init(&info.size);
   char name[template_size(env, &info)];
-  template_name(env, &info, name);
+  template_name(&info, name);
   vector_release(&info.type);
   vector_release(&info.size);
   return insert_symbol(name);
@@ -158,13 +157,21 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) {
       return a->base.type;
     a->base.tmpl = new_tmpl(env->gwion->mp, get_total_type_list(env, t), 0);
     a->base.tmpl->call = type->types;
-
-    CHECK_BO(scan0_class_def(env, a))
+    if(isa(t, t_union) < 0)
+      CHECK_BO(scan0_class_def(env, a))
+    else {
+      a->stmt = new_stmt_union(env->gwion->mp, (Decl_List)a->body, t->e->def->pos);
+      a->stmt->d.stmt_union.type_xid = a->base.xid;
+      CHECK_BO(scan0_stmt_union(env, &a->stmt->d.stmt_union))
+      a->base.type = a->stmt->d.stmt_union.type;
+      a->base.type->e->def = a;
+      SET_FLAG(a, union);
+    }
     SET_FLAG(a->base.type, template | ae_flag_ref);
     a->base.type->e->owner = t->e->owner;
     if(GET_FLAG(t, builtin))
       SET_FLAG(a->base.type, builtin);
-    CHECK_BO(scan1_class_def(env, a))
+    CHECK_BO(scan1_cdef(env, a))
     if(t->nspc->dtor) {
       a->base.type->nspc->dtor = t->nspc->dtor;
       SET_FLAG(a->base.type, dtor);
index b320346d4e12e081e2fc9ac2a37c060acc4a0e5a..bc1d4d9db3afab34a4a9a6ec9ddded0901aa8ad2 100644 (file)
@@ -7,6 +7,7 @@
 #include "nspc.h"
 #include "type.h"
 #include "vm.h"
+#include "traverse.h"
 #include "parse.h"
 
 ANN Type type_decl_resolve(const Env env, const Type_Decl* td) {
index d0aa6b3e6e9358f15bdd0b59f188b709c759e8dc..d27414a8dd91d0f36f28ddfe3e4d7f51ab43faf5 100644 (file)
@@ -7,6 +7,7 @@
 #include "value.h"
 #include "type.h"
 #include "vm.h"
+#include "traverse.h"
 #include "parse.h"
 
 ANN m_bool isres(const Env env, const Symbol xid, const loc_t pos) {
diff --git a/util b/util
index 6e10d0bd6a9e6731e35cc01d44562e0271755676..e2cb40dfde5fe6200e3d14954aec316de1883136 160000 (submodule)
--- a/util
+++ b/util
@@ -1 +1 @@
-Subproject commit 6e10d0bd6a9e6731e35cc01d44562e0271755676
+Subproject commit e2cb40dfde5fe6200e3d14954aec316de1883136