]> Nishi Git Mirror - gwion.git/commitdiff
:art: Simplify unions
authorJérémie Astor <fennecdjay@gmail.com>
Sat, 12 Dec 2020 21:44:03 +0000 (22:44 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Sat, 12 Dec 2020 21:44:45 +0000 (22:44 +0100)
30 files changed:
ast
include/clean.h
include/emit.h
include/import/checker.h
include/import/udef.h
src/clean.c
src/emit/emit.c
src/import/import_udef.c
src/lib/engine.c
src/lib/object_op.c
src/parse/check.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
tests/error/union.gw
tests/error/union_array_empty.gw
tests/error/union_global_private.gw
tests/error/union_global_private_static.gw
tests/error/union_global_static.gw
tests/error/union_unknown.gw
tests/plug/array_in_var_name_fail.c
tests/plug/union.c
tests/plug/union_fail_exp.c
tests/plug/union_member.c
tests/plug/union_name.c
tests/plug/union_tmpl.c
tests/plug/union_tmpl_fail.c
tests/plug/union_tmpl_fail2.c
tests/plug/union_tmpl_fail3.c
tests/xxxfix/post_func.gw

diff --git a/ast b/ast
index bb94d2722c601b3a767dbe1149925a3c09b8cca6..28c10a9ae4b3e704a5a570c94726ef8b0ba612fa 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit bb94d2722c601b3a767dbe1149925a3c09b8cca6
+Subproject commit 28c10a9ae4b3e704a5a570c94726ef8b0ba612fa
index 449a046823c712aae7d0ba05511b4240e15493a8..d77408f1ca62728940945122c9d607fd1bf9f2c4 100644 (file)
@@ -44,7 +44,6 @@ ANN static void clean_stmt_match(Clean *a, Stmt_Match b);
 ANN static void clean_stmt_case(Clean *a, Stmt_Match b);
 ANN static void clean_stmt(Clean *a, Stmt b);
 ANN static void clean_arg_list(Clean *a, Arg_List b);
-ANN static void clean_decl_list(Clean *a, Decl_List b);
 ANN static void clean_stmt_list(Clean *a, Stmt_List b);
 ANN static void clean_func_base(Clean *a, Func_Base *b);
 ANN static void clean_func_def(Clean *a, Func_Def b);
index 868b528909bb7eabec089923ca68aed0f6f8c936..272ac97e03fb16a218d28a11877faa7f5d5502e6 100644 (file)
@@ -39,7 +39,6 @@ ANN2(1) Instr emit_add_instr(const Emitter, const f_instr) __attribute__((return
 ANN Code* emit_class_code(const Emitter, const m_str);
 ANN m_bool emit_array_extend(const Emitter, const Type, const Exp);
 ANN void emit_class_finish(const Emitter, const Nspc);
-ANN void emit_union_offset(Decl_List, const m_uint);
 ANN2(1,2) m_bool emit_instantiate_object(const Emitter, const Type, const Array_Sub, const m_bool);
 ANN m_uint emit_code_offset(const Emitter emit);
 ANN m_uint emit_local(const Emitter emit, const Type t);
index 3221164c98a316a28a61eddbca00156314cb0b6c..69a357ddf77865914b31b7d23e368e1dfa82d499 100644 (file)
@@ -22,7 +22,7 @@ typedef struct ImportCK { // name_checker ?
     f_xfun addr;
   };
   union {
-    Decl_List list;// union
+    Type_List list;// union
     struct Vector_ v;
 //    ID_List curr;// enum
   };
index dc25503cf445b8bca7589e50c0fd3da9787e32e7..a11c1f1035ee0535a46e2f15a78987c81e653979 100644 (file)
@@ -2,7 +2,7 @@
 #define __IMPORT_UNION
 
 ANN2(1) m_int gwi_union_ini(const Gwi gwi, const m_str name);
-ANN m_int gwi_union_add(const Gwi gwi, const __restrict__ m_str type, const __restrict__ m_str name);
+ANN m_int gwi_union_add(const Gwi gwi, const __restrict__ m_str type);
 ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag);
 ANN void ck_clean_udef(MemPool, ImportCK*);
 
index 5d64b36ed5afb756e770be09597c91b7ce6dd6ca..bee2b1d71843b1cb439905648bb5849e42066316 100644 (file)
@@ -133,6 +133,10 @@ ANN static void clean_exp_lambda(Clean *a, Exp_Lambda *b) {
   clean_func_def(a, b->def);
 }
 
+ANN static void clean_exp_td(Clean *a, Type_Decl **b) {
+  clean_type_decl(a, *b);
+}
+
 DECL_EXP_FUNC(clean, void, Clean*)
 ANN static void clean_exp(Clean *a, Exp b) {
   clean_exp_func[b->exp_type](a, &b->d);
@@ -254,12 +258,6 @@ ANN static void clean_arg_list(Clean *a, Arg_List b) {
     clean_arg_list(a, b->next);
 }
 
-ANN static void clean_decl_list(Clean *a, Decl_List b) {
-  clean_exp(a, b->self);
-  if(b->next)
-    clean_decl_list(a, b->next);
-}
-
 ANN static void clean_stmt_list(Clean *a, Stmt_List b) {
   clean_stmt(a, b->stmt);
   if(b->next)
@@ -308,7 +306,7 @@ ANN static void clean_enum_def(Clean *a, Enum_Def b) {
 }
 
 ANN static void clean_union_def(Clean *a, Union_Def b) {
-  clean_decl_list(a, b->l);
+  clean_type_list(a, b->l);
   if(b->tmpl)
     clean_tmpl(a, b->tmpl);
 }
index 087cd29dccfc9c949522f52ef3369b759988c180..bd5858002394fab6bd44898b1ee7cde6873dbc7c 100644 (file)
@@ -1432,6 +1432,11 @@ ANN static m_bool emit_exp_lambda(const Emitter emit, const Exp_Lambda * lambda)
   return ret;
 }
 
+ANN static m_bool emit_exp_td(const Emitter emit, Type_Decl* td) {
+  regpushi(emit, (m_uint)exp_self(td)->info->type->info->base_type);
+  return GW_OK;
+}
+
 DECL_EXP_FUNC(emit, m_bool, Emitter)
 
 
index f49fb534b638164f4de0dd2d680ec8f910cc4ddd..af9be60cfd4393f4e5343a0b3d8ce24374317bc7 100644 (file)
@@ -31,11 +31,10 @@ ANN m_int gwi_union_ini(const Gwi gwi, const m_str name) {
   return GW_OK;
 }
 
-ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type, const restrict m_str name) {
+ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type) {
   CHECK_BB(ck_ok(gwi, ck_udef))
-  DECL_OB(const Exp, exp, = make_exp(gwi, type, name))
-  SET_FLAG(exp->d.exp_decl.td, ref); // might not be needed
-  gwi->ck->list = new_decl_list(gwi->gwion->mp, exp, gwi->ck->list);
+  DECL_OB(Type_Decl*, td, = str2decl(gwi->gwion, type, gwi->loc))
+  gwi->ck->list = new_type_list(gwi->gwion->mp, td, gwi->ck->list);
   return GW_OK;
 }
 
@@ -74,7 +73,7 @@ ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) {
 
 ANN void ck_clean_udef(MemPool mp, ImportCK* ck) {
   if(ck->list)
-    free_decl_list(mp, ck->list);
+    free_type_list(mp, ck->list);
   if(ck->tmpl)
     free_id_list(mp, ck->tmpl);
 }
index 6e4f824580e64fca493d9c7444bc488ac6f6eb47..76b70b949cdf5ea4179b27a4ff6047070d9e3e77 100644 (file)
 #include "gack.h"
 
 #undef insert_symbol
+static GACK(gack_none) {
+  INTERP_PRINTF("None")
+}
+
 static GACK(gack_class) {
   const Type type = actual_type(shred->info->vm->gwion, t) ?: t;
   INTERP_PRINTF("class(%s)", type->name)
@@ -77,55 +81,127 @@ static OP_CHECK(opck_basic_ctor) {
   ERR_N(exp_self(call)->pos, _("can't call a non-callable value"))
 }
 
-static OP_CHECK(opck_dot_union) {
-  Exp_Dot *dot = (Exp_Dot*)data;
-  const Value v = nspc_lookup_value0(dot->t_base->nspc, dot->xid);
-  if(!v)
-    ERR_N(exp_self(dot)->pos, _("'%s' is not legit in '%s'\n"), s_name(dot->xid), dot->t_base->name)
-  return v->type;
+static OP_CHECK(opck_any_at_union) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  CHECK_NN(opck_rassign(env, data, mut)) // check those two lines
+  exp_setvar(bin->rhs, 0);
+  const Type lhs = bin->lhs->info->type;
+  const Nspc nspc = bin->rhs->info->type->nspc;
+  for(m_uint i = 0; i < nspc->info->class_data_size; i += SZ_INT) {
+    if(lhs == *(Type*)(nspc->info->class_data + i))
+      return lhs;
+  }
+  return env->gwion->type[et_error]; // err_msg
 }
 
 static INSTR(UnionSet) {
-  const M_Object o = *(M_Object*)REG(-SZ_INT);
+  POP_REG(shred, SZ_INT);
+  const M_Object o = *(M_Object*)REG(0);
   *(m_uint*)(o->data) = instr->m_val2;
-  memset(o->data + SZ_INT, 0, instr->m_val); // needed only for object!
-  *(void**)REG(-instr->m_val) = &*(m_bit**)(o->data + SZ_INT);
+  memcpy(o->data + SZ_INT, REG(-instr->m_val), instr->m_val);
+}
+
+static OP_EMIT(opem_any_at_union) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  const Type lhs = bin->lhs->info->type;
+  const Nspc nspc = bin->rhs->info->type->nspc;
+  const Instr instr = emit_add_instr(emit, UnionSet);
+  for(m_uint i = 0; i < nspc->info->class_data_size; i += SZ_INT) {
+    if(lhs == *(Type*)(nspc->info->class_data + i)) {
+      instr->m_val2 = i + 1;
+      instr->m_val = lhs->size;
+      return instr;
+    }
+  }
+  return NULL;
+}
+
+static OP_CHECK(opck_union_at_any) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  CHECK_NN(opck_rassign(env, data, mut)) // check those two lines
+  const Type rhs = bin->rhs->info->type;
+  const Nspc nspc = bin->lhs->info->type->nspc;
+  for(m_uint i = 0; i < nspc->info->class_data_size; i += SZ_INT) {
+    if(rhs == *(Type*)(nspc->info->class_data + i))
+      return rhs;
+  }
+  return env->gwion->type[et_error]; // err_msg
 }
 
 static INSTR(UnionGet) {
-  const M_Object o = *(M_Object*)REG(-SZ_INT);
+  const M_Object o = *(M_Object*)REG(-SZ_INT*2);
   if(*(m_uint*)(o->data) != instr->m_val2)
     Except(shred, "invalid union access");
-  POP_REG(shred, SZ_INT - instr->m_val);
+  memcpy(*(m_bit**)REG(-SZ_INT), o->data + SZ_INT, instr->m_val);
+  POP_REG(shred, SZ_INT*2 - instr->m_val);
   memcpy(REG(-instr->m_val), o->data + SZ_INT, instr->m_val);
 }
-MFUN(union_is);
-static OP_EMIT(opem_dot_union) {
-  Exp_Dot *dot = (Exp_Dot*)data;
-  CHECK_BO(emit_exp(emit, dot->base))
-  if(isa(exp_self(dot)->info->type, emit->gwion->type[et_function]) > 0) {
-    const Func f = (Func)vector_at(&dot->t_base->nspc->info->vtable, 0);
-    const Instr instr = emit_add_instr(emit, RegPushImm);
-    instr->m_val = (m_uint)f->code;
-    return instr;
+
+static OP_EMIT(opem_union_at_any) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  const Type rhs = bin->rhs->info->type;
+  const Nspc nspc = bin->lhs->info->type->nspc;
+  const Instr instr = emit_add_instr(emit, UnionGet);
+  for(m_uint i = 0; i < nspc->info->class_data_size; i += SZ_INT) {
+    if(rhs == *(Type*)(nspc->info->class_data + i)) {
+      instr->m_val2 = i + 1;
+      instr->m_val = rhs->size;
+      return instr;
+    }
+  }
+  return NULL;
+}
+
+static OP_CHECK(opck_union_eq_class) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  const Type rhs = bin->rhs->info->type->info->base_type;
+  const Nspc nspc = bin->lhs->info->type->nspc;
+  for(m_uint i = 0; i < nspc->info->class_data_size; i += SZ_INT) {
+    if(rhs == *(Type*)(nspc->info->class_data + i))
+      return env->gwion->type[et_bool];
   }
-  const uint emit_var = exp_getvar(exp_self(dot));
-  const Value v = nspc_lookup_value0(dot->t_base->nspc, dot->xid);
-  const Instr instr = emit_add_instr(emit, !emit_var ? UnionGet : UnionSet);
-  instr->m_val = !emit_var ? v->type->size : SZ_INT;
-  instr->m_val2 = v->from->offset;
-  return instr;
+  return NULL; // err_msg
+}
+
+static INSTR(UnionEqClass) {
+  POP_REG(shred, SZ_INT);
+  const M_Object o = *(M_Object*)REG(-SZ_INT);
+  *(m_uint*)REG(-SZ_INT) = *(m_uint*)(o->data) == instr->m_val2;
+
+}
+
+static OP_EMIT(opem_union_eq_class) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  const Type rhs = bin->rhs->info->type->info->base_type;
+  const Nspc nspc = bin->lhs->info->type->nspc;
+  const Instr instr = emit_add_instr(emit, UnionEqClass);
+  for(m_uint i = 0; i < nspc->info->class_data_size; i += SZ_INT) {
+    if(rhs == *(Type*)(nspc->info->class_data + i)) {
+      instr->m_val2 = i + 1;
+      return instr;
+    }
+  }
+  return NULL;
 }
 
 DTOR(UnionDtor) {
   const m_uint idx = *(m_uint*)o->data;
   if(idx) {
-    const Type t = (Type)vector_at(&o->type_ref->info->tuple->contains, idx - 1);
+    const Type t = *(Type*)(o->type_ref->nspc->info->class_data + idx * SZ_INT);
     if(isa(t, shred->info->vm->gwion->type[et_compound]) > 0)
       compound_release(shred, t, *(m_bit**)(o->data + SZ_INT));
   }
 }
 
