]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improvments
authorJérémie Astor <fennecdjay@gmail.com>
Sun, 13 Dec 2020 20:52:14 +0000 (21:52 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Sun, 13 Dec 2020 20:52:14 +0000 (21:52 +0100)
15 files changed:
include/env/type.h
include/instr.h
src/clean.c
src/emit/emit.c
src/import/import_enum.c
src/lib/engine.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/type_decl.c
tests/tree/cpy_ast.gw
tests/tree/udef.gw
tests/tree/union.gw
tests/tree/union_global.gw
tests/tree/union_tmpl.gw

index b40df49ecc6f87cdb69d1348e28c20c1a30339b7..55bf9659032beb1309ed2ec7b6c6addcace36a83 100644 (file)
@@ -85,7 +85,7 @@ ANN Type get_type(const Type t);
 typedef enum {
   et_void, et_int, et_bool, et_char, et_float,
   et_error, et_compound, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack,
-  et_function, et_fptr, et_vararg, et_lambda, et_class, et_union, et_undefined, et_auto,
+  et_function, et_fptr, et_vararg, et_lambda, et_class, et_union, et_undefined, et_auto, et_none,
   MAX_TYPE
 } type_enum;
 #endif
index 3fa4fdde32f95f5e938a123fdce6713728d7a38d..c5286af0b83606140a9a898dc7676e0bf3b7eee1 100644 (file)
@@ -45,6 +45,7 @@ INSTR(ArrayBottom);
 INSTR(ArrayPost);
 INSTR(ArrayInit);
 INSTR(ArrayAlloc);
+INSTR(ArrayStruct);
 
 /* vararg */
 INSTR(VarargIni);
index bee2b1d71843b1cb439905648bb5849e42066316..007d6a116b4a7bbe3b9c5955b4f4ce8b8dd97b7e 100644 (file)
@@ -303,6 +303,8 @@ ANN void class_def_cleaner(const Gwion gwion, Class_Def b) {
 
 ANN static void clean_enum_def(Clean *a, Enum_Def b) {
   clean_id_list(a, b->list);
+  if(b->values.ptr)
+    vector_release(&b->values);
 }
 
 ANN static void clean_union_def(Clean *a, Union_Def b) {
index bd5858002394fab6bd44898b1ee7cde6873dbc7c..7913a0d0c1872504fc031f2a6ba2e2024aca1962 100644 (file)
@@ -244,8 +244,6 @@ ANN static void struct_expand(const Emitter emit, const Type t) {
 }
 
 
-INSTR(ArrayStruct);
-
 ANN static void emit_pre_constructor_array(const Emitter emit, const Type type) {
   const m_uint start_index = emit_code_size(emit);
   const Instr top = emit_add_instr(emit, ArrayTop);
@@ -359,6 +357,23 @@ ANN2(1,2) m_bool emit_instantiate_object(const Emitter emit, const Type type,
   return GW_OK;
 }
 
+ANN2(1,2) m_bool emit_instantiate_decl(const Emitter emit, const Type type,
+      const Type_Decl *td, const Array_Sub array, const m_bool is_ref) {
+  Exp base = td->array ? td->array->exp : NULL, exp = base,
+     next = array ? array->exp : NULL;
+  const m_uint depth = (td->array ? td->array->depth : 0) + (array ? array->depth : 0);
+  if(exp) {
+    while(exp->next)
+      exp = exp->next;
+    exp->next = next;
+  } else base = next;
+  struct Array_Sub_ a = { .exp=base, .depth=depth };
+  const m_bool ret = emit_instantiate_object(emit, type, &a, is_ref);
+  if(td->array && td->array->exp)
+    exp->next = NULL;
+  return ret;
+}
+
 ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data);
 ANN static m_bool emit_symbol_owned(const Emitter emit, const Symbol *data) {
   const Exp dot = symbol_owned_exp(emit->gwion, data);
@@ -635,11 +650,11 @@ ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, const
   return GW_OK;
 }
 
-ANN static m_bool decl_static(const Emitter emit, const Var_Decl var_decl, const uint is_ref) {
+ANN static m_bool decl_static(const Emitter emit, const Exp_Decl *decl, const Var_Decl var_decl, const uint is_ref) {
   const Value v = var_decl->value;
   Code* code = emit->code;
   emit->code = (Code*)vector_back(&emit->stack);
-  CHECK_BB(emit_instantiate_object(emit, v->type, var_decl->array, is_ref))
+  CHECK_BB(emit_instantiate_decl(emit, v->type, decl->td, var_decl->array, is_ref))
   CHECK_BB(emit_dot_static_data(emit, v, 1))
   emit_add_instr(emit, Assign);
   (void)emit_addref(emit, 0);
@@ -665,10 +680,10 @@ ANN static void emit_struct_decl_finish(const Emitter emit, const Type t, const
   emit->code->frame->curr_offset -= t->size + SZ_INT;
 }
 
-ANN static m_bool emit_exp_decl_static(const Emitter emit, const Var_Decl var_decl, const uint is_ref, const uint emit_addr) {
+ANN static m_bool emit_exp_decl_static(const Emitter emit, const Exp_Decl *decl, const Var_Decl var_decl, const uint is_ref, const uint emit_addr) {
   const Value v = var_decl->value;
   if(isa(v->type, emit->gwion->type[et_object]) > 0 && !is_ref)
-    CHECK_BB(decl_static(emit, var_decl, 0))
+    CHECK_BB(decl_static(emit, decl, var_decl, 0))
   CHECK_BB(emit_dot_static_data(emit, v, !struct_ctor(v) ? emit_addr : 1))
   if(struct_ctor(v))
     emit_struct_decl_finish(emit, v->type, emit_addr);
@@ -692,7 +707,7 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d
   const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
   const uint emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : 1;
   if(is_obj && (is_array || !is_ref))
-    CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
+    CHECK_BB(emit_instantiate_decl(emit, type, decl->td, array, is_ref))
   f_instr *exec = (f_instr*)allocmember;
   if(!vflag(v, vflag_member)) {
     v->from->offset = emit_local(emit, type);
@@ -713,17 +728,19 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d
       const Instr instr = emit_add_instr(emit, Reg2Reg);
       instr->m_val = -SZ_INT;
     }
-    const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
+/*
+    const size_t missing_depth = type->array_depth - (array ? array->depth : 0) - (decl->td->array ? decl->td->array->depth : 0);
     if(missing_depth) {
       const Instr push = emit_add_instr(emit, Reg2Reg);
       push->m_val = -(missing_depth) * SZ_INT;
     }
+*/
   } else if(struct_ctor(v))
     emit_struct_decl_finish(emit, v->type, emit_addr);
   return GW_OK;
 }
 
-ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_decl,
+ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl, const Var_Decl var_decl,
   const uint is_ref, const uint emit_var) {
   const Value v = var_decl->value;
   const Type type = v->type;
@@ -732,7 +749,7 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_de
   const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
   const uint emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : 1;
   if(is_obj && (is_array || !is_ref))
-    CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
+    CHECK_BB(emit_instantiate_decl(emit, type, decl->td, array, is_ref))
   const Instr instr = emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, dotstatic);
   v->d.ptr = mp_calloc2(emit->gwion->mp, v->type->size);
   if(isa(type, emit->gwion->type[et_union]) < 0)
@@ -741,12 +758,14 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_de
   instr->m_val2 = v->type->size;
   if(is_obj && (is_array || !is_ref)) {
     const Instr assign = emit_add_instr(emit, Assign);
-    const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
+    assign->m_val = emit_var;
+/*
+    const size_t missing_depth = type->array_depth - (array ? array->depth : 0) - (decl->td->array ? decl->td->array->depth : 0);
     if(missing_depth) {
       const Instr push = emit_add_instr(emit, Reg2Reg);
       push->m_val = -(missing_depth) * SZ_INT;
     }
-    assign->m_val = emit_var;
+*/
     (void)emit_addref(emit, emit_var);
   } else if(struct_ctor(v))
     emit_struct_decl_finish(emit, v->type, emit_addr);
@@ -772,12 +791,12 @@ ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) {
   Var_Decl_List list = decl->list;
   do {
     if(GET_FLAG(decl->td, static))
-      CHECK_BB(emit_exp_decl_static(emit, list->self, ref, var))
+      CHECK_BB(emit_exp_decl_static(emit, decl, list->self, ref, var))
     else if(!global)
       CHECK_BB(emit_exp_decl_non_static(emit, decl, list->self, ref, var))
     else
-      CHECK_BB(emit_exp_decl_global(emit, list->self, ref, var))
-    if(!var && !GET_FLAG(decl->td, optionnal) && (GET_FLAG(decl->td, ref) || is_fptr(emit->gwion, list->self->value->type)))
+      CHECK_BB(emit_exp_decl_global(emit, decl, list->self, ref, var))
+    if(!var && !decl->td->option && (GET_FLAG(decl->td, ref) || is_fptr(emit->gwion, list->self->value->type)))
       ERR_B(list->self->pos, "kljlkj")
   } while((list = list->next));
   return GW_OK;
index a68f6aaf7740487fad2d0f689bbe710f6d7e40fa..ab38a6dd4adc373cccb22187144f61a6ee055e4a 100644 (file)
@@ -89,6 +89,8 @@ ANN Type gwi_enum_end(const Gwi gwi) {
   const m_bool ret = traverse_enum_def(gwion->env, edef);
   import_enum_end(gwi, &edef->values);
   const Type t = ret > 0 ? edef->t : NULL;
+  if(edef->values.ptr)
+    vector_release(&edef->values);
   free_enum_def(gwion->mp, edef);
   vector_release(&gwi->ck->v);
   gwi->ck->v.ptr = NULL;
index 76b70b949cdf5ea4179b27a4ff6047070d9e3e77..1c23b8262ff7f9b5ee95c4fb182ea0014a3bb02f 100644 (file)
@@ -81,24 +81,35 @@ static OP_CHECK(opck_basic_ctor) {
   ERR_N(exp_self(call)->pos, _("can't call a non-callable value"))
 }
 
+#define UNION_IDX(a) (*(m_uint*)(a->data))
 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 bin->rhs->info->type;
   }
   return env->gwion->type[et_error]; // err_msg
 }
 
+static inline Type curr_type(const M_Object o) {
+  const m_uint idx = UNION_IDX(o);
+  if(!idx)
+    return NULL;
+  const Type curr = *(Type*)(o->type_ref->nspc->info->class_data + ((idx-1) * SZ_INT));
+  return curr;
+}
+
 static INSTR(UnionSet) {
   POP_REG(shred, SZ_INT);
-  const M_Object o = *(M_Object*)REG(0);
-  *(m_uint*)(o->data) = instr->m_val2;
+  const M_Object o = **(M_Object**)REG(0);
   memcpy(o->data + SZ_INT, REG(-instr->m_val), instr->m_val);
+  UNION_IDX(o) = instr->m_val2;
+  PUSH_REG(shred, SZ_INT-instr->m_val);
+  *(M_Object*)REG(-SZ_INT) = o;
+  _release(o, shred);
 }
 
 static OP_EMIT(opem_any_at_union) {
@@ -108,7 +119,7 @@ static OP_EMIT(opem_any_at_union) {
   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_val2 = i/SZ_INT + 1;
       instr->m_val = lhs->size;
       return instr;
     }
@@ -117,8 +128,8 @@ static OP_EMIT(opem_any_at_union) {
 }
 
 static OP_CHECK(opck_union_at_any) {
-  Exp_Binary *bin = (Exp_Binary*)data;
   CHECK_NN(opck_rassign(env, data, mut)) // check those two lines
+  Exp_Binary *bin = (Exp_Binary*)data;
   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) {
@@ -130,21 +141,27 @@ static OP_CHECK(opck_union_at_any) {
 
 static INSTR(UnionGet) {
   const M_Object o = *(M_Object*)REG(-SZ_INT*2);
-  if(*(m_uint*)(o->data) != instr->m_val2)
+  if(UNION_IDX(o) != 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(REG(-instr->m_val), o->data + SZ_INT, instr->m_val);
+  _release(o, shred);
 }
 
 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;
+  // TODO: compound
   const Instr instr = emit_add_instr(emit, UnionGet);
+  if(isa(rhs, emit->gwion->type[et_object]) > 0) {
+    const Instr instr = emit_add_instr(emit, RegAddRef);
+    instr->m_val = -SZ_INT;
+  }
   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_val2 = i/SZ_INT + 1;
       instr->m_val = rhs->size;
       return instr;
     }
@@ -166,8 +183,8 @@ static OP_CHECK(opck_union_eq_class) {
 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;
-
+  *(m_uint*)REG(-SZ_INT) = (UNION_IDX(o) == instr->m_val2);
+  _release(o, shred);
 }
 
 static OP_EMIT(opem_union_eq_class) {
@@ -175,33 +192,38 @@ static OP_EMIT(opem_union_eq_class) {
   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);
+  if(!strcmp(s_name(bin->op), "!="))
+    (void)emit_add_instr(emit, IntNot);
   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_val2 = i/SZ_INT + 1;
       return instr;
     }
   }
   return NULL;
 }
 
-DTOR(UnionDtor) {
+static INSTR(UnionNot) {
+  const M_Object o = *(M_Object*)REG(-SZ_INT);
+  const m_uint idx = UNION_IDX(o);
+  if(idx) {
+    const Type none = shred->info->vm->gwion->type[et_none];
+    const Type curr = *(Type*)(o->type_ref->nspc->info->class_data + ((idx-1) * SZ_INT));
+    *(m_uint*)REG(-SZ_INT) = curr == none;
+  } else
+    *(m_uint*)REG(-SZ_INT) = 1;
+  _release(o, shred);
+}
+
+static DTOR(UnionDtor) {
   const m_uint idx = *(m_uint*)o->data;
   if(idx) {
-    const Type t = *(Type*)(o->type_ref->nspc->info->class_data + idx * SZ_INT);
+    const Type t = *(Type*)(o->type_ref->nspc->info->class_data + (idx-1) * SZ_INT);
     if(isa(t, shred->info->vm->gwion->type[et_compound]) > 0)
-      compound_release(shred, t, *(m_bit**)(o->data + SZ_INT));
+      compound_release(shred, t, (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);
@@ -244,10 +266,12 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   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_set_global_type(gwi, t_none, et_none))
   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 };
+//  struct SpecialId_ spid = { .ck=idck_none, .em=idem_none, .is_const=1 };
+  struct SpecialId_ spid = { .type=gwi->gwion->type[et_none], .exec=NoOp, .is_const=1 };
   gwi_specialid(gwi, "None", &spid);
 }
 
@@ -328,10 +352,15 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   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_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_oper_ini(gwi, NULL, "@Union", "bool"))
+  GWI_BB(gwi_oper_end(gwi, "!", UnionNot))
 
   GWI_BB(gwi_union_ini(gwi, "Option:[A]"))
-  GWI_BB(gwi_union_add(gwi, "None"))
   GWI_BB(gwi_union_add(gwi, "A"))
+  GWI_BB(gwi_union_add(gwi, "None"))
   GWI_BB(gwi_union_end(gwi, ae_flag_none))
 
   return GW_OK;
index c8da51aa1a0e6a960c9d15ea9ab486c6e6e03c73..b66fc18cf1fb33fcd48cae1882d0ddc335d81cf7 100644 (file)
@@ -204,6 +204,7 @@ ANN m_bool scan0_enum_def(const Env env, const Enum_Def edef) {
   CHECK_BB(scan0_defined(env, edef->xid, edef->pos))
   CHECK_BB(scan0_global(env, edef->flag, edef->pos))
   edef->t = enum_type(env, edef);
+  vector_init(&edef->values);
   if(GET_FLAG(edef, global))
     context_global(env);
   return GW_OK;
@@ -212,7 +213,6 @@ ANN m_bool scan0_enum_def(const Env env, const Enum_Def edef) {
 ANN static Type union_type(const Env env, const Symbol s) {
   const m_str name = s_name(s);
   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;
index 14c4532267c1ffa6088b3f8575fdabab50921f9e..1331a2f51053688b4d4628b2ee1d5be20c6d5780 100644 (file)
@@ -70,6 +70,10 @@ static inline m_bool scan1_defined(const Env env, const Var_Decl var) {
   return GW_OK;
 }
 
+static inline uint array_ref(const Array_Sub array) {
+  return array && !array->exp;
+}
+
 ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
   Var_Decl_List list = decl->list;
   do {
@@ -77,7 +81,7 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
     CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
     Type t = decl->type;
     CHECK_BB(scan1_defined(env, var))
-   if(var->array) {
+    if(var->array) {
       if(var->array->exp)
         CHECK_BB(scan1_exp(env, var->array->exp))
       t = array_type(env, decl->type, var->array->depth);
@@ -100,7 +104,7 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
     nspc_add_value(env->curr, var->xid, v);
     v->flag |= decl->td->flag;
     v->type = t;
-    if(var->array && !var->array->exp)
+    if(array_ref(var->array))
       SET_FLAG(decl->td, ref);
     if(env->class_def) {
       if(env->class_def->info->tuple)
@@ -126,6 +130,8 @@ ANN int is_global(const Nspc nspc, Nspc global) {
 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))
   ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
+  if(array_ref(decl->td->array))
+   SET_FLAG(decl->td, ref);
   CHECK_OB(decl->type)
   const m_bool global = GET_FLAG(decl->td, global);
   if(global) {
@@ -399,12 +405,12 @@ ANN static inline m_bool scan1_union_def_inner_loop(const Env env, Union_Def ude
   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)))
+    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;
+  nspc->info->offset = sz + SZ_INT;
   return GW_OK;
 }
 
index 5d8c0f5e9507decb0d8fb0ab48936eddc261da20..a578d1b55fa176d49ddc9a2a99efea29c0413eb6 100644 (file)
@@ -260,8 +260,8 @@ ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) {
 }
 
 ANN m_bool scan2_union_def(const Env env, const Union_Def udef) {
-//  if(tmpl_base(udef->tmpl))
-//    return GW_OK;
+  if(tmpl_base(udef->tmpl))
+    return GW_OK;
   set_tflag(udef->type, tflag_scan2);
   return GW_OK;
 }
index d8af4d293bc81b4e3445d615509b49b0cb98ad27..becf93b1a1d12efdf1442ac2a42856c18f4fc3f4 100644 (file)
@@ -5,12 +5,17 @@
 #include "traverse.h"
 #include "parse.h"
 
-ANN static Type option(const Env env, Type_Decl* td) {
+ANN static Type _option(const Env env, Type_Decl* td, const m_uint n) {
   struct Type_List_ tl = { .td=td };
-  Type_Decl option_td = { .xid=insert_symbol("Option"), .types=&tl };
-  UNSET_FLAG(td, optionnal);
-  const Type ret = known_type(env, &option_td);
-  SET_FLAG(td, optionnal);
+  Type_Decl option_td = { .xid=insert_symbol("Option"), .types=&tl, .pos=td->pos };
+  return !(n-1) ? known_type(env, &option_td) : _option(env, &option_td, n-1);
+}
+
+ANN static Type option(const Env env, Type_Decl* td) {
+  const m_uint option = td->option;
+  td->option = 0;
+  const Type ret = _option(env, td, option);
+  td->option = option;
   return ret;
 }
 
@@ -19,8 +24,8 @@ ANN static Type resolve(const Env env, Type_Decl* td) {
   if(base->info->ctx && base->info->ctx->error)
     ERR_O(td_pos(td), _("type '%s' is invalid"), base->name)
   DECL_OO(const Type, t, = scan_type(env, base, td))
-  const Type ret = !td->array ? t : array_type(env, t, td->array->depth);
-  return !GET_FLAG(td, optionnal) ? ret : option(env, td);
+  const Type ret = !td->option ? t : option(env, td);
+  return !td->array ? ret : array_type(env, ret, td->array->depth);
 }
 
 struct td_info {
index 5e3c73cce69079df15d218b99a7cca1d83fca27d..21ebaae010f2e5975cb7485d5073c3114fb0132e 100644 (file)
@@ -8,8 +8,8 @@ class C:[A] {
   i++;
   i ? i : !i;
   ++i;
-  union { int ui; } u;
-  union U:[A] { int ui; };
+  union U { int }
+  union V:[A] { int }
   typeof(i);
   if(i) i; else i;
   for(var int _i; _i < 1; ++_i);
index fd0449db8abdfb5191ff93137f0eed02dfd85315..9f08d2d30cb41b71fa37ccae43dbbe26ec241f0c 100644 (file)
@@ -1,6 +1,3 @@
 class C {
-  union static {
-    int i;
-    float f;
-  };
+  union static { int : float }
 }
index 5cc3de061fd7daa8fe3923893e71768077af428c..fb01c1f9d5c40069826ed834a7c2cac9d4399a69 100644 (file)
@@ -1,6 +1,2 @@
-union
-{
-  int one;
-  string two;
-};
+union U { int : string };
 <<< one, " ", two >>>;
index 365a276a9a63502e8b1cb3353d6b2be98723a527..5c31d32a6f8803a46f4eecd488d87369e63ab6da 100644 (file)
@@ -1,5 +1,2 @@
-union global GlobalUnion {
-  int gui;
-  float guf;
-};
+union global GlobalUnion { int : float };
 <<<"test">>>;
index e01a87f507989a2aa2da41e934115ccfcca1ed5b..f4b22ea41ba7504f99873e5393013a31387764dd 100644 (file)
@@ -1,7 +1,4 @@
-union U:[A]{
-  int i;
-  A a;
-};
+union U:[A]{ int : A }
 
 var U:[float] u;
 <<< u.a >>>;