From: Jérémie Astor Date: Sun, 13 Dec 2020 20:58:28 +0000 (+0100) Subject: :art: Cleaning X-Git-Tag: nightly~1105^2~29 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=6f07d402f36c105b4c6304fe105ed023465656d4;p=gwion.git :art: Cleaning --- diff --git a/include/lang_private.h b/include/lang_private.h index f3351265..caa2f380 100644 --- a/include/lang_private.h +++ b/include/lang_private.h @@ -13,4 +13,5 @@ ANN m_bool import_func(const Gwi gwi); ANN m_bool import_modules(const Gwi gwi); ANN m_bool import_object_op(const Gwi gwi); ANN m_bool import_values(const Gwi gwi); +ANN m_bool import_union(const Gwi gwi); #endif diff --git a/src/lib/engine.c b/src/lib/engine.c index 1c23b826..14711919 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -1,4 +1,3 @@ -#include #include "gwion_util.h" #include "gwion_ast.h" #include "gwion_env.h" @@ -6,21 +5,14 @@ #include "instr.h" #include "object.h" #include "emit.h" -#include "vm.h" #include "gwion.h" #include "operator.h" #include "import.h" #include "gwi.h" -#include "engine.h" #include "lang_private.h" #include "specialid.h" #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) @@ -81,149 +73,6 @@ 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 - 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 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); - 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) { - 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/SZ_INT + 1; - instr->m_val = lhs->size; - return instr; - } - } - return NULL; -} - -static OP_CHECK(opck_union_at_any) { - 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) { - 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*2); - 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/SZ_INT + 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]; - } - 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) = (UNION_IDX(o) == instr->m_val2); - _release(o, shred); -} - -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); - 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/SZ_INT + 1; - return instr; - } - } - return NULL; -} - -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-1) * SZ_INT); - if(isa(t, shred->info->vm->gwion->type[et_compound]) > 0) - compound_release(shred, t, (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); @@ -265,26 +114,8 @@ 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_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 = { .type=gwi->gwion->type[et_none], .exec=NoOp, .is_const=1 }; - gwi_specialid(gwi, "None", &spid); -} - 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)) @@ -315,6 +146,7 @@ ANN static m_bool import_core_libs(const Gwi gwi) { GWI_BB(import_string(gwi)) GWI_BB(import_shred(gwi)) GWI_BB(import_modules(gwi)) + GWI_BB(import_union(gwi)) GWI_BB(gwi_oper_ini(gwi, "@Class", "@Class", "int")) GWI_BB(gwi_oper_end(gwi, "==", int_eq)) @@ -338,31 +170,6 @@ 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_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_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, "A")) - GWI_BB(gwi_union_add(gwi, "None")) - GWI_BB(gwi_union_end(gwi, ae_flag_none)) - return GW_OK; } diff --git a/src/lib/union.c b/src/lib/union.c new file mode 100644 index 00000000..e285d03b --- /dev/null +++ b/src/lib/union.c @@ -0,0 +1,204 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "gwion_env.h" +#include "vm.h" +#include "instr.h" +#include "object.h" +#include "emit.h" +#include "gwion.h" +#include "operator.h" +#include "import.h" +#include "gwi.h" +#include "specialid.h" +#include "gack.h" + +#define UNION_IDX(a) (*(m_uint*)(a->data)) + +static GACK(gack_none) { + INTERP_PRINTF("None") +} + +static OP_CHECK(opck_any_at_union) { + Exp_Binary *bin = (Exp_Binary*)data; + CHECK_NN(opck_rassign(env, data, mut)) // check those two lines + 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 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); + 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) { + 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/SZ_INT + 1; + instr->m_val = lhs->size; + return instr; + } + } + return NULL; +} + +static OP_CHECK(opck_union_at_any) { + 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) { + 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*2); + 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/SZ_INT + 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]; + } + 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) = (UNION_IDX(o) == instr->m_val2); + _release(o, shred); +} + +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); + 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/SZ_INT + 1; + return instr; + } + } + return NULL; +} + +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-1) * SZ_INT); + if(isa(t, shred->info->vm->gwion->type[et_compound]) > 0) + compound_release(shred, t, (o->data + SZ_INT)); + } +} + +ANN GWION_IMPORT(union) { + 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 = { .type=gwi->gwion->type[et_none], .exec=NoOp, .is_const=1 }; + gwi_specialid(gwi, "None", &spid); + + 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->gwion->type[et_union] = t_union; + + 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_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_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, "A")) + GWI_BB(gwi_union_add(gwi, "None")) + GWI_BB(gwi_union_end(gwi, ae_flag_none)) + + return GW_OK; +}