]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve ArrayAccess, again
authorfennecdjay <astor.jeremie@wanadoo.fr>
Sat, 17 Aug 2019 13:05:21 +0000 (15:05 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Sat, 17 Aug 2019 13:05:21 +0000 (15:05 +0200)
src/emit/emit.c
src/parse/check.c

index f3a14efd46ea106546d1f89b95de632bf884e0e1..a8cbef85d7dfcb5e2b3a5b7ba7d62a12cc0d605c 100644 (file)
@@ -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) {
index 4ba791520783babe6ce57d6b07bbd3b802ce5788..8f780625fc2270d4a0cda7f224e4b8dc71f2267d 100644 (file)
@@ -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) {