]> Nishi Git Mirror - gwion.git/commitdiff
:art: Typedefing array
authorfennecdjay <astor.jeremie@wanadoo.fr>
Tue, 16 Jul 2019 03:25:22 +0000 (05:25 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Tue, 16 Jul 2019 03:25:22 +0000 (05:25 +0200)
include/type.h
src/emit/emit.c
src/oo/type.c
src/parse/check.c
tests/new/typedefing_array.gw [new file with mode: 0644]

index a1c11a737db6b7b84c582ffaecd19a530ddffe77..082bf705dd5539dd3bf235828f60ac2e36c250ff 100644 (file)
@@ -50,6 +50,6 @@ ANN static inline m_uint env_push_type(const Env env, const Type type) { return
 ANN static inline m_bool is_fptr(const Type t) {
   return isa(actual_type(t), t_fptr) > 0;
 }
-
+ANN m_uint get_depth(const Type type);
 #endif
 
index 5831fbdb9dddd95d006f1ddc228e19026c4a3fde..e3771af87867d9e6ddb68b81a63d37d56ae76666 100644 (file)
@@ -396,16 +396,9 @@ ANN static m_bool prim_array(const Emitter emit, const Exp_Primary * primary) {
   return GW_OK;
 }
 
-ANN static m_uint get_depth(Type t) {
-  m_uint depth = 0;
-  do depth += t->array_depth;
-  while((t = t->e->parent));
-  return depth;
-}
-
 ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array* array) {
   const m_uint is_var = exp_self(array)->emit_var;
-  const m_uint depth = get_depth(array->base->type) - exp_self(array)->type->array_depth;
+  const m_uint depth = get_depth(array->base->type) - get_depth(exp_self(array)->type);
   CHECK_BB(emit_exp(emit, array->base, 0))
   emit_add_instr(emit, GcAdd);
   CHECK_BB(emit_exp(emit, array->array->exp, 0))
index ca36381c377f9ce76ced2be377502c1b2a3b8840..c9632d246145f2fac4032d2d819c7ef6be6e0e49 100644 (file)
@@ -162,6 +162,20 @@ ANN m_str get_type_name(const Env env, const m_str s, const m_uint index) {
   c[i] = '\0';
   return strlen(c) ? s_name(insert_symbol(c)) : NULL;
 }
+
+ANN m_uint get_depth(const Type type) {
+  m_uint depth = 0;
+  Type t = type;
+  do {
+    if(t->array_depth) {
+      depth += t->array_depth;
+      t = t->e->d.base_type;
+    } else
+      t = t->e->parent;
+  } while(t);
+  return depth;
+}
+
 Type t_void, t_int, t_bool, t_float, t_dur, t_time, t_now, t_complex, t_polar, t_vec3, t_vec4,
   t_null, t_object, t_shred, t_fork, t_event, t_ugen, t_string, t_ptr, t_array, t_gack,
   t_function, t_fptr, t_vararg, t_lambda, t_class, t_union, t_undefined, t_auto;
index 12bce2ed56ba7d6d003d61c3c12e309c736038b4..22f2f2c44306735592b68eb9f3b36f89afc513c0 100644 (file)
@@ -317,30 +317,39 @@ ANN static Type check_exp_primary(const Env env, const Exp_Primary* primary) {
   return exp_self(primary)->type = prim_func[primary->primary_type](env, primary);
 }
 
-ANN Type check_exp_array(const Env env, const Exp_Array* array) {
-  DECL_OO(Type, t_base,  = check_exp(env, array->base))
-  Exp e = array->array->exp;
-  CHECK_OO(check_exp(env, e))
+ANN Type at_depth(const Env env, const Type t, const m_uint depth) {
+  if(GET_FLAG(t, typedef))
+    return !depth ? t : at_depth(env, t->e->parent, depth);
+  if(depth > t->array_depth)
+    return at_depth(env, t->e->d.base_type, depth - t->array_depth);
+  return !depth ? t : array_type(env, array_base(t), t->array_depth - depth);
+}
+
+static inline m_bool index_is_int(const Env env, Exp e, m_uint *depth) {
+  do if(isa(e->type, t_int) < 0)
+    ERR_B(e->pos, _("array index %i must be of type 'int', not '%s'"),
+        *depth, e->type->name)
+  while(++(*depth) && (e = e->next));
+  return GW_OK;
+}
+
+static m_bool array_access_valid(const Env env, const Exp_Array* array) {
   m_uint depth = 0;
-  do {
-    if(isa(e->type, t_int) < 0)
-      ERR_O(e->pos, _("array index %i must be of type 'int', not '%s'"),
-            depth, e->type->name)
-  } while(++depth && (e = e->next));
+  CHECK_BB(index_is_int(env, array->array->exp, &depth))
   if(depth != array->array->depth)
-    ERR_O(exp_self(array)->pos, _("invalid array acces expression."))
-
-  while(t_base && array->array->depth > t_base->array_depth) {
-     depth -= t_base->array_depth;
-     if(t_base->e->parent)
-       t_base = t_base->e->parent;
-     else
-       ERR_O(exp_self(array)->pos,
-             _("array subscripts (%i) exceeds defined dimension (%i)"),
-             array->array->depth, t_base->array_depth)
-  }
-  return depth == t_base->array_depth ? array_base(t_base) :
-    array_type(env, array_base(t_base), t_base->array_depth - depth);
+    ERR_B(exp_self(array)->pos, _("invalid array acces expression."))
+  DECL_OB(const Type, t_base,  = check_exp(env, array->base))
+  if(depth > get_depth(t_base))
+    ERR_B(exp_self(array)->pos,
+      _("array subscripts (%i) exceeds defined dimension (%i)"),
+      array->array->depth, depth)
+  return GW_OK;
+}
+
+static ANN Type check_exp_array(const Env env, const Exp_Array* array) {
+  CHECK_OO(check_exp(env, array->array->exp))
+  CHECK_BO(array_access_valid(env, array))
+  return at_depth(env, array->base->type, array->array->depth);
 }
 
 ANN static Type_List mk_type_list(const Env env, const Type type) {
diff --git a/tests/new/typedefing_array.gw b/tests/new/typedefing_array.gw
new file mode 100644 (file)
index 0000000..18eccd7
--- /dev/null
@@ -0,0 +1,6 @@
+typedef int[1] Array;
+typedef Array[1] MyArray;
+MyArray a;
+<<< a >>>;
+<<< a[0] >>>;
+<<< a[0][0] >>>;