+static ID_CHECK(idck_none) {
+  struct loc_t_ loc = {};
+  return str2type(env->gwion, "None", &loc);
+}
+
+static ID_EMIT(idem_none) {
+  return (Instr)1;
+}
+
 ANN static m_bool import_core_libs(const Gwi gwi) {
   const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL);
   set_tflag(t_class, tflag_infer);
@@ -167,6 +243,14 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   GWI_BB(gwi_gack(gwi, t_compound, gack_compound))
   GWI_BB(gwi_set_global_type(gwi, t_compound, et_compound))
 
+  const Type t_none = gwi_mk_type(gwi, "None", 0, NULL);
+  GWI_BB(gwi_gack(gwi, t_none, gack_none))
+  gwi_add_type(gwi, t_none);
+{
+  struct SpecialId_ spid = { .ck=idck_none, .em=idem_none, .is_const=1 };
+  gwi_specialid(gwi, "None", &spid);
+}
+
   GWI_BB(import_object(gwi))
 
   const Type t_union = gwi_class_ini(gwi, "@Union", "Object");
@@ -230,13 +314,24 @@ 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, "@dot", NULL))
 
+  GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@Union", NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_any_at_union))
+  GWI_BB(gwi_oper_emi(gwi, opem_any_at_union))
+  GWI_BB(gwi_oper_end(gwi, "?=>", NULL))
+
   GWI_BB(gwi_oper_ini(gwi, "@Union", (m_str)OP_ANY_TYPE, NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_dot_union))
