]> Nishi Git Mirror - gwion.git/commitdiff
:art: Tagged unions and Maybe type
authorJérémie Astor <fennecdjay@gmail.com>
Fri, 11 Dec 2020 00:26:44 +0000 (01:26 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Fri, 11 Dec 2020 00:26:44 +0000 (01:26 +0100)
37 files changed:
include/import/udef.h
include/parse.h
include/tmpl_info.h [new file with mode: 0644]
src/emit/emit.c
src/import/import_oper.c
src/import/import_udef.c
src/lib/engine.c
src/lib/object.c
src/lib/object_op.c
src/lib/prim.c
src/lib/tmpl_info.c [new file with mode: 0644]
src/parse/check.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/stage.c [deleted file]
src/parse/template.c
tests/error/named_union_global_private.gw [deleted file]
tests/error/named_union_global_private_static.gw [deleted file]
tests/error/named_union_global_static.gw [deleted file]
tests/error/no_member.gw [deleted file]
tests/error/not_nn.gw [new file with mode: 0644]
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/empty_union.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

index d74200ebaaa8fee3ecd0776907c37a95756fb255..dc25503cf445b8bca7589e50c0fd3da9787e32e7 100644 (file)
@@ -1,8 +1,8 @@
 #ifndef __IMPORT_UNION
 #define __IMPORT_UNION
 
-ANN2(1) m_int gwi_union_ini(const Gwi gwi, const m_str type, const m_str name);
-ANN m_int gwi_union_add(const Gwi gwi, const __restrict__ m_str type, const __restrict__ m_str name); 
+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 Type gwi_union_end(const Gwi gwi, const ae_flag flag);
 ANN void ck_clean_udef(MemPool, ImportCK*);
 
index 394a5314e76faac61aa4f23c40bb88b43ae65fc4..3e24a72c715870a20bdb5b875c74257d326668ae 100644 (file)
@@ -46,9 +46,6 @@ ANN static m_bool prefix##_stmt_##name(const Env env, const type stmt) { \
   RET_NSPC(exp) \
 }
 
-ANN m_uint union_push(const Env, const Union_Def);
-ANN void union_pop(const Env, const Union_Def, const m_uint);
-ANN void union_flag(const Union_Def, const enum tflag);
 ANN m_bool check_stmt(const Env env, const Stmt stmt);
 
 typedef m_bool (*_exp_func)(const void*, const void*);
diff --git a/include/tmpl_info.h b/include/tmpl_info.h
new file mode 100644 (file)
index 0000000..fd2b2b8
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _TMPL_INFO
+#define _TMPL_INFO
+struct tmpl_info {
+  Symbol           name;
+  ID_List          list;
+  const Type_Decl* td;
+  Type             ret;
+  Type             base;
+  struct Vector_   type;
+  struct Vector_   size;
+  uint8_t index;
+};
+#endif
index 973bdbfc6e0ab5b4362a10135c4323bb13c2f8ca..a7beb5ce180afeb258402509fe48491331d0b2b2 100644 (file)
@@ -1350,7 +1350,6 @@ ANN static void struct_addref(const Emitter emit, const Type type,
   }
 }
 
