From 576c6230197785bebd44f10e4446500343ee5903 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Fri, 1 Oct 2021 13:34:15 +0200 Subject: [PATCH] :art: unary Fixes --- include/env/value.h | 21 +++++++++++---------- src/lib/opfunc.c | 2 ++ src/lib/prim.c | 9 ++++++--- src/parse/check.c | 16 ++++++++++------ tests/error/auto_fail.gw | 2 -- 5 files changed, 29 insertions(+), 21 deletions(-) delete mode 100644 tests/error/auto_fail.gw diff --git a/include/env/value.h b/include/env/value.h index 92000963..6c305aaf 100644 --- a/include/env/value.h +++ b/include/env/value.h @@ -10,16 +10,17 @@ struct ValueFrom_ { }; enum vflag { - vflag_none = 1 << 0, - vflag_func = 1 << 1, - vflag_fglobal = 1 << 2, - vflag_valid = 1 << 3, - vflag_direct = 1 << 4, - vflag_builtin = 1 << 5, - vflag_member = 1 << 6, - vflag_closed = 1 << 7, - vflag_inner = 1 << 8, // value is in a scope - vflag_release = 1 << 9 + vflag_none = 1 << 0, + vflag_func = 1 << 1, + vflag_fglobal = 1 << 2, + vflag_valid = 1 << 3, + vflag_direct = 1 << 4, + vflag_builtin = 1 << 5, + vflag_member = 1 << 6, + vflag_closed = 1 << 7, + vflag_inner = 1 << 8, // value is in a scope + vflag_release = 1 << 9, + vflag_assigned = 1 << 10 // vflag_used = 1 << 3 } __attribute__((packed)); diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 40fae1d4..ad4960a5 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -80,6 +80,7 @@ OP_CHECK(opck_unary) { _("unary operator '%s' cannot be used on %s data-types."), s_name(unary->op), access); exp_setvar(unary->exp, 1); + exp_setmeta(exp_self(unary), 1); return unary->exp->type; } @@ -91,6 +92,7 @@ OP_CHECK(opck_post) { _("post operator '%s' cannot be used on %s data-type."), s_name(post->op), access); exp_setvar(post->exp, 1); + exp_setmeta(exp_self(post), 1); return post->exp->type; } diff --git a/src/lib/prim.c b/src/lib/prim.c index db5e8a80..7a4fce26 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -235,8 +235,10 @@ static GWION_IMPORT(int_unary) { GWI_BB(gwi_oper_ini(gwi, NULL, "int", "int")) GWI_BB(gwi_oper_add(gwi, opck_int_negate)) GWI_BB(gwi_oper_end(gwi, "-", int_negate)) - CHECK_OP("++", unary, pre_inc) - CHECK_OP("--", unary, pre_dec) + GWI_BB(gwi_oper_add(gwi, opck_unary)) + GWI_BB(gwi_oper_end(gwi, "++", int_pre_inc)) + GWI_BB(gwi_oper_add(gwi, opck_unary)) + GWI_BB(gwi_oper_end(gwi, "--", int_pre_dec)) GWI_BB(gwi_oper_add(gwi, opck_int_cmp)) GWI_BB(gwi_oper_end(gwi, "~", int_cmp)) GWI_BB(gwi_oper_ini(gwi, NULL, "int", NULL)) @@ -244,7 +246,8 @@ static GWION_IMPORT(int_unary) { GWI_BB(gwi_oper_emi(gwi, opem_int_range)) GWI_BB(gwi_oper_end(gwi, "@range", NULL)) GWI_BB(gwi_oper_ini(gwi, "int", NULL, "int")) - CHECK_OP("++", post, post_inc) + GWI_BB(gwi_oper_add(gwi, opck_post)) + GWI_BB(gwi_oper_end(gwi, "++", int_post_inc)) GWI_BB(gwi_oper_add(gwi, opck_post)) GWI_BB(gwi_oper_end(gwi, "--", int_post_dec)) return GW_OK; diff --git a/src/parse/check.c b/src/parse/check.c index 6b1ac31c..521a0161 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -869,11 +869,15 @@ ANN Type check_exp_call1(const Env env, Exp_Call *const exp) { ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) { CHECK_OO(check_exp(env, bin->lhs)); - const m_bool is_auto = bin->rhs->exp_type == ae_exp_decl && + const m_bool is_auto = (bin->op == insert_symbol("=>") || bin->op == insert_symbol("@=>")) && + bin->rhs->exp_type == ae_exp_decl && bin->rhs->d.exp_decl.type == env->gwion->type[et_auto]; if (is_auto) bin->rhs->d.exp_decl.type = bin->lhs->type; CHECK_OO(check_exp(env, bin->rhs)); - if (is_auto) bin->rhs->type = bin->lhs->type; + if (is_auto) { + bin->rhs->type = bin->lhs->type; + set_vflag(bin->rhs->d.exp_decl.list->self->value, vflag_assigned); + } struct Op_Import opi = {.op = bin->op, .lhs = bin->lhs->type, .rhs = bin->rhs->type, @@ -1857,7 +1861,7 @@ ANN static bool recursive_value(const Env env, const Type t, const Value v) { return true; } - if(t != tgt && v->type->nspc && !GET_FLAG(v, late) && strncmp(tgt->name, "Option:[", 8) && + if(t != tgt && v->type->nspc && (!GET_FLAG(v, late) || vflag(v, vflag_assigned)) && strncmp(tgt->name, "Option:[", 8) && isa(tgt, env->gwion->type[et_compound]) > 0) return recursive_type(env, t, tgt); @@ -1869,7 +1873,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) && v->type != tgt && recursive_value(env, t, v)) { + if((!GET_FLAG(v, late) || vflag(v, vflag_assigned)) && v->type != tgt && recursive_value(env, t, v)) { error = true; } } @@ -1882,8 +1886,8 @@ ANN static m_bool recursive_type_base(const Env env, const Type t) { struct scope_iter iter = {t->nspc->info->value, 0, 0}; 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(/*value->type != t && */recursive_type(env, t, value->type)) { + if (value->type->nspc && (!GET_FLAG(value, late) || vflag(value, vflag_assigned))) { + 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/tests/error/auto_fail.gw b/tests/error/auto_fail.gw deleted file mode 100644 index 33976383..00000000 --- a/tests/error/auto_fail.gw +++ /dev/null @@ -1,2 +0,0 @@ -#! [contains] no match found for operator -var int i => var auto ae :=> var auto A; -- 2.43.0