From b637b3f4465f240afa2c710541ff0dc22108c9c5 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 16 Jul 2022 17:32:12 +0200 Subject: [PATCH] :art: Improve late and array semantics --- include/parse.h | 2 ++ src/lib/opfunc.c | 4 ++++ src/parse/scan1.c | 20 +++++++++++++++----- tests/array/array0.gw | 7 +++++++ tests/array/array1.gw | 3 +++ tests/array/array2.gw | 1 + tests/array/array3.gw | 3 +++ tests/error/abstract_array.gw | 2 +- tests/error/invalid_array_acces.gw | 2 +- 9 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 tests/array/array0.gw create mode 100644 tests/array/array1.gw create mode 100644 tests/array/array2.gw create mode 100644 tests/array/array3.gw diff --git a/include/parse.h b/include/parse.h index 6617a81e..fd03f95e 100644 --- a/include/parse.h +++ b/include/parse.h @@ -120,4 +120,6 @@ ANN static inline bool not_upvalue(const Env env, const Value v) { (v->from->owner_class && isa(v->from->owner_class, env->class_def) > 0) || nspc_lookup_value1(env->curr, insert_symbol(v->name)); } + +ANN m_bool abstract_array(const Env env, const Array_Sub array); #endif diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 41fbf850..f9a46ce2 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -118,6 +118,10 @@ OP_CHECK(opck_new) { Exp_Unary *unary = (Exp_Unary *)data; const Array_Sub array = unary->ctor.td->array; DECL_ON(const Type, t, = known_type(env, unary->ctor.td)); + if(array) { + const Type base = array_base(t); + if(GET_FLAG(base, abstract)) CHECK_BB(abstract_array(env, array)); + } CHECK_BN(ensure_traverse(env, t)); if (type_ref(t)) ERR_N(unary->ctor.td->pos, _("can't use 'new' on ref type '%s'\n"), t->name); diff --git a/src/parse/scan1.c b/src/parse/scan1.c index b04f1818..24710be2 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -96,8 +96,14 @@ static inline bool array_ref(const Array_Sub array) { return array && !array->exp; } -static inline bool array_ref2(const Array_Sub array) { - return array && !(array->exp && exp_is_zero(array->exp)); +ANN m_bool abstract_array(const Env env, const Array_Sub array) { + Exp e = array->exp; + while(e) { + if(!exp_is_zero(e)) + ERR_B(e->pos, _("arrays of abstract type should use `0` size")); + e = e->next; + } + return GW_OK; } ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) { @@ -107,9 +113,13 @@ ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) { Type t = decl->type; CHECK_BB(scan1_defined(env, vd)); const Type base = array_base_simple(t); - if ((!GET_FLAG(decl->td, late) && GET_FLAG(base, abstract)) && array_ref2(decl->td->array)) - ERR_B(vd->pos, _("arrays of abstract type '%s' must be declared empty"), - base->name); + if(decl->td->array) { + if (!GET_FLAG(decl->td, late) && !decl->td->array->exp) + ERR_B(decl->td->pos, _("arrays with no expressions should be declared `late`")); + if (GET_FLAG(decl->td, late) && decl->td->array->exp) + ERR_B(decl->td->array->exp->pos, _("late array should have no size")); + if (GET_FLAG(base, abstract)) CHECK_BB(abstract_array(env, decl->td->array)); + } const Value v = vd->value = vd->value ?: new_value(env, t, s_name(vd->xid), vd->pos); nspc_add_value(env->curr, vd->xid, v); diff --git a/tests/array/array0.gw b/tests/array/array0.gw new file mode 100644 index 00000000..b091f579 --- /dev/null +++ b/tests/array/array0.gw @@ -0,0 +1,7 @@ +class abstract C { + +} + +class D { + var C[2] modules; +} diff --git a/tests/array/array1.gw b/tests/array/array1.gw new file mode 100644 index 00000000..7117ca82 --- /dev/null +++ b/tests/array/array1.gw @@ -0,0 +1,3 @@ +class abstract C {} + +late C[2] c; diff --git a/tests/array/array2.gw b/tests/array/array2.gw new file mode 100644 index 00000000..59978267 --- /dev/null +++ b/tests/array/array2.gw @@ -0,0 +1 @@ +var int[] i; diff --git a/tests/array/array3.gw b/tests/array/array3.gw new file mode 100644 index 00000000..cbce2289 --- /dev/null +++ b/tests/array/array3.gw @@ -0,0 +1,3 @@ +class abstract C {} + +new C[2]; diff --git a/tests/error/abstract_array.gw b/tests/error/abstract_array.gw index d89b9016..841e285d 100644 --- a/tests/error/abstract_array.gw +++ b/tests/error/abstract_array.gw @@ -1,2 +1,2 @@ -#! [contains] must be declared empty +#! [contains] arrays of abstract type var Shred[12] shreds; diff --git a/tests/error/invalid_array_acces.gw b/tests/error/invalid_array_acces.gw index cee8891e..86ee14e4 100644 --- a/tests/error/invalid_array_acces.gw +++ b/tests/error/invalid_array_acces.gw @@ -1,3 +1,3 @@ #! [contains] invalid array access expression -var int[] j; +var int[2] j; j[1,2,3,4] => i; -- 2.43.0