-
 ANN static inline m_uint exp_size(const Exp e) {
   if(exp_getvar(e))
     return SZ_INT;
@@ -1700,67 +1699,10 @@ ANN static m_bool emit_enum_def(const Emitter emit, const Enum_Def edef) {
   return GW_OK;
 }
 
-ANN void emit_union_offset(Decl_List l, const m_uint o) {
-  do {
-    Var_Decl_List v = l->self->d.exp_decl.list;
-    do v->self->value->from->offset = o;
-    while((v = v->next));
-  } while((l = l->next));
-}
-
-ANN static inline void union_allocdata(MemPool mp, const Union_Def udef) {
-  const Nspc nspc = (udef->xid ? udef->value->type : udef->type)->nspc;
-  nspc_allocdata(mp, nspc);
-  nspc->info->offset = udef->s;
-}
-
-ANN static m_bool emit_union_def(const Emitter emit, const Union_Def udef) {
+ANN static m_bool emit_union_def(const Emitter emit NUSED, const Union_Def udef) {
   if(tmpl_base(udef->tmpl))
     return GW_OK;
-  Decl_List l = udef->l;
-  m_uint scope = emit->env->scope->depth;
-  const m_bool global = GET_FLAG(udef, global);
-  if(udef->xid) {
-    union_allocdata(emit->gwion->mp, udef);
-    Type_Decl *type_decl = new_type_decl(emit->gwion->mp,
-        udef->xid, loc_cpy(emit->gwion->mp, udef->pos));
-    type_decl->flag = udef->flag;
-    const Var_Decl var_decl = new_var_decl(emit->gwion->mp, udef->xid, NULL, loc_cpy(emit->gwion->mp, udef->pos));
-    const Var_Decl_List var_decl_list = new_var_decl_list(emit->gwion->mp, var_decl, NULL);
-    const Exp exp = new_exp_decl(emit->gwion->mp, type_decl, var_decl_list, loc_cpy(emit->gwion->mp, udef->pos));
-    exp->d.exp_decl.type = udef->value->type;
-    var_decl->value = udef->value;
-    const m_bool ret = emit_exp_decl(emit, &exp->d.exp_decl);
-    free_exp(emit->gwion->mp, exp);
-    CHECK_BB(ret)
-    if(global) {
-      const M_Object o = new_object(emit->gwion->mp, NULL, udef->value->type);
-      udef->value->d.ptr = (m_uint*)o;
-      set_vflag(udef->value, vflag_builtin);
-    }
-    scope = emit_push_type(emit, udef->value->type);
-  } else if(udef->type_xid) {
-    union_allocdata(emit->gwion->mp, udef);
-    scope = emit_push_type(emit, udef->type);
-  } else if(global) {
-    // TODO: use mpool allocation
-    void* ptr = (void*)xcalloc(1, udef->s);
-    l = udef->l;
-    udef->value->d.ptr = ptr;
-    udef->value->vflag |= (vflag_enum | vflag_freeme);
-    do {
-      Var_Decl_List list = l->self->d.exp_decl.list;
-      list->self->value->d.ptr = ptr;
-      set_vflag(list->self->value, vflag_direct);// xcalloc
-    } while((l = l->next));
-    udef->l->self->d.exp_decl.list->self->value->vflag |= (vflag_enum | vflag_freeme);
-  }
-  if(udef->xid)
-    regpop(emit, SZ_INT);
-  emit_union_offset(udef->l, udef->o);
-  if(udef->xid || udef->type_xid || global)
-    emit_pop(emit, scope);
-  union_flag(udef, tflag_emit);
+  set_tflag(udef->type, tflag_emit);
   return GW_OK;
 }
 
index 0d744892d387c2e7c6fbeaff8025ad0e8c2f6467..01df4c0ea56a74b1efca262fbfccc67a8c2ae50e 100644 (file)
@@ -19,6 +19,7 @@
 ANN static Type _get_type(const Gwi gwi, const m_str s) {
   if(s == (m_str)OP_ANY_TYPE)
     return OP_ANY_TYPE;
+  // str2type
   Type_Decl *td = gwi_str2decl(gwi, s);
   const Type t = known_type(gwi->gwion->env, td);
   free_type_decl(gwi->gwion->mp, td);
index 8c58aa227242c102fa78a35d570a35dfde789ac8..f49fb534b638164f4de0dd2d680ec8f910cc4ddd 100644 (file)
@@ -24,13 +24,10 @@ ANN Exp make_exp(const Gwi gwi, const m_str type, const m_str name) {
   return NULL;
 }
 
-ANN2(1) m_int gwi_union_ini(const Gwi gwi, const m_str type, const m_str name) {
+ANN m_int gwi_union_ini(const Gwi gwi, const m_str name) {
   CHECK_BB(ck_ini(gwi, ck_udef))
-  if(name)
-    CHECK_OB((gwi->ck->xid = gwi_str2sym(gwi, name)))
-  gwi->ck->name = type;
-  if(type)
-    CHECK_BB(check_typename_def(gwi, gwi->ck))
+  gwi->ck->name = name;
+  CHECK_BB(check_typename_def(gwi, gwi->ck))
   return GW_OK;
 }
 
@@ -45,17 +42,14 @@ ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type, const restrict
 ANN static Type union_type(const Gwi gwi, const Union_Def udef) {
   CHECK_BO(scan0_union_def(gwi->gwion->env, udef))
   CHECK_BO(traverse_union_def(gwi->gwion->env, udef))
-  if(!udef->tmpl)
-    emit_union_offset(udef->l, udef->o);
-  if(gwi->gwion->env->class_def && !GET_FLAG(udef, static))
-      gwi->gwion->env->class_def->nspc->info->offset =
-       udef->o + udef->s;
-  if(udef->xid || !udef->type_xid) {
-    set_vflag(udef->value, vflag_builtin);
-    const M_Object o = new_object(gwi->gwion->mp, NULL, udef->value->type);
-    udef->value->d.ptr = (m_uint*)o;
-   return udef->value->type;
-  }
+//  if(!udef->tmpl)
+//    emit_union_offset(udef->l, udef->o);
+//  if(gwi->gwion->env->class_def && !GET_FLAG(udef, static))
+//      gwi->gwion->env->class_def->nspc->info->offset =
+//       udef->o + udef->s;
+//  set_vflag(udef->value, vflag_builtin);
+//  const M_Object o = new_object(gwi->gwion->mp, NULL, udef->value->type);
+//  udef->value->d.ptr = (m_uint*)o;
   return udef->type;
 }
 
@@ -63,13 +57,10 @@ ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) {
   CHECK_BO(ck_ok(gwi, ck_udef))
   if(!gwi->ck->list)
     GWI_ERR_O(_("union is empty"));
-  if(gwi->ck->tmpl && gwi->ck->xid)
-    GWI_ERR_O(_("Template union type can't declare instance at declaration"));
   const Union_Def udef = new_union_def(gwi->gwion->mp, gwi->ck->list, loc(gwi));
   gwi->ck->list = NULL;
   udef->flag = flag;
-  udef->xid = gwi->ck->xid;
-  udef->type_xid = gwi->ck->sym;
+  udef->xid = gwi->ck->sym;
   if(gwi->ck->tmpl) {
     udef->tmpl = gwi_tmpl(gwi);
     gwi->ck->tmpl = NULL;
index b58b7b3b2f173e3cdb7ec73cbf1c3b7faf3aedbc..b53a4851e5156303f7e026e1a35e3c126ac32d07 100644 (file)
@@ -77,15 +77,55 @@ 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 INSTR(UnionSet) {
+  const M_Object o = *(M_Object*)REG(-SZ_INT);
+  *(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);
+}
+
+static INSTR(UnionGet) {
+  const M_Object o = *(M_Object*)REG(-SZ_INT);
+  if(*(m_uint*)(o->data) != instr->m_val2)
+    Except(shred, "invalid union access");
+  POP_REG(shred, SZ_INT - instr->m_val);
+  memcpy(REG(-instr->m_val), o->data + SZ_INT, instr->m_val);
+}
+
+static OP_EMIT(opem_dot_union) {
+  Exp_Dot *dot = (Exp_Dot*)data;
+  CHECK_BO(emit_exp(emit, dot->base))
+  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;
+}
+
+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);
+    if(isa(t, shred->info->vm->gwion->type[et_compound]) > 0)
+      compound_release(shred, t, *(m_bit**)(o->data + SZ_INT));
+  }
+}
+
 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);
   GWI_BB(gwi_set_global_type(gwi, t_class, et_class))
-  GWI_BB(gwi_gack(gwi, t_class, gack_class)) // not working yet
-  GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, (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, "@dot", NULL))
+  GWI_BB(gwi_gack(gwi, t_class, gack_class))
+
   const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL);
   GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined))
   const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL);
@@ -120,7 +160,17 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   const Type t_compound = gwi_mk_type(gwi, "@Compound", 0, NULL);
   GWI_BB(gwi_gack(gwi, t_compound, gack_compound))
   GWI_BB(gwi_set_global_type(gwi, t_compound, et_compound))
+
   GWI_BB(import_object(gwi))
