From 89fc8fc9205c423544228763d09067870a349e43 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Sat, 12 Dec 2020 22:44:03 +0100 Subject: [PATCH] :art: Simplify unions --- ast | 2 +- include/clean.h | 1 - include/emit.h | 1 - include/import/checker.h | 2 +- include/import/udef.h | 2 +- src/clean.c | 12 +- src/emit/emit.c | 5 + src/import/import_udef.c | 9 +- src/lib/engine.c | 157 +++++++++++++++++---- src/lib/object_op.c | 20 ++- src/parse/check.c | 63 +-------- src/parse/scan0.c | 5 +- src/parse/scan1.c | 18 ++- src/parse/scan2.c | 16 +-- tests/error/union.gw | 4 +- tests/error/union_array_empty.gw | 5 +- tests/error/union_global_private.gw | 2 +- tests/error/union_global_private_static.gw | 2 +- tests/error/union_global_static.gw | 2 +- tests/error/union_unknown.gw | 4 +- tests/plug/array_in_var_name_fail.c | 2 +- tests/plug/union.c | 4 +- tests/plug/union_fail_exp.c | 4 +- tests/plug/union_member.c | 4 +- tests/plug/union_name.c | 4 +- tests/plug/union_tmpl.c | 6 +- tests/plug/union_tmpl_fail.c | 6 +- tests/plug/union_tmpl_fail2.c | 6 +- tests/plug/union_tmpl_fail3.c | 6 +- tests/xxxfix/post_func.gw | 2 +- 30 files changed, 214 insertions(+), 162 deletions(-) diff --git a/ast b/ast index bb94d272..28c10a9a 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit bb94d2722c601b3a767dbe1149925a3c09b8cca6 +Subproject commit 28c10a9ae4b3e704a5a570c94726ef8b0ba612fa diff --git a/include/clean.h b/include/clean.h index 449a0468..d77408f1 100644 --- a/include/clean.h +++ b/include/clean.h @@ -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); diff --git a/include/emit.h b/include/emit.h index 868b5289..272ac97e 100644 --- a/include/emit.h +++ b/include/emit.h @@ -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); diff --git a/include/import/checker.h b/include/import/checker.h index 3221164c..69a357dd 100644 --- a/include/import/checker.h +++ b/include/import/checker.h @@ -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 }; diff --git a/include/import/udef.h b/include/import/udef.h index dc25503c..a11c1f10 100644 --- a/include/import/udef.h +++ b/include/import/udef.h @@ -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*); diff --git a/src/clean.c b/src/clean.c index 5d64b36e..bee2b1d7 100644 --- a/src/clean.c +++ b/src/clean.c @@ -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); } diff --git a/src/emit/emit.c b/src/emit/emit.c index 087cd29d..bd585800 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -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) diff --git a/src/import/import_udef.c b/src/import/import_udef.c index f49fb534..af9be60c 100644 --- a/src/import/import_udef.c +++ b/src/import/import_udef.c @@ -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); } diff --git a/src/lib/engine.c b/src/lib/engine.c index 6e4f8245..76b70b94 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -17,6 +17,10 @@ #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; diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 0c8a21c7..c98925d7 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -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)) diff --git a/src/parse/check.c b/src/parse/check.c index 2d537ab2..39108371 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -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) { diff --git a/src/parse/scan0.c b/src/parse/scan0.c index d9f18493..c8da51aa 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -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); diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 374c5c35..14c45322 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -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; diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 30f33763..5d8c0f5e 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -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; } diff --git a/tests/error/union.gw b/tests/error/union.gw index 7467b932..7619b016 100644 --- a/tests/error/union.gw +++ b/tests/error/union.gw @@ -1,4 +1,2 @@ #! [contains] -union { - one; two; -}; +union { one : two }; diff --git a/tests/error/union_array_empty.gw b/tests/error/union_array_empty.gw index 3310091a..0c99543b 100644 --- a/tests/error/union_array_empty.gw +++ b/tests/error/union_array_empty.gw @@ -1,5 +1,2 @@ #! [contains] must be defined with empty -union U { - int i; - int array[4]; -}; +union U { int : int [4] }; diff --git a/tests/error/union_global_private.gw b/tests/error/union_global_private.gw index 1e17f48a..98f3a2dd 100644 --- a/tests/error/union_global_private.gw +++ b/tests/error/union_global_private.gw @@ -1,2 +1,2 @@ #! [contains] can only be used at class scope. -union static U { int i; }; +union static U { int }; diff --git a/tests/error/union_global_private_static.gw b/tests/error/union_global_private_static.gw index 13e237e7..6c0b5b44 100644 --- a/tests/error/union_global_private_static.gw +++ b/tests/error/union_global_private_static.gw @@ -1,2 +1,2 @@ #! [contains] can only be used at class scope. -union private static U { int i; }; +union private static U { int }; diff --git a/tests/error/union_global_static.gw b/tests/error/union_global_static.gw index 1e748934..f1c95c51 100644 --- a/tests/error/union_global_static.gw +++ b/tests/error/union_global_static.gw @@ -1,2 +1,2 @@ #! [contains] can only be used at class scope. -union private U { int i; }; +union private U { int }; diff --git a/tests/error/union_unknown.gw b/tests/error/union_unknown.gw index ef81d7c3..633116b1 100644 --- a/tests/error/union_unknown.gw +++ b/tests/error/union_unknown.gw @@ -1,4 +1,2 @@ #! [contains] unknown_type -union U { - unknown_type unknown_variable; -} +union U { unknown_type unknown_variable } diff --git a/tests/plug/array_in_var_name_fail.c b/tests/plug/array_in_var_name_fail.c index 5f01d5a3..6963aaf2 100644 --- a/tests/plug/array_in_var_name_fail.c +++ b/tests/plug/array_in_var_name_fail.c @@ -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; } diff --git a/tests/plug/union.c b/tests/plug/union.c index 5dd8357f..fe8127af 100644 --- a/tests/plug/union.c +++ b/tests/plug/union.c @@ -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; } diff --git a/tests/plug/union_fail_exp.c b/tests/plug/union_fail_exp.c index 6d4bc044..fe6645fa 100644 --- a/tests/plug/union_fail_exp.c +++ b/tests/plug/union_fail_exp.c @@ -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; } diff --git a/tests/plug/union_member.c b/tests/plug/union_member.c index 4647dce8..65e2fcd2 100644 --- a/tests/plug/union_member.c +++ b/tests/plug/union_member.c @@ -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; diff --git a/tests/plug/union_name.c b/tests/plug/union_name.c index 671280d2..17cf8856 100644 --- a/tests/plug/union_name.c +++ b/tests/plug/union_name.c @@ -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; } diff --git a/tests/plug/union_tmpl.c b/tests/plug/union_tmpl.c index 83aee39e..637251b2 100644 --- a/tests/plug/union_tmpl.c +++ b/tests/plug/union_tmpl.c @@ -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; } diff --git a/tests/plug/union_tmpl_fail.c b/tests/plug/union_tmpl_fail.c index 83aee39e..637251b2 100644 --- a/tests/plug/union_tmpl_fail.c +++ b/tests/plug/union_tmpl_fail.c @@ -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; } diff --git a/tests/plug/union_tmpl_fail2.c b/tests/plug/union_tmpl_fail2.c index cc23bc1b..e8310372 100644 --- a/tests/plug/union_tmpl_fail2.c +++ b/tests/plug/union_tmpl_fail2.c @@ -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; diff --git a/tests/plug/union_tmpl_fail3.c b/tests/plug/union_tmpl_fail3.c index 83aee39e..637251b2 100644 --- a/tests/plug/union_tmpl_fail3.c +++ b/tests/plug/union_tmpl_fail3.c @@ -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; } diff --git a/tests/xxxfix/post_func.gw b/tests/xxxfix/post_func.gw index d4adfdbb..9c2b2d29 100644 --- a/tests/xxxfix/post_func.gw +++ b/tests/xxxfix/post_func.gw @@ -2,4 +2,4 @@ fun int add(int i) { return i + 3; } -<<< 2 $add>>>; +<<< 2 .add>>>; -- 2.43.0