-  GWI_BB(gwi_oper_emi(gwi, opem_dot_union))
-  GWI_BB(gwi_oper_end(gwi, "@dot", NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_union_at_any))
+  GWI_BB(gwi_oper_emi(gwi, opem_union_at_any))
+  GWI_BB(gwi_oper_end(gwi, "?=>", NULL))
+
+  GWI_BB(gwi_oper_ini(gwi, "@Union", "@Class", NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_union_eq_class))
+  GWI_BB(gwi_oper_emi(gwi, opem_union_eq_class))
+  GWI_BB(gwi_oper_end(gwi, "==", NULL))
 
   GWI_BB(gwi_union_ini(gwi, "Option:[A]"))
-  GWI_BB(gwi_union_add(gwi, "A", "@val"))
+  GWI_BB(gwi_union_add(gwi, "None"))
+  GWI_BB(gwi_union_add(gwi, "A"))
   GWI_BB(gwi_union_end(gwi, ae_flag_none))
 
   return GW_OK;
index 0c8a21c70e9b0eb14e38b37a3bdec55daab72d4e..c98925d7c63706e15c1cf953f3edae4402fa0683 100644 (file)
@@ -226,7 +226,7 @@ ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
     free_class_def(env->gwion->mp, cdef);
   return ret;
 }