+
+  const Type t_union = gwi_class_ini(gwi, "@Union", "Object");
+  gwi_class_xtor(gwi, NULL, UnionDtor);
+  GWI_BB(gwi_item_ini(gwi, "int", "@index"))
+  GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
+  GWI_BB(gwi_class_end(gwi))
+  GWI_BB(gwi_gack(gwi, t_union, gack_compound))
+  gwi->gwion->type[et_union] = t_union;
+
   GWI_BB(import_prim(gwi))
   const Type t_function = gwi_mk_type(gwi, "@function", SZ_INT, NULL);
   GWI_BB(gwi_gack(gwi, t_function, gack_function))
@@ -138,11 +188,6 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   GWI_BB(import_object_op(gwi))
   GWI_BB(import_values(gwi))
 
-// TODO: check me
-  const Type t_union = gwi_class_ini(gwi, "@Union", NULL);
-  gwi->gwion->type[et_union] = t_union;
-  GWI_BB(gwi_class_end(gwi))
-
   GWI_BB(import_array(gwi))
   GWI_BB(import_event(gwi))
   GWI_BB(import_ugen(gwi))
@@ -152,7 +197,6 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   GWI_BB(gwi_oper_add(gwi, opck_new))
   GWI_BB(gwi_oper_emi(gwi, opem_new))
   GWI_BB(gwi_oper_end(gwi, "new", NULL))
-//  GWI_BB(import_prim(gwi))
   GWI_BB(import_vararg(gwi))
   GWI_BB(import_string(gwi))
   GWI_BB(import_shred(gwi))
@@ -169,6 +213,26 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_basic_ctor))
   GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
