From: fennecdjay Date: Sat, 17 Aug 2019 13:05:21 +0000 (+0200) Subject: :art: Improve ArrayAccess, again X-Git-Tag: nightly~2274 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=c974c85bd96d89a3af0bfbc7dd56e69abc4b6b4f;p=gwion.git :art: Improve ArrayAccess, again --- diff --git a/src/emit/emit.c b/src/emit/emit.c index f3a14efd..a8cbef85 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -484,24 +484,26 @@ ANN static inline Exp emit_n_exp(const Emitter emit, struct ArrayAccessInfo *co return ret > 0 ? next : NULL; } +ANN static inline m_bool emit_partial_indexes(const Emitter emit, struct ArrayAccessInfo *const info) { + struct Array_Sub_ partial = { info->array.exp, info->array.type, info->array.type->array_depth }; + struct Array_Sub_ next = { info->array.exp, array_base(info->array.type), info->array.depth - info->array.type->array_depth }; + info->array = partial; + DECL_OB(const Exp, exp, = emit_n_exp(emit, info)) + next.exp = exp; + info->array = next; + return _emit_indexes(emit, info); +} + ANN static inline m_bool _emit_indexes(const Emitter emit, struct ArrayAccessInfo *const info) { if(GET_FLAG(info->array.type, typedef)) { info->array.type = info->array.type->e->parent; return _emit_indexes(emit, info); } - if(!info->array.type->array_depth) - return tuple_index(emit, info); if(info->array.type->array_depth >= info->array.depth) { struct Array_Sub_ next = { info->array.exp, info->type, info->array.depth }; return array_do(emit, &next, info->is_var); } - struct Array_Sub_ partial = { info->array.exp, info->array.type, info->array.depth - info->array.type->array_depth }; - struct Array_Sub_ next = { info->array.exp, array_base(info->array.type), info->array.depth - info->array.type->array_depth }; - info->array = partial; - DECL_OB(const Exp, exp, = emit_n_exp(emit, info)) - next.exp = exp; - info->array = next; - return _emit_indexes(emit, info); + return (info->array.type->array_depth ? emit_partial_indexes : tuple_index)(emit, info); } ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array* array) { diff --git a/src/parse/check.c b/src/parse/check.c index 4ba79152..8f780625 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -364,37 +364,40 @@ static inline Exp take_exp(Exp e, m_uint n) { return e; } +ANN static Type at_depth(const Env env, const Array_Sub array); +ANN static Type tuple_depth(const Env env, const Array_Sub array) { + if(array->exp->exp_type != ae_exp_primary || + array->exp->d.exp_primary.primary_type != ae_primary_num) + ERR_O(array->exp->pos, _("tuple subscripts must be litteral")) + const m_uint idx = array->exp->d.exp_primary.d.num; + const Type type = (Type)vector_at(&array->type->e->tuple->types, idx); + if(type == t_undefined) + ERR_O(array->exp->pos, _("tuple subscripts is undefined")) + if(!array->exp->next) + return type; + struct Array_Sub_ next = { array->exp->next, type, array->depth - 1 }; + return at_depth(env, &next); +} + +ANN static Type partial_depth(const Env env, const Array_Sub array) { + const Exp curr = take_exp(array->exp, array->type->array_depth); + if(!curr->next) + ERR_O(array->exp->pos, _("array subscripts (%i) exceeds defined dimension (%i)"), + array->depth, get_depth(array->type)) + struct Array_Sub_ next = { curr->next, array_base(array->type), array->depth - array->type->array_depth }; + return at_depth(env, &next); +} + ANN static Type at_depth(const Env env, const Array_Sub array) { const Type t = array->type; const m_uint depth = array->depth; - const Exp e = array->exp; - if(!depth) - return t; if(GET_FLAG(t, typedef)) { - struct Array_Sub_ next = { e, t->e->parent, depth }; + struct Array_Sub_ next = { array->exp, t->e->parent, depth }; return at_depth(env, &next); } - if(depth > t->array_depth) { - const Exp curr = take_exp(e, t->array_depth); - const Type t_base = array_base(t) ?: t; - if(isa(t_base, t_tuple) > 0) { - if(curr->exp_type != ae_exp_primary || - curr->d.exp_primary.primary_type != ae_primary_num) - ERR_O(e->pos, _("tuple subscripts must be litteral")) - const m_uint idx = curr->d.exp_primary.d.num; - const Type type = (Type)vector_at(&t_base->e->tuple->types, idx); - if(type == t_undefined) - ERR_O(e->pos, _("tuple subscripts is undefined")) - struct Array_Sub_ next = { curr->next, type, depth - t->array_depth - 1 }; - return at_depth(env, &next); - } - if(!curr->next) - ERR_O(e->pos, _("array subscripts (%i) exceeds defined dimension (%i)"), - depth, get_depth(t)) - struct Array_Sub_ next = { curr->next, t_base, depth - t->array_depth }; - return at_depth(env, &next); - } - return array_type(env, array_base(t), t->array_depth - depth); + if(t->array_depth >= depth) + return array_type(env, array_base(array->type), t->array_depth - depth); + return (isa(t, t_tuple) < 0 ? partial_depth : tuple_depth)(env, array); } static inline m_bool index_is_int(const Env env, Exp e, m_uint *depth) {