-
+/*
 ANN static OP_CHECK(opck_option_get) {
   Exp_Binary *bin = (Exp_Binary*)data;
   exp_setvar(bin->rhs, 1);
@@ -254,8 +254,15 @@ ANN static OP_CHECK(opck_option_set) {
   Exp_Binary *bin = (Exp_Binary*)data;
   CHECK_NN(opck_rassign(env, data, mut)) // check those two lines
   exp_setvar(bin->rhs, 0);
-  const Value v = nspc_lookup_value0(bin->rhs->info->type->nspc, insert_symbol(env->gwion->st, "@val"));
-  return v->type;
+  const Type rhs = bin->rhs->info->type;
+  const Nspc nspc = bin->lhs->info->type->nspc;
+  for(m_uint i = 0; i < nspc->info->class_data_size; i += SZ_INT) {
+    if(rhs == *(Type*)(nspc->info->class_data + i))
+      return rhs;
+  }
+//  ERR_N(exp_self(data)->pos, _(
+//  const Value v = nspc_lookup_value0(bin->rhs->info->type->nspc, insert_symbol(env->gwion->st, "@val"));
+//  return v->type;
 }
 
 static INSTR(OptionSet) {
@@ -311,11 +318,11 @@ ANN static OP_EMIT(opem_option_uncond) {
   pop->m_val = exp->info->type->size - SZ_INT;
   return emit_add_instr(emit, BranchNeqInt);
 }
-
+*/
 
 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_decl_list(env->gwion->mp, u->l),
+  const Union_Def udef = new_union_def(env->gwion->mp, cpy_type_list(env->gwion->mp, u->l),
     loc_cpy(env->gwion->mp, u->pos));
   udef->xid = info->name;
   udef->tmpl = mk_tmpl(env, u->tmpl, info->td->types);
