From: fennecdjay Date: Tue, 16 Jul 2019 03:25:22 +0000 (+0200) Subject: :art: Typedefing array X-Git-Tag: nightly~2329 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=e0f1742beab878ce793c1569d6eeccf113a9751b;p=gwion.git :art: Typedefing array --- diff --git a/include/type.h b/include/type.h index a1c11a73..082bf705 100644 --- a/include/type.h +++ b/include/type.h @@ -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 diff --git a/src/emit/emit.c b/src/emit/emit.c index 5831fbdb..e3771af8 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -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)) diff --git a/src/oo/type.c b/src/oo/type.c index ca36381c..c9632d24 100644 --- a/src/oo/type.c +++ b/src/oo/type.c @@ -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; diff --git a/src/parse/check.c b/src/parse/check.c index 12bce2ed..22f2f2c4 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -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 index 00000000..18eccd7e --- /dev/null +++ b/tests/new/typedefing_array.gw @@ -0,0 +1,6 @@ +typedef int[1] Array; +typedef Array[1] MyArray; +MyArray a; +<<< a >>>; +<<< a[0] >>>; +<<< a[0][0] >>>;