From 1c693aa98089eeaa73294ead7e8260e1c1afb0db Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Wed, 16 Dec 2020 01:29:40 +0100 Subject: [PATCH] :art: Update --- ast | 2 +- include/import/checker.h | 6 +++++ src/lib/array.c | 13 +++++++++- src/lib/ptr.c | 19 ++++++++------- src/lib/tmpl_info.c | 3 ++- src/lib/union.c | 18 ++++++++++++++ src/parse/check.c | 6 ++--- src/parse/operator.c | 3 +-- tests/error/array_cast_err.gw | 2 +- tests/tree/class_named_union.gw | 30 ------------------------ tests/tree/class_union.gw | 9 ------- tests/tree/cpy_ast.gw | 4 ++-- tests/tree/global_named_union.gw | 8 ------- tests/tree/global_unnamed_union.gw | 6 ----- tests/tree/named_union.gw | 16 ------------- tests/tree/named_union_private_static.gw | 9 ------- tests/tree/named_union_static.gw | 11 --------- tests/tree/udef.gw | 3 --- tests/tree/union.gw | 2 -- tests/tree/union_global.gw | 2 -- tests/tree/union_tmpl.gw | 4 ---- tests/union/none.gw | 1 + tests/union/option.gw | 4 ++++ tests/union/option_check.gw | 9 +++++++ tests/union/option_invalid_runtime.gw | 3 +++ tests/union/union.gw | 10 ++++++++ 26 files changed, 84 insertions(+), 119 deletions(-) delete mode 100644 tests/tree/class_named_union.gw delete mode 100644 tests/tree/class_union.gw delete mode 100644 tests/tree/global_named_union.gw delete mode 100644 tests/tree/global_unnamed_union.gw delete mode 100644 tests/tree/named_union.gw delete mode 100644 tests/tree/named_union_private_static.gw delete mode 100644 tests/tree/named_union_static.gw delete mode 100644 tests/tree/udef.gw delete mode 100644 tests/tree/union.gw delete mode 100644 tests/tree/union_global.gw delete mode 100644 tests/tree/union_tmpl.gw create mode 100644 tests/union/none.gw create mode 100644 tests/union/option.gw create mode 100644 tests/union/option_check.gw create mode 100644 tests/union/option_invalid_runtime.gw create mode 100644 tests/union/union.gw diff --git a/ast b/ast index 607704e1..8fdf56e0 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 607704e19a25cd9985506c75fe600d2a4213aba1 +Subproject commit 8fdf56e0aabe91bcaded35c38d036e81a3a34432 diff --git a/include/import/checker.h b/include/import/checker.h index f7adeb71..3b81b40c 100644 --- a/include/import/checker.h +++ b/include/import/checker.h @@ -53,6 +53,12 @@ ANN Var_Decl str2var(const Gwion, const m_str, const loc_t); ANN Var_Decl_List str2varlist(const Gwion, const m_str, const loc_t); ANN Type_Decl* str2td(const Gwion, const m_str, const loc_t); ANN Type str2type(const Gwion, const m_str, const loc_t); +ANN static inline Type_Decl* type2td(const Gwion gwion, const Type t, const loc_t pos) { + const m_str str = type2str(gwion->env, t); + Type_Decl *td = str2td(gwion, str, pos); + free_mstr(gwion->mp, str); + return td; +} #define gwi_str2sym(gwi, path) str2sym(gwi->gwion, path, gwi->loc) #define gwi_str2symlist(gwi, path) str2symlist(gwi->gwion, path, gwi->loc) diff --git a/src/lib/array.c b/src/lib/array.c index 687e353f..af6d4301 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -272,7 +272,7 @@ static OP_CHECK(opck_array_cast) { r = r->info->parent; if(get_depth(cast->exp->info->type) == get_depth(exp_self(cast)->info->type) && isa(l->info->base_type, r->info->base_type) > 0) return l; - return env->gwion->type[et_error]; + return NULL; } static OP_CHECK(opck_array_slice) { @@ -335,6 +335,14 @@ static OP_CHECK(opck_array) { return check_array_access(env, &next); } +static OP_CHECK(opck_not_array) { + const Array_Sub array = (Array_Sub)data; + if(array->depth <= get_depth(array->type)) + return array->type; + ERR_N(array->exp->pos, _("array subscripts (%"UINT_F") exceeds defined dimension (%"UINT_F")"), + array->depth, get_depth(array->type)) +} + ANN static void array_loop(const Emitter emit, const m_uint depth) { const Instr pre_pop = emit_add_instr(emit, RegPop); pre_pop->m_val = depth * SZ_INT; @@ -432,6 +440,9 @@ GWION_IMPORT(array) { GWI_BB(gwi_oper_add(gwi, opck_array_slice)) GWI_BB(gwi_oper_emi(gwi, opem_array_slice)) GWI_BB(gwi_oper_end(gwi, "@slice", NULL)) + GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, (m_str)OP_ANY_TYPE, NULL)) + GWI_BB(gwi_oper_add(gwi, opck_not_array)) + GWI_BB(gwi_oper_end(gwi, "@array", NULL)) GWI_BB(gwi_oper_ini(gwi, "int", "@Array", NULL)) GWI_BB(gwi_oper_add(gwi, opck_array)) GWI_BB(gwi_oper_emi(gwi, opem_array_access)) diff --git a/src/lib/ptr.c b/src/lib/ptr.c index 35127ad3..fabd8c07 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -22,6 +22,10 @@ static m_bool ptr_access(const Env env, const Exp e) { ERR_B(e->pos, _("operand is %s"), access); } +ANN static inline Type ptr_base(const Env env, const Type t) { + return known_type(env, t->info->cdef->base.tmpl->call->td); +} + static OP_CHECK(opck_ptr_assign) { const Exp_Binary* bin = (Exp_Binary*)data; CHECK_BO(ptr_access(env, bin->lhs)) @@ -32,10 +36,10 @@ static OP_CHECK(opck_ptr_assign) { do { Type u = bin->rhs->info->type; do { - const m_str str = get_type_name(env, u, 1); - if(str && !strcmp(t->name, str)) - return bin->lhs->info->type; // use rhs? - } while((u = u->info->parent)); + const Type base = ptr_base(env, u); + if(isa(t, base) > 0) + return t; + } while((u = u->info->parent) && u->info->cdef->base.tmpl->call); } while((t = t->info->parent)); return env->gwion->type[et_error]; } @@ -66,8 +70,7 @@ static OP_EMIT(opem_ptr_assign) { static OP_CHECK(opck_ptr_deref) { const Exp_Unary* unary = (Exp_Unary*)data; - DECL_ON(const m_str, str, = get_type_name(env, unary->exp->info->type, 1)) - return exp_self(unary)->info->type = nspc_lookup_type1(env->curr, insert_symbol(str)); + return ptr_base(env, unary->exp->info->type); } static OP_CHECK(opck_ptr_cast) { @@ -88,8 +91,8 @@ static OP_CHECK(opck_ptr_cast) { static OP_CHECK(opck_ptr_implicit) { const struct Implicit* imp = (struct Implicit*)data; const Exp e = imp->e; - DECL_OO(const m_str, name, = get_type_name(env, imp->t, 1)) - if(!strcmp(get_type_name(env, imp->t, 1), e->info->type->name)) { + const Type base = ptr_base(env, imp->t); + if(isa(e->info->type, base) > 0) { const m_str access = exp_access(e); if(access) ERR_N(e->pos, _("can't cast %s value to Ptr"), access); diff --git a/src/lib/tmpl_info.c b/src/lib/tmpl_info.c index f9297e7e..535d462d 100644 --- a/src/lib/tmpl_info.c +++ b/src/lib/tmpl_info.c @@ -40,8 +40,9 @@ ANN static inline size_t tmpl_set(struct tmpl_info* info, const m_str str) { ANN static ssize_t template_size(const Env env, struct tmpl_info* info) { DECL_OB(const m_str, str, = tl2str(env, info->td->types)) + const size_t tmpl_sz = tmpl_set(info, str); const m_str base = type2str(env, info->base); - return tmpl_set(info, str) + tmpl_set(info, base) + 4; + return tmpl_sz + tmpl_set(info, base) + 4; } ANEW ANN static Symbol _template_id(const Env env, struct tmpl_info *const info, const size_t sz) { diff --git a/src/lib/union.c b/src/lib/union.c index f4a68913..f5d059d3 100644 --- a/src/lib/union.c +++ b/src/lib/union.c @@ -16,6 +16,19 @@ static GACK(gack_none) { INTERP_PRINTF("None") } +static OP_CHECK(opck_none) { + Exp_Binary *bin = (Exp_Binary*)data; + CHECK_NN(opck_rassign(env, data, mut)) + exp_setvar(bin->rhs, 1); + return bin->rhs->info->type; +} + +static OP_EMIT(opem_none) { + const Instr instr = emit_add_instr(emit, RegPop); + instr->m_val = SZ_INT; + return GW_OK; +} + static const f_instr dotmember[] = { DotMember, DotMember2, DotMember3, DotMember4 }; ANN Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]); @@ -90,6 +103,11 @@ ANN GWION_IMPORT(union) { struct SpecialId_ spid = { .type=gwi->gwion->type[et_none], .exec=NoOp, .is_const=1 }; gwi_specialid(gwi, "None", &spid); + GWI_BB(gwi_oper_ini(gwi, "None", "None", "None")) + GWI_BB(gwi_oper_add(gwi, opck_none)) + GWI_BB(gwi_oper_emi(gwi, opem_none)) + GWI_BB(gwi_oper_end(gwi, "=>", NoOp)) + const Type t_union = gwi_class_ini(gwi, "@Union", "Object"); gwi_class_xtor(gwi, NULL, UnionDtor); GWI_BB(gwi_item_ini(gwi, "int", "@index")) diff --git a/src/parse/check.c b/src/parse/check.c index 08b0c8c3..e1e5a103 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -393,9 +393,9 @@ ANN static Type check_prim(const Env env, Exp_Primary *prim) { } ANN Type check_array_access(const Env env, const Array_Sub array) { - if(!get_depth(array->type)) - ERR_O(array->exp->pos, _("array subscripts (%"UINT_F") exceeds defined dimension (%"UINT_F")"), - array->depth, get_depth(array->type)) +// if(!get_depth(array->type)) +// ERR_O(array->exp->pos, _("array subscripts (%"UINT_F") exceeds defined dimension (%"UINT_F")"), +// array->depth, get_depth(array->type)) const Symbol sym = insert_symbol("@array"); struct Op_Import opi = { .op=sym, .lhs=array->exp->info->type, .rhs=array->type, .pos=array->exp->pos, .data=(uintptr_t)array, .op_type=op_array }; diff --git a/src/parse/operator.c b/src/parse/operator.c index 93faab19..29101022 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -180,7 +180,7 @@ ANN Type op_check(const Env env, struct Op_Import* opi) { const Type ret = op_check_inner(&ock); if(ret) { if(ret == env->gwion->type[et_error]) - break; + return NULL; if(!ock.mut) set_nspc(&opi2, nspc); return ret; @@ -188,7 +188,6 @@ ANN Type op_check(const Env env, struct Op_Import* opi) { } while(l && (l = l->info->parent)); } } while((nspc = nspc->parent)); -// if(env->func && env->func->nspc) if(opi->op == insert_symbol(env->gwion->st, "$") && opi->rhs == opi->lhs) return opi->rhs; if(opi->op == insert_symbol(env->gwion->st, "@func_check")) diff --git a/tests/error/array_cast_err.gw b/tests/error/array_cast_err.gw index a270eb01..3e18f3a5 100644 --- a/tests/error/array_cast_err.gw +++ b/tests/error/array_cast_err.gw @@ -1,2 +1,2 @@ -#! [contains] no match found for operator +#! [contains] can't cast <<< [ 1 ] $ int[][] >>>; diff --git a/tests/tree/class_named_union.gw b/tests/tree/class_named_union.gw deleted file mode 100644 index a72232be..00000000 --- a/tests/tree/class_named_union.gw +++ /dev/null @@ -1,30 +0,0 @@ -class C { - 12 => var int _i; - union { - int i; - float f; - } U; - - <<< U >>>; - <<< U.i >>>; - <<< U.f >>>; - 12 => U.i; - <<< U.i >>>; - 12.3 => U.f; - <<< U.f >>>; - <<< U.i >>>; -} - -var C c; - -<<< c >>>; -<<< c.U >>>; -<<< c.U.i >>>; -<<< c.U.f >>>; -123 => c.U.i; -<<< c.U.i >>>; -1.23 => c.U.f; -<<< c.U.f >>>; -<<< c.U.i >>>; -<<< c._i >>>; - diff --git a/tests/tree/class_union.gw b/tests/tree/class_union.gw deleted file mode 100644 index 4a27e0e2..00000000 --- a/tests/tree/class_union.gw +++ /dev/null @@ -1,9 +0,0 @@ -class C { - union - { - int one; - string two; - }; - <<< one, " ", two >>>; -} - diff --git a/tests/tree/cpy_ast.gw b/tests/tree/cpy_ast.gw index 21ebaae0..3ffd53f7 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 U { int } - union V:[A] { int } + union U { int i; } + union V:[A] { int i; } typeof(i); if(i) i; else i; for(var int _i; _i < 1; ++_i); diff --git a/tests/tree/global_named_union.gw b/tests/tree/global_named_union.gw deleted file mode 100644 index 5eb4c3aa..00000000 --- a/tests/tree/global_named_union.gw +++ /dev/null @@ -1,8 +0,0 @@ -union global { - int int_from_global_nanmed_union; - float float_from_global_named_union; -} global_union; - -<<< "HERE", global_union >>>; -<<< 123.456 => global_union.float_from_global_named_union >>>; -<<< global_union.float_from_global_named_union >>>; diff --git a/tests/tree/global_unnamed_union.gw b/tests/tree/global_unnamed_union.gw deleted file mode 100644 index 9a1a2739..00000000 --- a/tests/tree/global_unnamed_union.gw +++ /dev/null @@ -1,6 +0,0 @@ -union global { - int int_from_global_union; - float float_from_global_union; -}; - -<<< float_from_global_union >>>; diff --git a/tests/tree/named_union.gw b/tests/tree/named_union.gw deleted file mode 100644 index 0735743e..00000000 --- a/tests/tree/named_union.gw +++ /dev/null @@ -1,16 +0,0 @@ -15 => var int i; -union { - int i; - float f; -} U; -7.3 => var float f; -<<< U >>>; -<<< U.i >>>; -<<< U.f >>>; -12 => U.i; -<<< U.i >>>; -12.3 => U.f; -<<< U.f >>>; -<<< U.i >>>; -<<< i >>>; -<<< f >>>; diff --git a/tests/tree/named_union_private_static.gw b/tests/tree/named_union_private_static.gw deleted file mode 100644 index 1e598323..00000000 --- a/tests/tree/named_union_private_static.gw +++ /dev/null @@ -1,9 +0,0 @@ -class C { - union private static { - int i; - } u; - <<< this, " ", u, " ", this.u.i >>>; -} - -var C c; -<<< c >>>; diff --git a/tests/tree/named_union_static.gw b/tests/tree/named_union_static.gw deleted file mode 100644 index 549480c6..00000000 --- a/tests/tree/named_union_static.gw +++ /dev/null @@ -1,11 +0,0 @@ -class C { - union static { - int i; - } u; - <<< this, " ", u, " ", this.u.i >>>; -} - -var C c; -<<< c >>>; -<<< C.u >>>; -<<< C.u.i >>>; diff --git a/tests/tree/udef.gw b/tests/tree/udef.gw deleted file mode 100644 index 9f08d2d3..00000000 --- a/tests/tree/udef.gw +++ /dev/null @@ -1,3 +0,0 @@ -class C { - union static { int : float } -} diff --git a/tests/tree/union.gw b/tests/tree/union.gw deleted file mode 100644 index fb01c1f9..00000000 --- a/tests/tree/union.gw +++ /dev/null @@ -1,2 +0,0 @@ -union U { int : string }; -<<< one, " ", two >>>; diff --git a/tests/tree/union_global.gw b/tests/tree/union_global.gw deleted file mode 100644 index 5c31d32a..00000000 --- a/tests/tree/union_global.gw +++ /dev/null @@ -1,2 +0,0 @@ -union global GlobalUnion { int : float }; -<<<"test">>>; diff --git a/tests/tree/union_tmpl.gw b/tests/tree/union_tmpl.gw deleted file mode 100644 index f4b22ea4..00000000 --- a/tests/tree/union_tmpl.gw +++ /dev/null @@ -1,4 +0,0 @@ -union U:[A]{ int : A } - -var U:[float] u; -<<< u.a >>>; diff --git a/tests/union/none.gw b/tests/union/none.gw new file mode 100644 index 00000000..1bb4787a --- /dev/null +++ b/tests/union/none.gw @@ -0,0 +1 @@ +None => None; diff --git a/tests/union/option.gw b/tests/union/option.gw new file mode 100644 index 00000000..d5c1c564 --- /dev/null +++ b/tests/union/option.gw @@ -0,0 +1,4 @@ +#! [contains] 12 +var int? i; +<<< 12 => i.val >>>; +<<< i.val >>>; diff --git a/tests/union/option_check.gw b/tests/union/option_check.gw new file mode 100644 index 00000000..81ed9990 --- /dev/null +++ b/tests/union/option_check.gw @@ -0,0 +1,9 @@ +#! [contains] 12 +var int? i; + +<<< 12 => i.val >>>; +if(i.is(val)) + <<< i.val >>>; +#!<<< None => i.none >>>; +#!if(i.is(none)) +#! <<< "option unset" >>>; diff --git a/tests/union/option_invalid_runtime.gw b/tests/union/option_invalid_runtime.gw new file mode 100644 index 00000000..b83406db --- /dev/null +++ b/tests/union/option_invalid_runtime.gw @@ -0,0 +1,3 @@ +#! [contains] invalid union acces +var int? i; +<<< i.val >>>; diff --git a/tests/union/union.gw b/tests/union/union.gw new file mode 100644 index 00000000..88d47c27 --- /dev/null +++ b/tests/union/union.gw @@ -0,0 +1,10 @@ +union U { + int i; + float f; +} + +var U u; +<<< u.i >>>; + +<<< u.f >>>; + -- 2.43.0