+
+  GWI_BB(gwi_oper_ini(gwi, "@Compound", (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, "@dot", NULL))
+
+  GWI_BB(gwi_oper_ini(gwi, "@Class", (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, "@dot", 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_union_ini(gwi, "Option:[A]"))
+  GWI_BB(gwi_union_add(gwi, "A", "@val"))
+  GWI_BB(gwi_union_end(gwi, ae_flag_none))
+
   return GW_OK;
 }
 
index 115f80843a547203ec2fe4796b8adf84353aecdd..64cd45f381ac25fc8d13ca391e7171b8ae0e8485 100644 (file)
@@ -66,7 +66,7 @@ ANN void __release(const M_Object o, const VM_Shred shred) {
   MemPool p = shred->info->mp;
   Type t = o->type_ref;
   do {
-    if(!t->nspc || is_special(t))
+    if(!t->nspc || is_special(t) || tflag(t, tflag_udef))
       continue;
     struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
     Value v;
index 639a894a052c9ff045c0357a0bd27dbb8d8c8c97..cb57147c674b33c69cc0d4755449675b0fa65ca5 100644 (file)
@@ -14,8 +14,8 @@
 #include "template.h"
 #include "parse.h"
 #include "specialid.h"
-
 #include "gwi.h"
+#include "tmpl_info.h"
 
 #undef insert_symbol
 
@@ -118,7 +118,7 @@ static OP_CHECK(opck_object_not) {
   return unary->exp->info->type;
 }
 
-ANN /*static*/ Type scan_class(const Env env, const Type t, const Type_Decl* td);
+ANN /*static*/ Type scan_class(const Env env, const Type t, const Type_Decl * td);
 
 static Type opck_object_scan(const Env env, const struct TemplateScan *ts) {
   if(ts->td->types)
@@ -204,10 +204,10 @@ OP_CHECK(opck_object_dot) {
   const m_str str = s_name(member->xid);
   const m_bool base_static = is_class(env->gwion, member->t_base);
   const Type the_base = base_static ? member->t_base->info->base_type : member->t_base;
-  if(!the_base->nspc)
-    ERR_N(member->base->pos,
-          _("type '%s' does not have members - invalid use in dot expression of %s"),
-          the_base->name, str)
+//  if(!the_base->nspc)
+//    ERR_N(member->base->pos,
+//          _("type '%s' does not have members - invalid use in dot expression of %s"),
+//          the_base->name, str)
   if(member->xid ==  insert_symbol(env->gwion->st, "this") && base_static)
     ERR_N(exp_self(member)->pos,
           _("keyword 'this' must be associated with object instance..."))
@@ -254,7 +254,6 @@ OP_EMIT(opem_object_dot) {
     if(!tflag(t_base, tflag_struct))
       emit_member(emit, value, exp_getvar(exp_self(member)));
     else {
-//      exp_setvar(member->base, exp_getvar(exp_self(member)));
       exp_setvar(member->base, 1);
       CHECK_BO(emit_exp(emit, member->base))
       emit_struct_data(emit, value, exp_getvar(exp_self(member)));
@@ -268,90 +267,13 @@ OP_EMIT(opem_object_dot) {
   return (Instr)GW_OK;
 }
 
-struct tmpl_info {
-  Symbol           name;
-  ID_List          list;
-  Type_List        call;
-  Type             ret;
-  Type             base;
-  struct Vector_   type;
-  struct Vector_   size;
-  uint8_t index;
-};
-
-ANN static inline size_t tmpl_set(struct tmpl_info* info, const Type t) {
-  vector_add(&info->type, (vtype)t);
-  const size_t len = strlen(t->name);
-  vector_add(&info->size, len);
-  return len;
-}
-
-ANN static ssize_t template_size(const Env env, struct tmpl_info* info) {
-  ID_List base = info->list; // ???
-  Type_List call = info->call;
-  size_t size = 0;
-  do {
-    DECL_OB(const Type, t, = known_type(env, call->td))
-    size += tmpl_set(info, t);
-  } while((call = call->next) && (base = base->next) && ++size);
-//  } while((call = call->next) && ++size);
-  size += tmpl_set(info, info->base);
-  return size + 4;
-}
-
-ANN static inline m_str tmpl_get(struct tmpl_info* info, m_str str) {
-  const Type t = (Type)vector_at(&info->type, info->index);
-  strcpy(str, t->name);
-  return str += vector_at(&info->size, info->index);
-}
-
-ANN static void template_name(struct tmpl_info* info, m_str s) {
-  m_str str = s;
-  const m_uint size = info->index = vector_size(&info->type) -1;
-  str = tmpl_get(info, str);
-  *str++ = ':';
-  *str++ = '[';
-  for(info->index = 0; info->index < size; ++info->index) {
-    str = tmpl_get(info, str);
-    if(info->index < size - 1)
-      *str++ = ',';
-    else {
-      *str++ = ']';
-    }
-  }
-  *str = '\0';
-}
-
-ANEW ANN static Symbol template_id(const Env env, struct tmpl_info* info) {
-  vector_init(&info->type);
-  vector_init(&info->size);
-  ssize_t sz = template_size(env, info);
-  char name[sz];
-  if(sz > GW_ERROR)
-    template_name(info, name);
-  vector_release(&info->type);
-  vector_release(&info->size);
-  return sz > GW_ERROR ? insert_symbol(env->gwion->st, name) : NULL;
-}
-
-ANN static m_bool template_match(ID_List base, Type_List call) {
-  while((call = call->next) && (base = base->next));
-  return !call ? GW_OK : GW_ERROR;
-}
-
-ANN static Type tmpl_exists(const Env env, const Symbol name) {
-  if(env->class_def && name == insert_symbol(env->gwion->st, env->class_def->name))
-     return env->class_def;
-  return nspc_lookup_type1(env->curr, name);
-}
-
 ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
   const Class_Def c = info->base->info->cdef;
   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,
       c->body ?cpy_ast(env->gwion->mp, c->body) : NULL,
     loc_cpy(env->gwion->mp, c->pos));
   cdef->cflag = c->cflag;
-  cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->call);
+  cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->td->types);
   const m_bool ret = scan0_class_def(env, cdef);
   if((info->ret = cdef->base.type)) {
     info->ret->info->cdef = cdef;
@@ -362,16 +284,142 @@ ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
   return ret;
 }
 
+ANN static OP_CHECK(opck_option_get) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  exp_setvar(bin->rhs, 1);
+  return bin->rhs->info->type;
+}
+
+static INSTR(OptionCheck) {
+  const M_Object o = *(M_Object*)REG(-SZ_INT*2);
+  if(*(m_uint*)(o->data) != instr->m_val2)
+    Except(shred, "invalid union access");
+  memcpy(*(m_bit**)REG(-SZ_INT), o->data + SZ_INT, instr->m_val);
+  POP_REG(shred, SZ_INT*2 - instr->m_val);
+  memcpy(&*(m_bit*)REG(-instr->m_val), o->data + SZ_INT, instr->m_val);
+}
+
+ANN static OP_EMIT(opem_option_get) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  const Instr instr = emit_add_instr(emit, OptionCheck);
+  instr->m_val = bin->rhs->info->type->size;
+  instr->m_val2 = 1;
+  return instr;
+}
+
+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;
+}
+
+static INSTR(OptionSet) {
+  M_Object o = *(M_Object*)REG(-SZ_INT);
+  *(m_uint*)(o->data) = instr->m_val2;
+  *(m_bit**)(o->data + SZ_INT) = *(void**)REG(-instr->m_val);
+}
+
+ANN static OP_EMIT(opem_option_set) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  const Value v = nspc_lookup_value0(bin->rhs->info->type->nspc, insert_symbol(emit->gwion->st, "@val"));
+  const Instr set = emit_add_instr(emit, OptionSet);
+  set->m_val = SZ_INT + v->type->size;
+  set->m_val2 = 1;
+  const Instr pop = emit_add_instr(emit, RegPop);
+  pop->m_val = SZ_INT;
+  return set;
+}
+
+ANN static OP_CHECK(opck_option_setn) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  CHECK_NN(opck_rassign(env, data, mut))
+  exp_setvar(bin->rhs, 1);
+  return env->gwion->type[et_void];
+}
+
+ANN static OP_EMIT(opem_option_setn) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  const Instr instr = emit_add_instr(emit, OptionSet);
+  instr->m_val = bin->rhs->info->type->nspc->info->offset;
+  const Instr  pop2 = emit_add_instr(emit, RegPop);
+  pop2->m_val = SZ_INT * 2;
+  return instr;
+}
+
+ANN static OP_EMIT(opem_option_not) {
+  Exp_Unary *unary = (Exp_Unary*)data;
+  const Instr pop = emit_add_instr(emit, RegPop);
+  pop->m_val = unary->exp->info->type->nspc->info->offset - sizeof(uint16_t)*2;
+  const Instr set = emit_add_instr(emit, Reg2Reg);
+  set->m_val = -sizeof(uint16_t)*2;
+  set->m_val2 = unary->exp->info->type->nspc->info->offset - sizeof(uint16_t)*2;
+  return emit_add_instr(emit, IntNot);
+}
+
+ANN static OP_EMIT(opem_option_cond) {
+  Exp exp = (Exp)data;
+  const Instr set = emit_add_instr(emit, Reg2Reg);
+  set->m_val = -exp->info->type->size;
+  set->m_val2 = -sizeof(uint16_t)*2;
+  const Instr  pop2 = emit_add_instr(emit, RegPop);
+  pop2->m_val = exp->info->type->nspc->info->offset - sizeof(uint16_t)*2;
+  const Instr instr = emit_add_instr(emit, BranchEqInt);
+  return instr;
+}
+
+ANN static OP_EMIT(opem_option_uncond) {
+  Exp exp = (Exp)data;
+  const Instr set = emit_add_instr(emit, Reg2Reg);
+  set->m_val = -exp->info->type->size;
+  set->m_val2 = -sizeof(uint16_t)*2;
+  const Instr  pop2 = emit_add_instr(emit, RegPop);
+  pop2->m_val = exp->info->type->size - sizeof(uint16_t)*2;
+  const Instr instr = emit_add_instr(emit, BranchNeqInt);
+  return instr;
+}
+
+
 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),
     loc_cpy(env->gwion->mp, u->pos));
-  udef->type_xid = info->name;
-  udef->tmpl = mk_tmpl(env, u->tmpl, info->call);
+  udef->xid = info->name;
+  udef->tmpl = mk_tmpl(env, u->tmpl, info->td->types);
   if(GET_FLAG(info->base, global))
     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);