@@ -323,6 +330,7 @@ ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) {
     SET_FLAG(udef, global);
   const m_bool ret = scan0_union_def(env, udef);
   if(udef->type) {
+/*
     if(!strcmp(info->base->name, "Option")) {
       const Type base = known_type(env, info->td->types->td);
       const m_uint scope = env_push(env, udef->type->info->parent->info->owner_class, udef->type->info->parent->info->owner);
@@ -352,6 +360,7 @@ ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) {
       CHECK_BB(add_op(env->gwion, &opi5))
       env_pop(env, scope);
     }
+*/
     udef->type->info->udef = udef;// mark as udef
     info->ret = udef->type;
     set_tflag(info->ret, tflag_udef);
@@ -433,7 +442,6 @@ GWION_IMPORT(object_op) {
   const Type t_error  = gwi_mk_type(gwi, "@error",  0, NULL);
   gwi->gwion->type[et_error] = t_error;
   GWI_BB(gwi_set_global_type(gwi, t_error, et_error))
-  GWI_BB(gwi_oper_cond(gwi, "Object", BranchEqInt, BranchNeqInt))
   GWI_BB(gwi_oper_ini(gwi, "Object", "Object", NULL))
   GWI_BB(gwi_oper_add(gwi, at_object))
   GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
index 2d537ab29e2c7cd38ef918ba422fbf0fc312d0b1..39108371132b420c7cd5b0a13ecd5ea9c05002a0 100644 (file)
@@ -845,6 +845,11 @@ ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
 ANN static Type check_exp_lambda(const Env env,
     const Exp_If* exp_if NUSED) { return env->gwion->type[et_lambda]; }
 
+ANN static Type check_exp_td(const Env env, Type_Decl **td) {
+  DECL_OO(const Type, t, = known_type(env, *td))
+  return type_class(env->gwion, t);
+}
+
 DECL_EXP_FUNC(check, Type, Env)
 
 ANN Type check_exp(const Env env, const Exp exp) {
@@ -1008,65 +1013,11 @@ ANN static m_bool check_stmt_jump(const Env env, const Stmt_Jump stmt) {
   return GW_OK;
 }
 
-ANN m_bool check_union_decl(const Env env, const Union_Def udef) {
-  Decl_List l = udef->l;
-  m_uint sz = 0, idx = 0;
-  do {
-    CHECK_OB(check_exp(env, l->self))
-    Var_Decl_List list = l->self->d.exp_decl.list;
-    list->self->value->from->offset = ++idx;
-    set_vflag(list->self->value, vflag_union);
-    if(l->self->info->type->size > sz)
-      sz = l->self->info->type->size;
-  } while((l = l->next));
-  udef->type->nspc->info->offset = sz + SZ_INT;
-  return GW_OK;
-}
-
-static OP_CHECK(opck_union_is) {
-  Exp_Call *call = (Exp_Call*)data; 
-  Exp exp = call->args;
-  if(exp->exp_type != ae_exp_primary && exp->d.prim.prim_type != ae_prim_id)
-    ERR_N(exp->pos, "FFI variadic arguments must be of FFI type CHANGE ME");
-  const Value v = find_value(call->func->info->type->info->owner_class, exp->d.prim.d.var);
-  if(!v)
-    ERR_N(exp->pos, "'%s' has no member '%s'", call->func->info->type->info->owner_class, exp->d.prim.d.var);
-  exp->d.prim.prim_type = ae_prim_num;
-  exp->d.prim.d.num = v->from->offset;
-  return NULL;
-}
-
-/*static*/ MFUN(union_is) {
- *(m_uint*)RETURN = *(m_uint*)MEM(SZ_INT) == *(m_uint*)o->data;
-}
-
-ANN m_bool check_union_def(const Env env, const Union_Def udef) {
+ANN m_bool check_union_def(const Env env NUSED, const Union_Def udef) {
   if(tmpl_base(udef->tmpl)) // there's a func for this
     return GW_OK;
-  const m_uint scope = env_push_type(env, udef->type);
-  const m_bool ret = check_union_decl(env, udef);
-
-  Type_Decl *td = new_type_decl(env->gwion->mp, insert_symbol("bool"), loc_cpy(env->gwion->mp, udef->pos));
-//  Type_Decl *arg_td = new_type_decl(env->gwion->mp, insert_symbol(), loc_cpy(env->gwion->mp, udef->pos));
-  Type_Decl *arg_td = new_type_decl(env->gwion->mp, insert_symbol("int"), loc_cpy(env->gwion->mp, udef->pos));;
-  Var_Decl var = new_var_decl(env->gwion->mp, insert_symbol("arg"), NULL, loc_cpy(env->gwion->mp, udef->pos));
-  Arg_List args = new_arg_list(env->gwion->mp, arg_td, var, NULL);
-  Func_Base *fb = new_func_base(env->gwion->mp, td, insert_symbol("is"), args, ae_flag_none);
-  Func_Def fdef = new_func_def(env->gwion->mp, fb, NULL, loc_cpy(env->gwion->mp, udef->pos));
-  CHECK_BB(traverse_func_def(env, fdef)) // use ret
-  builtin_func(env->gwion->mp, fb->func, union_is);
-
-  const m_uint oscope = env_push(env, udef->type->info->owner_class, udef->type->info->owner);
-  const struct Op_Func opfunc = { .ck=opck_union_is };
-  const struct Op_Import opi = { .rhs=fb->func->value_ref->type,
-      .func=&opfunc, .data=(uintptr_t)fb->func, .pos=udef->pos, .op=insert_symbol("@func_check") };
-  CHECK_BB(add_op(env->gwion, &opi))
-  env_pop(env, oscope);
-//  set_vflag(fb->func->value_ref, vflag_builtin);
-
-  env_pop(env, scope);
   set_tflag(udef->type, tflag_check);
-  return ret;
+  return GW_OK;
 }
 
 ANN static m_bool check_stmt_exp(const Env env, const Stmt_Exp stmt) {
index d9f18493befc0dbaf9e00866a52e3ee5e08ae2c3..c8da51aa1a0e6a960c9d15ea9ab486c6e6e03c73 100644 (file)
@@ -216,7 +216,7 @@ ANN static Type union_type(const Env env, const Symbol s) {
   t->nspc = new_nspc(env->gwion->mp, name);
   t->info->owner = t->nspc->parent = env->curr;
   t->info->owner_class = env->class_def;
-  t->info->tuple = new_tupleform(env->gwion->mp, NULL);
+  t->info->tuple = new_tupleform(env->gwion->mp, NULL); // ???
   add_type(env, env->curr, t);
   mk_class(env, t);
   SET_FLAG(t, final);
@@ -244,6 +244,9 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
     context_global(env);
   CHECK_BB(scan0_defined(env, udef->xid, udef->pos))
   udef->type = union_type(env, udef->xid);
+  Type_List tl = udef->l;
+  do udef->type->nspc->info->class_data_size += SZ_INT;
+  while((tl = tl->next));
   SET_ACCESS(udef, udef->type);
   if(udef->tmpl)
     union_tmpl(env, udef);
index 374c5c35cc039904acc87c282c9e6bbd15d0a021..14c4532267c1ffa6088b3f8575fdabab50921f9e 100644 (file)
@@ -252,6 +252,7 @@ ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary
 }
 
 #define scan1_exp_lambda dummy_func
+#define scan1_exp_td dummy_func
 HANDLE_EXP_FUNC(scan1, m_bool, Env)
 
 ANN static inline m_bool _scan1_stmt_match_case(const restrict Env env, const Stmt_Match stmt) {
@@ -392,16 +393,25 @@ ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
     scan1_cdef(env, tdef->type) : GW_OK;
 }
 
-ANN static inline m_bool scan1_union_def_inner_loop(const Env env, Decl_List l) {
-  do CHECK_BB(scan1_exp(env, l->self))
-  while((l = l->next));
+ANN static inline m_bool scan1_union_def_inner_loop(const Env env, Union_Def udef) {
+  nspc_allocdata(env->gwion->mp, udef->type->nspc);
+  Type_List l = udef->l;
+  m_uint sz = 0;
+  const Nspc nspc = udef->type->nspc;
+  for(m_uint i = 0; i < nspc->info->class_data_size; i += SZ_INT) {
+    DECL_OB(const Type, t, =(*(Type*)(nspc->info->class_data +i) = known_type(env, l->td)))
+    if(t->size > sz)
+      sz = t->size;
+    l = l->next;
+  }
+  nspc->info->offset = sz;
   return GW_OK;
 }
 
 ANN static m_bool scan1_union_def_inner(const Env env, const Union_Def udef) {
   if(udef->tmpl && udef->tmpl->call)
     CHECK_BB(template_push_types(env, udef->tmpl))
-  const m_bool ret = scan1_union_def_inner_loop(env, udef->l);
+  const m_bool ret = scan1_union_def_inner_loop(env, udef);
   if(udef->tmpl && udef->tmpl->call)
     nspc_pop_type(env->gwion->mp, env->curr);
   return ret;
index 30f33763f60c5692910ae89595758aea988c7992..5d8c0f5e9507decb0d8fb0ab48936eddc261da20 100644 (file)
@@ -204,6 +204,7 @@ ANN static inline m_bool scan2_stmt_match(const restrict Env env, const Stmt_Mat
 }
 
 #define scan2_exp_lambda dummy_func
+#define scan2_exp_td dummy_func
 HANDLE_EXP_FUNC(scan2, m_bool, Env)
 
 #define scan2_stmt_func(name, type, prolog, exp) describe_stmt_func(scan2, name, type, prolog, exp)
@@ -258,20 +259,11 @@ ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) {
   return GW_OK;
 }
 
-ANN static m_bool scan2_union_decl(const Env env, Decl_List l) {
-  do CHECK_BB(scan2_exp(env, l->self))
-  while((l = l->next));
-  return GW_OK;
-}
-
 ANN m_bool scan2_union_def(const Env env, const Union_Def udef) {
-  if(tmpl_base(udef->tmpl))
-    return GW_OK;
-  const m_uint scope = env_push_type(env, udef->type);
-  const m_bool ret = scan2_union_decl(env, udef->l);
-  env_pop(env, scope);
+//  if(tmpl_base(udef->tmpl))
+//    return GW_OK;
   set_tflag(udef->type, tflag_scan2);
-  return ret;
+  return GW_OK;
 }
 
 
index 7467b93237c95fa867c6f57932624b230424cafc..7619b016d1f42342b40ed6d162aa249049d97a25 100644 (file)
@@ -1,4 +1,2 @@
 #! [contains] 
-union {
-  one; two;
-};
+union { one : two };
index 3310091a299d74d85cf81aa93a0828077e516f4e..0c99543b9c7bbc95416445c0691a0c04333c3e1b 100644 (file)
@@ -1,5 +1,2 @@
 #! [contains] must be defined with empty
-union U {
-  int i;
-  int array[4];
-};
+union U { int : int [4] };
index 1e17f48ad3d53eb79aec5af5f2f04c059e6dfc27..98f3a2ddb50adea51906a0ae581ed06b79c478e9 100644 (file)
@@ -1,2 +1,2 @@
 #! [contains] can only be used at class scope.
-union static U { int i; };
+union static U { int };
index 13e237e7004ec37c6576efab479999e621b7ea89..6c0b5b44fee1cc77530744e540a5ffc79766ae3c 100644 (file)
@@ -1,2 +1,2 @@
 #! [contains] can only be used at class scope.
-union private  static U { int i; };
+union private  static U { int };
index 1e748934bd8ec3276d9442b3cb903bfe84edb60f..f1c95c5107541ca2af408eb2e762be1c3ae84ba6 100644 (file)
@@ -1,2 +1,2 @@
 #! [contains] can only be used at class scope.
-union private U { int i; };
+union private U { int };
index ef81d7c388db23a503958513e5c416b3200bc280..633116b1c9d59acabd2b1ced466debf0ae57cb13 100644 (file)
@@ -1,4 +1,2 @@
 #! [contains] unknown_type
-union U {
-       unknown_type unknown_variable;
-}
+union U { unknown_type unknown_variable }
index 5f01d5a37042097aa6241a18572c387cb271be60..6963aaf201ab8d06ed17f72ce35980d33e5fed92 100644 (file)
@@ -11,6 +11,6 @@
 
 GWION_IMPORT(checker) {
   GWI_BB(gwi_union_ini(gwi, "U"))
-  GWI_BB(gwi_union_add(gwi, "int", "|array[2][3]"))
+  GWI_BB(gwi_union_add(gwi, "int"))
   return GW_OK;
 }
index 5dd8357fe0ff1221402a949e4681fc957f55d156..fe8127afa6d59d440573ffb8aa91f3dcb540726f 100644 (file)
@@ -10,8 +10,8 @@
 
 GWION_IMPORT(union_test) {
   GWI_BB(gwi_union_ini(gwi, "U"))
-  GWI_BB(gwi_union_add(gwi,"float", "f"))
-  GWI_BB(gwi_union_add(gwi,"int", "i"))
+  GWI_BB(gwi_union_add(gwi,"float"))
+  GWI_BB(gwi_union_add(gwi,"int"))
   GWI_OB(gwi_union_end(gwi, 0))
   return GW_OK;
 }
index 6d4bc0447d3ad40dfaae2c32178140994cb068cf..fe6645fa7c2b5b542f9dd7f190b0df3743e16f12 100644 (file)
@@ -10,8 +10,8 @@
 
 GWION_IMPORT(union_test) {
   GWI_BB(gwi_union_ini(gwi, "U"))
-  GWI_BB(gwi_union_add(gwi,"Float", "f"))
-  GWI_BB(gwi_union_add(gwi,"int", "i"))
+  GWI_BB(gwi_union_add(gwi,"Float"))
+  GWI_BB(gwi_union_add(gwi,"int"))
   GWI_OB(gwi_union_end(gwi, 0))
   return GW_OK;
 }
index 4647dce8e95a1e5981645e185dc8c000367fdf2e..65e2fcd2a67918eeaa6b5d8b21e48e15e0f1deb0 100644 (file)
@@ -11,8 +11,8 @@
 GWION_IMPORT(union_member) {
   GWI_OB(gwi_class_ini(gwi, "UnionMember", NULL))
     GWI_BB(gwi_union_ini(gwi, "U"))
-    GWI_BB(gwi_union_add(gwi,"float", "f"))
-    GWI_BB(gwi_union_add(gwi,"int[]", "i"))
+    GWI_BB(gwi_union_add(gwi,"float"))
+    GWI_BB(gwi_union_add(gwi,"int[]"))
     GWI_OB(gwi_union_end(gwi, ae_flag_none))
   GWI_BB(gwi_class_end(gwi))
   return GW_OK;
index 671280d2fe6ee5d4fa275644e6d336616debd86c..17cf8856b23d393dcc9d37bbcdcbb8e05328e6de 100644 (file)
@@ -10,8 +10,8 @@
 
 GWION_IMPORT(union_test) {
   GWI_BB(gwi_union_ini(gwi, "my_union"))
-  GWI_BB(gwi_union_add(gwi,"float", "f"))
-  GWI_BB(gwi_union_add(gwi,"int", "i"))
+  GWI_BB(gwi_union_add(gwi,"float"))
+  GWI_BB(gwi_union_add(gwi,"int"))
   GWI_OB(gwi_union_end(gwi, 0))
   return GW_OK;
 }
index 83aee39ea617d7329322a16f469eeb5491306768..637251b293bebf83f1ccbb3c7b122c2f025af304 100644 (file)
@@ -10,9 +10,9 @@
 
 GWION_IMPORT(union_test) {
   GWI_BB(gwi_union_ini(gwi, "U:[A]"))
-  GWI_BB(gwi_union_add(gwi,"float", "f"))
-  GWI_BB(gwi_union_add(gwi,"int", "i"))
-  GWI_BB(gwi_union_add(gwi,"A", "a"))
+  GWI_BB(gwi_union_add(gwi,"float"))
+  GWI_BB(gwi_union_add(gwi,"int"))
+  GWI_BB(gwi_union_add(gwi,"A"))
   GWI_OB(gwi_union_end(gwi, 0))
   return GW_OK;
 }
index 83aee39ea617d7329322a16f469eeb5491306768..637251b293bebf83f1ccbb3c7b122c2f025af304 100644 (file)
@@ -10,9 +10,9 @@
 
 GWION_IMPORT(union_test) {
   GWI_BB(gwi_union_ini(gwi, "U:[A]"))
-  GWI_BB(gwi_union_add(gwi,"float", "f"))
-  GWI_BB(gwi_union_add(gwi,"int", "i"))
-  GWI_BB(gwi_union_add(gwi,"A", "a"))
+  GWI_BB(gwi_union_add(gwi,"float"))
+  GWI_BB(gwi_union_add(gwi,"int"))
+  GWI_BB(gwi_union_add(gwi,"A"))
   GWI_OB(gwi_union_end(gwi, 0))
   return GW_OK;
 }
index cc23bc1b27be21a7f30e481d4cc955ea40818fdb..e8310372eb21e67448040cd39423070566b98642 100644 (file)
@@ -10,9 +10,9 @@
 
 GWION_IMPORT(union_test) {
   GWI_BB(gwi_union_ini(gwi, "U:[A]"))
-  GWI_BB(gwi_union_add(gwi,"float", "f"))
-  GWI_BB(gwi_union_add(gwi,"int", "i"))
-  GWI_BB(gwi_union_add(gwi,"A", "a"))
+  GWI_BB(gwi_union_add(gwi,"float"))
+  GWI_BB(gwi_union_add(gwi,"int"))
+  GWI_BB(gwi_union_add(gwi,"A"))
   GWI_BB(gwi_union_ini(gwi, "U:[A]"))
   GWI_OB(gwi_union_end(gwi, 0))
   return GW_OK;
index 83aee39ea617d7329322a16f469eeb5491306768..637251b293bebf83f1ccbb3c7b122c2f025af304 100644 (file)
@@ -10,9 +10,9 @@
 
 GWION_IMPORT(union_test) {
   GWI_BB(gwi_union_ini(gwi, "U:[A]"))
-  GWI_BB(gwi_union_add(gwi,"float", "f"))
-  GWI_BB(gwi_union_add(gwi,"int", "i"))
-  GWI_BB(gwi_union_add(gwi,"A", "a"))
+  GWI_BB(gwi_union_add(gwi,"float"))
+  GWI_BB(gwi_union_add(gwi,"int"))
+  GWI_BB(gwi_union_add(gwi,"A"))
   GWI_OB(gwi_union_end(gwi, 0))
   return GW_OK;
 }
index d4adfdbb7ba2cf60999a199b063c1f6f2656d148..9c2b2d297bf492836c8d95525f9ecc8a0e26642e 100644 (file)
@@ -2,4 +2,4 @@ fun int add(int i) {
   return i + 3;
 }
 
-<<< 2 $add>>>;
+<<< 2 .add>>>;