From 386101cd2e39fe70f47da4d00f940bb194e2275c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Sun, 13 Dec 2020 21:52:14 +0100 Subject: [PATCH] :art: Improvments --- include/env/type.h | 2 +- include/instr.h | 1 + src/clean.c | 2 + src/emit/emit.c | 49 +++++++++++++++-------- src/import/import_enum.c | 2 + src/lib/engine.c | 79 ++++++++++++++++++++++++++------------ src/parse/scan0.c | 2 +- src/parse/scan1.c | 14 +++++-- src/parse/scan2.c | 4 +- src/parse/type_decl.c | 19 +++++---- tests/tree/cpy_ast.gw | 4 +- tests/tree/udef.gw | 5 +-- tests/tree/union.gw | 6 +-- tests/tree/union_global.gw | 5 +-- tests/tree/union_tmpl.gw | 5 +-- 15 files changed, 125 insertions(+), 74 deletions(-) diff --git a/include/env/type.h b/include/env/type.h index b40df49e..55bf9659 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -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 diff --git a/include/instr.h b/include/instr.h index 3fa4fdde..c5286af0 100644 --- a/include/instr.h +++ b/include/instr.h @@ -45,6 +45,7 @@ INSTR(ArrayBottom); INSTR(ArrayPost); INSTR(ArrayInit); INSTR(ArrayAlloc); +INSTR(ArrayStruct); /* vararg */ INSTR(VarargIni); diff --git a/src/clean.c b/src/clean.c index bee2b1d7..007d6a11 100644 --- a/src/clean.c +++ b/src/clean.c @@ -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) { diff --git a/src/emit/emit.c b/src/emit/emit.c index bd585800..7913a0d0 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -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; diff --git a/src/import/import_enum.c b/src/import/import_enum.c index a68f6aaf..ab38a6dd 100644 --- a/src/import/import_enum.c +++ b/src/import/import_enum.c @@ -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; diff --git a/src/lib/engine.c b/src/lib/engine.c index 76b70b94..1c23b826 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -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; diff --git a/src/parse/scan0.c b/src/parse/scan0.c index c8da51aa..b66fc18c 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -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; diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 14c45322..1331a2f5 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -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; } diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 5d8c0f5e..a578d1b5 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -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; } diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index d8af4d29..becf93b1 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -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 { diff --git a/tests/tree/cpy_ast.gw b/tests/tree/cpy_ast.gw index 5e3c73cc..21ebaae0 100644 --- a/tests/tree/cpy_ast.gw +++ b/tests/tree/cpy_ast.gw @@ -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); diff --git a/tests/tree/udef.gw b/tests/tree/udef.gw index fd0449db..9f08d2d3 100644 --- a/tests/tree/udef.gw +++ b/tests/tree/udef.gw @@ -1,6 +1,3 @@ class C { - union static { - int i; - float f; - }; + union static { int : float } } diff --git a/tests/tree/union.gw b/tests/tree/union.gw index 5cc3de06..fb01c1f9 100644 --- a/tests/tree/union.gw +++ b/tests/tree/union.gw @@ -1,6 +1,2 @@ -union -{ - int one; - string two; -}; +union U { int : string }; <<< one, " ", two >>>; diff --git a/tests/tree/union_global.gw b/tests/tree/union_global.gw index 365a276a..5c31d32a 100644 --- a/tests/tree/union_global.gw +++ b/tests/tree/union_global.gw @@ -1,5 +1,2 @@ -union global GlobalUnion { - int gui; - float guf; -}; +union global GlobalUnion { int : float }; <<<"test">>>; diff --git a/tests/tree/union_tmpl.gw b/tests/tree/union_tmpl.gw index e01a87f5..f4b22ea4 100644 --- a/tests/tree/union_tmpl.gw +++ b/tests/tree/union_tmpl.gw @@ -1,7 +1,4 @@ -union U:[A]{ - int i; - A a; -}; +union U:[A]{ int : A } var U:[float] u; <<< u.a >>>; -- 2.43.0