+      const struct Op_Func opfunc0 = { .ck=opck_option_get, .em=opem_option_get };
+      struct Op_Import opi0 = { .lhs=udef->type, .rhs=base, .ret=base,
+       .op=insert_symbol(env->gwion->st, "?=>"), .pos=info->td->pos, .func=&opfunc0 };
+      CHECK_BB(add_op(env->gwion, &opi0))
+      const struct Op_Func opfunc1 = { .ck=opck_option_set, .em=opem_option_set };
+      struct Op_Import opi1 = { .lhs=base, .rhs=udef->type, .ret=udef->type, .func=&opfunc1,
+       .op=insert_symbol(env->gwion->st, "@=>"), .pos=info->td->pos };
+      CHECK_BB(add_op(env->gwion, &opi1))
+      const struct Op_Func opfunc2 = { .ck=opck_option_setn, .em=opem_option_setn };
+      struct Op_Import opi2 = { .lhs=env->gwion->type[et_null], .rhs=udef->type, .ret=udef->type, .func=&opfunc2,
+       .op=insert_symbol(env->gwion->st, "@=>"), .pos=info->td->pos };
+      CHECK_BB(add_op(env->gwion, &opi2))
+      const struct Op_Func opfunc3 = { .em=opem_option_not };
+      struct Op_Import opi3 = { .rhs=udef->type, .ret=env->gwion->type[et_bool], .func=&opfunc3,
+       .op=insert_symbol(env->gwion->st, "!"), .pos=info->td->pos };
+      CHECK_BB(add_op(env->gwion, &opi3))
+      const struct Op_Func opfunc4 = { .em=opem_option_cond };
+      struct Op_Import opi4 = { .rhs=udef->type, .ret=env->gwion->type[et_bool], .func=&opfunc4,
+       .op=insert_symbol(env->gwion->st, "@conditionnal"), .pos=info->td->pos };
+      CHECK_BB(add_op(env->gwion, &opi4))
+      const struct Op_Func opfunc5 = { .em=opem_option_uncond };
+      struct Op_Import opi5 = { .rhs=udef->type, .ret=env->gwion->type[et_bool], .func=&opfunc5,
+       .op=insert_symbol(env->gwion->st, "@unconditionnal"), .pos=info->td->pos };
+      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);
@@ -389,14 +437,12 @@ ANN static Type _scan_class(const Env env, struct tmpl_info *info) {
   return info->ret;
 }
 
-ANN Type scan_class(const Env env, const Type t, const Type_Decl* td) {
-  if(template_match(t->info->cdef->base.tmpl->list, td->types) < 0) // invalid template
-    ERR_O(td->pos, _("invalid template types number"))
-  struct tmpl_info info = { .base=t, .call=td->types, .list=t->info->cdef->base.tmpl->list  };
-  DECL_OO(const Symbol, name, = info.name = template_id(env, &info))
-  const Type exists = tmpl_exists(env, name);
+ANN Type tmpl_exists(const Env env, struct tmpl_info *const 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  };
+  const Type exists = tmpl_exists(env, &info);
   if(exists)
-    return exists;
+    return exists != env->gwion->type[et_null] ? exists : NULL;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef,
     .scope=env->scope->depth, .flag=tflag_scan0 };
   CHECK_BO(envset_push(&es, t->info->owner_class, t->info->ctx ? t->info->ctx->nspc : env->curr))
