From 51a1ad43016171f4e8ceca50b52d53179b09b8ea Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Wed, 22 Sep 2021 16:15:53 +0200 Subject: [PATCH] :art: update --- include/env/type.h | 1 + plug | 2 +- src/clean.c | 2 +- src/emit/emit.c | 4 +--- src/env/type.c | 3 ++- src/env/value.c | 3 --- src/lib/deep_equal.c | 31 ++++++++++++++++++++----------- src/lib/object_op.c | 21 +++++++++++++-------- src/parse/check.c | 20 ++++++++++++++------ src/parse/type_decl.c | 4 ++-- 10 files changed, 55 insertions(+), 36 deletions(-) diff --git a/include/env/type.h b/include/env/type.h index 168d55e8..5efc523e 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -38,6 +38,7 @@ enum tflag { tflag_contract = 1 << 19, tflag_float = 1 << 20, tflag_union = 1 << 21, + tflag_error = 1 << 22, } __attribute__((packed)); struct Type_ { diff --git a/plug b/plug index f88125de..ca543643 160000 --- a/plug +++ b/plug @@ -1 +1 @@ -Subproject commit f88125defdcc1ea298fae47b02c5c4b87b28ea5d +Subproject commit ca54364364765ea11af9d121cbdf6aab700aeb19 diff --git a/src/clean.c b/src/clean.c index f124e059..f3d965b6 100644 --- a/src/clean.c +++ b/src/clean.c @@ -51,7 +51,7 @@ ANN static void clean_prim(Clean *a, Exp_Primary *b) { ANN static void clean_var_decl(Clean *a, Var_Decl b) { if (b->array) clean_array_sub(a, b->array); - if (a->scope && b->value) value_remref(b->value, a->gwion); + if (a->scope && b->value && !tflag(b->value->type, tflag_error)) value_remref(b->value, a->gwion); } ANN static void clean_var_decl_list(Clean *a, Var_Decl_List b) { diff --git a/src/emit/emit.c b/src/emit/emit.c index 719e2558..e4d6f0bf 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -895,6 +895,7 @@ ANN static m_bool emit_exp_decl_static(const Emitter emit, const Exp_Decl *decl, ANN static Instr emit_struct_decl(const Emitter emit, const Value v, const bool emit_addr) { +printf("emit %s\n", v->name); emit_add_instr(emit, RegPushMem); const Instr instr = emit_structmember(emit, v->type->size, emit_addr); if (!emit_addr) { @@ -906,8 +907,6 @@ ANN static Instr emit_struct_decl(const Emitter emit, const Value v, ANN void unset_local(const Emitter emit, Local *const l) { l->instr->opcode = eNoOp; -// l->is_compound = false; -// l-> = false; for(m_uint i = m_vector_size(&emit->code->live_values) + 1; --i;) { VMValue vmval = *(VMValue*)(ARRAY_PTR((&emit->code->live_values)) + (i-1) * sizeof(VMValue)); if(vmval.offset != l->offset) continue; @@ -940,7 +939,6 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, f_instr *exec = (f_instr *)allocmember; if (!emit->env->scope->depth) emit_debug(emit, v); if (!vflag(v, vflag_member)) { -// v->from->offset = exp_self(decl)->data ? ((Local*)exp_self(decl)->data)->offset : emit_local(emit, type); v->from->offset = decl_non_static_offset(emit, decl, type); exec = (f_instr *)(allocword); if (GET_FLAG(v, late)) { // ref or emit_var ? diff --git a/src/env/type.c b/src/env/type.c index 0d2755c7..97b3302e 100644 --- a/src/env/type.c +++ b/src/env/type.c @@ -144,7 +144,8 @@ ANN bool is_fptr(const struct Gwion_ *gwion, const Type t) { return isa(actual_type(gwion, t), gwion->type[et_fptr]) > 0; } ANN inline bool is_class(const struct Gwion_ *gwion, const Type t) { - return isa(t, gwion->type[et_class]) > 0; +// return isa(t, gwion->type[et_class]) > 0; + return t->info->parent == gwion->type[et_class]; } ANN Type actual_type(const struct Gwion_ *gwion, const Type t) { diff --git a/src/env/value.c b/src/env/value.c index e64a5cbf..616c92e1 100644 --- a/src/env/value.c +++ b/src/env/value.c @@ -7,15 +7,12 @@ #define MAX(a, b) (a >= b ? a : b) ANN void free_value(Value a, Gwion gwion) { const Type t = a->type; -// if(t) { - if (t->size > SZ_INT && !vflag(a, vflag_func) && a->d.ptr) _mp_free(gwion->mp, t->size, a->d.ptr); else if (is_class(gwion, t)) type_remref(t, gwion); else if (vflag(a, vflag_inner)) type_remref(t, gwion); -// } mp_free(gwion->mp, ValueFrom, a->from); mp_free(gwion->mp, Value, a); diff --git a/src/lib/deep_equal.c b/src/lib/deep_equal.c index 11ec7109..e7e208fd 100644 --- a/src/lib/deep_equal.c +++ b/src/lib/deep_equal.c @@ -15,8 +15,6 @@ #define deep_any(_name, _data, action, ACTION, _test, _t, _op) \ static OP_##ACTION(op##action##_deep_##_t##_any) { \ Exp_Binary *bin = data; \ - _test(_name##_exp(_data, bin->lhs)); \ - _test(_name##_exp(_data, bin->rhs)); \ struct Op_Import opi = { \ .lhs = bin->lhs->type, \ .rhs = bin->rhs->type, \ @@ -26,10 +24,20 @@ static OP_##ACTION(op##action##_deep_##_t##_any) { \ }; \ return op_##_name(_data, &opi); \ } +static OP_CHECK(opck_deep_eq_any) { + Exp_Binary *bin = data; + bin->op = insert_symbol(env->gwion->st, "=="); + DECL_ON(const Type, t, = check_exp(env, exp_self(bin))); + return t; +} +static OP_CHECK(opck_deep_ne_any) { + Exp_Binary *bin = data; + bin->op = insert_symbol(env->gwion->st, "!="); + const Type t = check_exp(env, exp_self(bin)); + return !t ? env->gwion->type[et_error] : env->gwion->type[et_bool]; +} -deep_any(check, env, ck, CHECK, CHECK_ON, eq, ==); deep_any(emit, emit, em, EMIT, CHECK_BB, eq, ==); -deep_any(check, env, ck, CHECK, CHECK_ON, ne, !=); deep_any(emit, emit, em, EMIT, CHECK_BB, ne, !=); // get members of a specific type @@ -109,7 +117,7 @@ static OP_CHECK(opck_deep_equal) { const bool ret = deep_check(env, bin, &l, &r); vector_release(&l); vector_release(&r); - if(ret > 0) return env->gwion->type[et_bool]; + if(ret) return env->gwion->type[et_bool]; ERR_N(exp_self(bin)->pos, "no deep operation for: {G+/}%s{0} {+}%s{0} {G+/}%s{0}", bin->lhs->type->name, s_name(bin->op), bin->rhs->type->name); } @@ -156,9 +164,9 @@ struct DeepEmits { }; static void deep_emits_init(const Emitter emit, struct DeepEmits *ds) { - emit_add_instr(emit, RegMove)->m_val = -SZ_INT*2; - deep_emit_init(emit, ds->lhs, 0); - deep_emit_init(emit, ds->rhs, SZ_INT); + emit_add_instr(emit, RegMove)->m_val = -SZ_INT; + deep_emit_init(emit, ds->lhs, -SZ_INT); + deep_emit_init(emit, ds->rhs, 0); vector_init(&ds->acc); } @@ -174,7 +182,6 @@ ANN static void emit_deep_fail(const Emitter emit, const Vector v) { const Instr branch = (Instr)vector_at(v, i); branch->m_val = sz; } - emit_add_instr(emit, RegMove)->m_val = -SZ_INT; emit_add_instr(emit, RegSetImm)->m_val2 = -SZ_INT; } @@ -186,10 +193,12 @@ ANN static bool deep_emit(const Emitter emit, struct DeepEmits *ds) { struct Exp_ rexp = MK_DOT(emit, ds->rhs->tmp, rhs); struct Exp_ temp = MK_BIN(lexp, rexp, ds->bin); temp.type=emit->gwion->type[et_bool]; + if(tflag(lexp.type, tflag_struct)) + exp_setvar(&lexp, true); + if(tflag(rexp.type, tflag_struct)) + exp_setvar(&rexp, true); if(emit_exp(emit, &temp) < 0) return false; vector_add(&ds->acc, (m_uint)emit_add_instr(emit, BranchEqInt)); - const Instr pop = emit_add_instr(emit, RegMove); - pop->m_val = -SZ_INT; } const Instr jmp = emit_add_instr(emit, Goto); emit_deep_fail(emit, &ds->acc); diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 6155ae98..e2353320 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -378,10 +378,12 @@ static OP_EMIT(opem_not_object) { static OP_EMIT(opem_uncond_object) { const Vector v = &emit->code->instr; - const Instr back = (Instr)vector_at(v, vector_size(v) -2); - if (back->opcode == eGWOP_EXCEPT || (back->opcode == eOP_MAX && back->execute == fast_except)) { - free_instr(emit->gwion, back); - vector_rem(v, vector_size(v) - 2); + if(vector_size(v) >= 2) { + const Instr back = (Instr)vector_at(v, vector_size(v) -2); + if (back->opcode == eGWOP_EXCEPT || (back->opcode == eOP_MAX && back->execute == fast_except)) { + free_instr(emit->gwion, back); + vector_rem(v, vector_size(v) - 2); + } } emit_add_instr(emit, BranchNeqInt); return GW_OK; @@ -389,10 +391,13 @@ static OP_EMIT(opem_uncond_object) { static OP_EMIT(opem_cond_object) { const Vector v = &emit->code->instr; - const Instr back = (Instr)vector_at(v, vector_size(v) -2); - if (back->opcode == eGWOP_EXCEPT || (back->opcode == eOP_MAX && back->execute == fast_except)) { - free_instr(emit->gwion, back); - vector_rem(v, vector_size(v) - 2); + printf("size %lu\n", vector_size(v)); + if(vector_size(v) >= 2) { + const Instr back = (Instr)vector_at(v, vector_size(v) -2); + if (back->opcode == eGWOP_EXCEPT || (back->opcode == eOP_MAX && back->execute == fast_except)) { + free_instr(emit->gwion, back); + vector_rem(v, vector_size(v) - 2); + } } emit_add_instr(emit, BranchEqInt); return GW_OK; diff --git a/src/parse/check.c b/src/parse/check.c index e6fbe284..8147c744 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1097,6 +1097,8 @@ ANN static Type check_exp_lambda(const Env env, const Exp_If *exp_if NUSED) { ANN static Type check_exp_td(const Env env, Type_Decl **td) { DECL_OO(const Type, t, = known_type(env, *td)); + if(t == env->gwion->type[et_class]) + ERR_O(exp_self(td)->pos, "can't use {G+}Class{0} in type decl expression"); if (!is_func(env->gwion, t) || is_fptr(env->gwion, t)) return type_class(env->gwion, t); return t; @@ -1355,7 +1357,7 @@ ANN static m_bool match_case_exp(const Env env, Exp e) { e->next = next; CHECK_OB(t); Exp_Binary bin = {.lhs = base, .rhs = e, .op = op}; - struct Exp_ ebin = {.d = {.exp_binary = bin}}; + struct Exp_ ebin = {.d = {.exp_binary = bin}, .exp_type = ae_exp_binary}; struct Op_Import opi = {.op = op, .lhs = base->type, .rhs = e->type, @@ -1810,6 +1812,7 @@ ANN static bool class_def_has_body(const Env env, Ast ast) { } ANN static inline bool type_is_recurs(const Type t, const Type tgt) { +// if(tflag(tgt, tflag_union)) return false; return isa(tgt, t) > 0 || isa(t, tgt) > 0 || (tgt->info->tuple && vector_find(&tgt->info->tuple->contains, (m_uint)t) > -1); } @@ -1839,18 +1842,23 @@ ANN static bool recursive_value(const Env env, const Type t, const Value v) { type_remref(first, env->gwion); if(second->ref > 2) type_remref(second, env->gwion); - if(tgt != t && v->type == tgt && strncmp(tgt->name, "Option:[", 8)) - recursive_type_base(env, tgt); + if(v->from->owner_class->ref > 2) + type_remref(v->from->owner_class, env->gwion); + if(t->ref > 2) + type_remref(t, env->gwion); } + set_tflag(t, tflag_error); set_tflag(t, tflag_infer); set_tflag(tgt, tflag_infer); unset_tflag(t, tflag_check); unset_tflag(tgt, tflag_check); return true; } - if(v->type->nspc && !GET_FLAG(v, late) && + + if(t != tgt && v->type->nspc && !GET_FLAG(v, late) && strncmp(tgt->name, "Option:[", 8) && isa(tgt, env->gwion->type[et_compound]) > 0) return recursive_type(env, t, tgt); + return false; } @@ -1859,7 +1867,7 @@ ANN static bool recursive_type(const Env env, const Type t, const Type tgt) { struct scope_iter inner = {tgt->nspc->info->value, 0, 0}; bool error = false; while (scope_iter(&inner, &v) > 0) { - if(!GET_FLAG(v, late) && recursive_value(env, t, v)) { + if(!GET_FLAG(v, late) && v->type != tgt && recursive_value(env, t, v)) { error = true; } } @@ -1873,7 +1881,7 @@ ANN static m_bool recursive_type_base(const Env env, const Type t) { while (scope_iter(&iter, &value) > 0) { if (isa(value->type, env->gwion->type[et_compound]) < 0) continue; if (value->type->nspc && !GET_FLAG(value, late)) { - if(recursive_type(env, t, value->type)) { + if(/*value->type != t && */recursive_type(env, t, value->type)) { env_err(env, value->from->loc, _("recursive type")); gw_err("use {+G}late{0} on one (or more) of the variables?\n"); error = true; diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index c74f2408..a71d20e1 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -55,8 +55,8 @@ ANN static Type resolve(const Env env, Type_Decl *td) { const Context ctx = base->info->value->from->ctx; if (ctx && ctx->error) ERR_O(td->pos, _("type '%s' is invalid"), base->name) DECL_OO(const Type, type, = find1(env, base, td)); - const Type t = !td->ref ? type : ref(env, td); - const Type ret = !td->option ? t : option(env, td); + DECL_OO(const Type, t, = !td->ref ? type : ref(env, td)); + DECL_OO(const Type, ret, = !td->option ? t : option(env, td)); const Array_Sub array = last->array; return !array ? ret : array_type(env, ret, array->depth); } -- 2.43.0