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) {
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) {