@@ -468,7 +514,7 @@ GWION_IMPORT(object_op) {
   GWI_BB(gwi_oper_emi(gwi, opem_object_cast))
   GWI_BB(gwi_oper_end(gwi, "$", NULL))
   GWI_BB(gwi_oper_ini(gwi, NULL, "Object", "bool"))
-  GWI_BB(gwi_oper_add(gwi, opck_unary_meta2))
+  GWI_BB(gwi_oper_add(gwi, opck_unary_meta2)) // this is suspicious
   GWI_BB(gwi_oper_add(gwi, opck_object_not))
   GWI_BB(gwi_oper_end(gwi, "!", IntNot))
   GWI_BB(gwi_oper_ini(gwi, "@Compound", NULL, NULL))
index e021a10485f5658411aadbcf0420ef2b9eea28af..2dbbcba9e644a8d5bfef42424fe8fb1d01cc96ea 100644 (file)
@@ -114,7 +114,7 @@ static GWION_IMPORT(int_values) {
   GWI_BB(gwi_gack(gwi, t_bool, gack_bool))
   gwi->gwion->type[et_bool] = t_bool;
   GWI_BB(gwi_oper_ini(gwi, NULL, "int", "bool"))
-  GWI_BB(gwi_oper_add(gwi, opck_unary_meta)) // should return bool
+  GWI_BB(gwi_oper_add(gwi, opck_unary_meta))
   GWI_BB(gwi_oper_end(gwi,  "!", IntNot))
   struct SpecialId_ spid = { .type=t_bool, .exec=RegPushMaybe, .is_const=1 };
   gwi_specialid(gwi, "maybe", &spid);
@@ -295,7 +295,7 @@ static GWION_IMPORT(float) {
   GWI_BB(gwi_oper_ini(gwi, "float", "dur", "dur"))
   GWI_BB(gwi_oper_end(gwi, "::",         FloatTimes))
   GWI_BB(gwi_oper_ini(gwi, NULL,   "float", "bool"))
-  GWI_BB(gwi_oper_add(gwi, opck_unary_meta2)) // should return bool
+  GWI_BB(gwi_oper_add(gwi, opck_unary_meta2))
   GWI_BB(gwi_oper_end(gwi,  "!", float_not))
   return GW_OK;
 }
diff --git a/src/lib/tmpl_info.c b/src/lib/tmpl_info.c
new file mode 100644 (file)
index 0000000..f63e7bb
--- /dev/null
@@ -0,0 +1,81 @@
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "gwion.h"
+#include "object.h"
+#include "operator.h"
+#include "traverse.h"
+#include "parse.h"
+#include "tmpl_info.h"
+
+ANN static inline m_str tmpl_get(struct tmpl_info* info, m_str str) {
+  const Type t = (Type)vector_at(&info->type, info->index);
+  strcpy(str, t->name);
+  return str += vector_at(&info->size, info->index);
+}
+
+ANN static void template_name(struct tmpl_info* info, m_str s) {
+  m_str str = s;
+  const m_uint size = info->index = vector_size(&info->type) -1;
+  str = tmpl_get(info, str);
+  *str++ = ':';
+  *str++ = '[';
+  for(info->index = 0; info->index < size; ++info->index) {
+    str = tmpl_get(info, str);
+    if(info->index < size - 1)
+      *str++ = ',';
+    else
+      *str++ = ']';
+  }
+  *str = '\0';
+}
+
+ANN static inline size_t tmpl_set(struct tmpl_info* info, const Type t) {
+  vector_add(&info->type, (vtype)t);
+  const size_t len = strlen(t->name);
+  vector_add(&info->size, len);
+  return len;
+}
+
+ANN static ssize_t template_size(const Env env, struct tmpl_info* info) {
+  ID_List base = info->list; // ???
+  Type_List call = info->td->types;
+  size_t size = 0;
+  do {
+    DECL_OB(const Type, t, = known_type(env, call->td))
+    size += tmpl_set(info, t);
+  } while((call = call->next) && (base = base->next) && ++size);
+  size += tmpl_set(info, info->base);
+  return size + 4;
+}
+
+ANEW ANN static Symbol template_id(const Env env, struct tmpl_info *const info) {
+  vector_init(&info->type);
+  vector_init(&info->size);
+  ssize_t sz = template_size(env, info);
+  char name[sz];
+  if(sz > GW_ERROR)
+    template_name(info, name);
+  vector_release(&info->type);
+  vector_release(&info->size);
+  return sz > GW_ERROR ? insert_symbol(name) : NULL;
+}
+
+ANN static m_bool template_match(ID_List base, Type_List call) {
+  while((call = call->next) && (base = base->next));
+  return !call ? GW_OK : GW_ERROR;
+}
+
+ANN static Type _tmpl_exists(const Env env, const Symbol name) {
+  if(env->class_def && name == insert_symbol(env->class_def->name))
+     return env->class_def;
+  return nspc_lookup_type1(env->curr, 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"))
+  DECL_ON(const Symbol, name, = info->name = template_id(env, info))
+  return _tmpl_exists(env, name);
+}
index 361078aff34daf0954fcc57ba9cf4e2a7494184c..1c0e857f4ec753e1b8d1e670724e92431e7522ed 100644 (file)
@@ -1012,42 +1012,27 @@ ANN static m_bool check_stmt_jump(const Env env, const Stmt_Jump stmt) {
 
 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;
     do set_vflag(list->self->value, vflag_union);
-    while((list = list->next));
-    if(l->self->info->type->size > udef->s)
-      udef->s = l->self->info->type->size;
+    while((list = list->next)); // disallow multiple values here.
+    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;
 }
 
-ANN void check_udef(const Env env, const Union_Def udef) {
-  if(udef->xid) {
-    if(env->class_def)
-      (!GET_FLAG(udef, static) ? decl_member : decl_static)(env, udef->value);
-    else if(env->class_def) {
-      if(!GET_FLAG(udef, static))
-        udef->o = env->class_def->nspc->info->offset;
-      else {
-        udef->o = env->class_def->nspc->info->class_data_size;
-        env->class_def->nspc->info->class_data_size += SZ_INT;
-      }
-    }
-  }
-}
-
 ANN m_bool check_union_def(const Env env, const Union_Def udef) {
   if(tmpl_base(udef->tmpl)) // there's a func for this
     return GW_OK;
-  check_udef(env, udef);
-  const m_uint scope = union_push(env, udef);
+  const m_uint scope = env_push_type(env, udef->type);
   const m_bool ret = check_union_decl(env, udef);
-  if(!udef->xid && !udef->type_xid && env->class_def && !GET_FLAG(udef, static))
-    env->class_def->nspc->info->offset = udef->o + udef->s;
-  union_pop(env, udef, scope);
-  union_flag(udef, tflag_check);
+  env_pop(env, scope);
+  set_tflag(udef->type, tflag_check);
   return ret;
 }
 
index 5c5b3eea6d2e91425f992f1c008a63b9d71417dc..d9f18493befc0dbaf9e00866a52e3ee5e08ae2c3 100644 (file)
@@ -209,18 +209,17 @@ ANN m_bool scan0_enum_def(const Env env, const Enum_Def edef) {
   return GW_OK;
 }
 
-ANN static Type union_type(const Env env, const Symbol s, const m_bool add) {
+ANN static Type union_type(const Env env, const Symbol s) {
   const m_str name = s_name(s);
-  const Type t = type_copy(env->gwion->mp, env->gwion->type[et_union]);
-  t->name = name;
+  const Type t = new_type(env->gwion->mp, name, env->gwion->type[et_union]);
+  t->size = SZ_INT;
   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->parent = env->gwion->type[et_union];
   t->info->tuple = new_tupleform(env->gwion->mp, NULL);
   add_type(env, env->curr, t);
-  if(add)
-    mk_class(env, t);
+  mk_class(env, t);
+  SET_FLAG(t, final);
   return t;
 }
 
@@ -232,16 +231,8 @@ ANN static void union_tmpl(const Env env, const Union_Def udef) {
     set_tflag(u->type, tflag_tmpl);
     set_tflag(u->type, tflag_udef);
   }
-  if(GET_FLAG(udef, global))
-    SET_FLAG(udef->type, global);
-}
-
-ANN static Value union_value(const Env env, const Type t, const Symbol sym) {
-  const Value v = new_value(env->gwion->mp, t, s_name(sym));
-  valuefrom(env, v->from);
-  nspc_add_value(env->curr, sym, v);
-  set_vflag(v, vflag_union);
-  return v;
+//  if(GET_FLAG(udef, global))
+//    SET_FLAG(udef->type, global);
 }
 
 ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
@@ -251,32 +242,14 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
       env_push_global(env);
   if(GET_FLAG(udef, global))
     context_global(env);
-  if(udef->xid) {
-    CHECK_BB(scan0_defined(env, udef->xid, udef->pos))
-    const Symbol sym = udef->type_xid ?: scan0_sym(env, "union", udef->pos);
-    const Type t = union_type(env, sym, !!udef->type_xid);
-    udef->value = union_value(env, t, udef->xid);
-    udef->value->flag |= udef->flag;
-    SET_ACCESS(udef, t);
-    if(env->class_def && !GET_FLAG(udef, static))
-      set_vflag(udef->value, vflag_member);
-  } else if(udef->type_xid) {
-    CHECK_BB(scan0_defined(env, udef->type_xid, udef->pos))
-    udef->type = union_type(env, udef->type_xid, 1);
-    SET_ACCESS(udef, udef->type);
-  } else {
-    const Symbol sym = scan0_sym(env, "union", udef->pos);
-    CHECK_BB(scan0_defined(env, sym, udef->pos))
-    const Type t = union_type(env, sym, 1);
-    SET_ACCESS(udef, t);
-    udef->value = union_value(env, t, sym);
-    udef->value->flag |= udef->flag;
-  }
+  CHECK_BB(scan0_defined(env, udef->xid, udef->pos))
+  udef->type = union_type(env, udef->xid);
+  SET_ACCESS(udef, udef->type);
   if(udef->tmpl)
     union_tmpl(env, udef);
   if(GET_FLAG(udef, global))
     env_pop(env, scope);
-  union_flag(udef, tflag_scan0);
+  set_tflag(udef->type, tflag_scan0);
   return GW_OK;
 }
 
index 4ba9110e81d29d66466962aeb668d84e2fc285d9..54b21a8ce9bc99fd29de7efaa997d45b40aa79b0 100644 (file)
@@ -392,28 +392,8 @@ ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
     scan1_cdef(env, tdef->type) : GW_OK;
 }
 
-ANN static m_bool scan1_union_def_action(const Env env, const Union_Def udef,
-    const Decl_List l) {
-  const Exp_Decl decl = l->self->d.exp_decl;
-  decl.td->flag |= udef->flag;
-  const m_bool global = GET_FLAG(udef, global);
-  if(global)
-    UNSET_FLAG(decl.td, global);
-  else if(GET_FLAG(udef, static))
-    SET_FLAG(decl.td, static);
-  CHECK_BB(scan1_exp(env, l->self))
-
-  Var_Decl_List list = decl.list;
-  do value_addref(list->self->value);
-  while((list = list->next));
-
-  if(global)
-    SET_FLAG(decl.td, global);
-  return GW_OK;
-}
-
-ANN static inline m_bool scan1_union_def_inner_loop(const Env env, const Union_Def udef, Decl_List l) {
-  do CHECK_BB(scan1_union_def_action(env, udef, l))
+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));
   return GW_OK;
 }
@@ -421,7 +401,7 @@ ANN static inline m_bool scan1_union_def_inner_loop(const Env env, const Union_D
 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, udef->l);
+  const m_bool ret = scan1_union_def_inner_loop(env, udef->l);
   if(udef->tmpl && udef->tmpl->call)
     nspc_pop_type(env->gwion->mp, env->curr);
   return ret;
@@ -430,14 +410,10 @@ ANN static m_bool scan1_union_def_inner(const Env env, const Union_Def udef) {
 ANN m_bool scan1_union_def(const Env env, const Union_Def udef) {
   if(tmpl_base(udef->tmpl))
     return GW_OK;
-  const m_uint scope = union_push(env, udef);
-  if(udef->xid || udef->type_xid) {
-    UNSET_FLAG(udef, private);
-    UNSET_FLAG(udef, protect);
-  }
+  const m_uint scope = env_push_type(env, udef->type);
   const m_bool ret = scan1_union_def_inner(env, udef);
-  union_pop(env, udef, scope);
-  union_flag(udef, tflag_scan1);
+  env_pop(env, scope);
+  set_tflag(udef->type, tflag_scan1);
   return ret;
 }
 
index 7f34c2947bed3094998e8a0587791cdc561ff773..30f33763f60c5692910ae89595758aea988c7992 100644 (file)
@@ -258,10 +258,8 @@ 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, const Decl_List list) {
-  Decl_List l = list;
-  do CHECK_BB(scan2_exp_decl(env, &l->self->d.exp_decl))
-//  do CHECK_BB(scan2_exp(env, l->self))
+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;
 }
@@ -269,10 +267,10 @@ ANN static m_bool scan2_union_decl(const Env env, const Decl_List list) {
 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 = union_push(env, udef);
+  const m_uint scope = env_push_type(env, udef->type);
   const m_bool ret = scan2_union_decl(env, udef->l);
-  union_pop(env, udef, scope);
-  union_flag(udef, tflag_scan2);
+  env_pop(env, scope);
+  set_tflag(udef->type, tflag_scan2);
   return ret;
 }
 
diff --git a/src/parse/stage.c b/src/parse/stage.c
deleted file mode 100644 (file)
index 84c1dad..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "gwion_util.h"
-#include "gwion_ast.h"
-#include "gwion_env.h"
-
-ANN m_uint union_push(const Env env, const Union_Def udef) {
-  const Type type = udef->xid ? udef->value->type : udef->type_xid ?
-    udef->type : NULL;
-  return type ? env_push_type(env, type) : GET_FLAG(udef, global) ?
-    env_push_global(env) : env->scope->depth;
-}
-
-ANN void union_pop(const Env env, const Union_Def udef, const m_uint scope) {
-  if(udef->xid || udef->type_xid || GET_FLAG(udef, global))
-    env_pop(env, scope);
-}
-
-ANN void union_flag(const Union_Def udef, const enum tflag flag) {
-  const Type type = udef->xid || !udef->type_xid ?
-    udef->value->type : udef->type;
-  type->tflag |= flag;
-}
index 9a0127ff2681f909d2c6c83449e5d4a43503178c..3d71630b99a1261a0b030e7d28b7e68939332d63 100644 (file)
@@ -9,14 +9,6 @@
 #include "gwion.h"
 #include "operator.h"
 
-struct tmpl_info {
-  const  Class_Def cdef;
-  Type_List        call;
-  struct Vector_   type;
-  struct Vector_   size;
-  uint8_t index;
-};
-
 ANN static m_bool push_types(const Env env, const Tmpl *tmpl) {
   ID_List list = tmpl->list;
   Type_List call = tmpl->call;
diff --git a/tests/error/named_union_global_private.gw b/tests/error/named_union_global_private.gw
deleted file mode 100644 (file)
index 901cf42..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] can only be used at class scope.
-union private { int i; } u;
diff --git a/tests/error/named_union_global_private_static.gw b/tests/error/named_union_global_private_static.gw
deleted file mode 100644 (file)
index 3c59bee..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] can only be used at class scope.
-union private static { int i; } u;
diff --git a/tests/error/named_union_global_static.gw b/tests/error/named_union_global_static.gw
deleted file mode 100644 (file)
index 704217b..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] can only be used at class scope.
-union static { int i; } u;
diff --git a/tests/error/no_member.gw b/tests/error/no_member.gw
deleted file mode 100644 (file)
index 332cd47..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#! [contains] does not have members - invalid use in dot expression
-var int i;
-i.nothing;
-
diff --git a/tests/error/not_nn.gw b/tests/error/not_nn.gw
new file mode 100644 (file)
index 0000000..748b8ff
--- /dev/null
@@ -0,0 +1,3 @@
+#! [contains] expression is known to be nonnull
+nonnull Object o;
+<<< (!o) >>>;
index d62b538d09b99ebefdf6cf84f3f8c7671def51df..3310091a299d74d85cf81aa93a0828077e516f4e 100644 (file)
@@ -1,5 +1,5 @@
 #! [contains] must be defined with empty
-union {
+union {
   int i;
   int array[4];
 };
index 188ecb2387e57472ccad65354a0e2c635cae2c22..1e17f48ad3d53eb79aec5af5f2f04c059e6dfc27 100644 (file)
@@ -1,2 +1,2 @@
 #! [contains] can only be used at class scope.
-union static { int i; };
+union static { int i; };
index c9f8e009677804de45358c9bd64eec6805f72b43..13e237e7004ec37c6576efab479999e621b7ea89 100644 (file)
@@ -1,2 +1,2 @@
 #! [contains] can only be used at class scope.
-union private  static { int i; };
+union private  static { int i; };
index 76f37242e2430411265cb5ab543515de4b024a73..1e748934bd8ec3276d9442b3cb903bfe84edb60f 100644 (file)
@@ -1,2 +1,2 @@
 #! [contains] can only be used at class scope.
-union private { int i; };
+union private { int i; };
index b40d7d8ba91fcc6bf91c1fd004093128f4800d8b..788a6ade503cdc7cd1b1ac471b2182ec807e5799 100644 (file)
@@ -1,5 +1,5 @@
 #! [contains] unknown_type
-union
+union U
 {
        unknown_type unknown_variable;
 };
index 605bdb96396c1accea6f61fadc911c8f479cf8e2..5f01d5a37042097aa6241a18572c387cb271be60 100644 (file)
@@ -10,7 +10,7 @@
 #include "gwi.h"
 
 GWION_IMPORT(checker) {
-  GWI_BB(gwi_union_ini(gwi, NULL, NULL))
+  GWI_BB(gwi_union_ini(gwi, "U"))
   GWI_BB(gwi_union_add(gwi, "int", "|array[2][3]"))
   return GW_OK;
 }
index 9cf0af19aaa980b357f7a44b859660c0e981e393..78ba7a8da4130e792900528721b3ae2804877e24 100644 (file)
@@ -9,7 +9,7 @@
 #include "import.h"
 
 GWION_IMPORT(empty_union_test) {
-  GWI_BB(gwi_union_ini(gwi, NULL, NULL))
+  GWI_BB(gwi_union_ini(gwi, "U"))
   GWI_OB(gwi_union_end(gwi, 0))
   return GW_OK;
 }
index 9e2fc88432068ae8f341fd3e53f15d874da7c0fc..5dd8357fe0ff1221402a949e4681fc957f55d156 100644 (file)
@@ -9,7 +9,7 @@
 #include "import.h"
 
 GWION_IMPORT(union_test) {
-  GWI_BB(gwi_union_ini(gwi, NULL, 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_OB(gwi_union_end(gwi, 0))
index 09d40f7700daee76d3971068b5cf7800283b9d94..6d4bc0447d3ad40dfaae2c32178140994cb068cf 100644 (file)
@@ -9,7 +9,7 @@
 #include "import.h"
 
 GWION_IMPORT(union_test) {
-  GWI_BB(gwi_union_ini(gwi, NULL, 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_OB(gwi_union_end(gwi, 0))
index 1d36fa0f2d286edd743722018068ab76efdf7a92..4647dce8e95a1e5981645e185dc8c000367fdf2e 100644 (file)
@@ -10,7 +10,7 @@
 
 GWION_IMPORT(union_member) {
   GWI_OB(gwi_class_ini(gwi, "UnionMember", NULL))
-    GWI_BB(gwi_union_ini(gwi, "U", 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_OB(gwi_union_end(gwi, ae_flag_none))
index b92ec03f49f521b7ba11c7123e2c90ee77a93112..671280d2fe6ee5d4fa275644e6d336616debd86c 100644 (file)
@@ -9,7 +9,7 @@
 #include "import.h"
 
 GWION_IMPORT(union_test) {
-  GWI_BB(gwi_union_ini(gwi, NULL, "my_union"))
+  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_OB(gwi_union_end(gwi, 0))
index 049f6d4075784d5500975bb8ba53f9fe6b73fa79..83aee39ea617d7329322a16f469eeb5491306768 100644 (file)
@@ -9,7 +9,7 @@
 #include "import.h"
 
 GWION_IMPORT(union_test) {
-  GWI_BB(gwi_union_ini(gwi, "U:[A]", NULL))
+  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"))
index f38840f7358e68084c1f4b938f024135eede726d..83aee39ea617d7329322a16f469eeb5491306768 100644 (file)
@@ -9,7 +9,7 @@
 #include "import.h"
 
 GWION_IMPORT(union_test) {
-  GWI_BB(gwi_union_ini(gwi, "U:[A]", "My"))
+  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"))
index 0cf882e5eab6fb626808593ac6717c0b234a06e7..cc23bc1b27be21a7f30e481d4cc955ea40818fdb 100644 (file)
@@ -9,11 +9,11 @@
 #include "import.h"
 
 GWION_IMPORT(union_test) {
-  GWI_BB(gwi_union_ini(gwi, "U:[A]", NULL))
+  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_ini(gwi, "U:[A]", NULL))
+  GWI_BB(gwi_union_ini(gwi, "U:[A]"))
   GWI_OB(gwi_union_end(gwi, 0))
   return GW_OK;
 }
index 36afd1f09ae22a5871b7931f3e870872a194c935..83aee39ea617d7329322a16f469eeb5491306768 100644 (file)
@@ -9,7 +9,7 @@
 #include "import.h"
 
 GWION_IMPORT(union_test) {
-  GWI_BB(gwi_union_ini(gwi, "U:[A]", "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"))