From: Jérémie Astor Date: Fri, 11 Sep 2020 10:51:34 +0000 (+0200) Subject: :art: Improve special types X-Git-Tag: nightly~1348 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=ea17d2c687f7f10f144cadb09e5a69de25fdacab;p=gwion.git :art: Improve special types --- diff --git a/include/env/type.h b/include/env/type.h index 44cc592a..0ff7e13f 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -54,6 +54,14 @@ ANN static inline Type get_gack(Type t) { return t; // unreachable } +__attribute__((returns_nonnull)) +ANN Type unflag_type(const Type t); +__attribute__((returns_nonnull)) +ANN Type get_type(const Type t); +ANN static inline int is_special(const Type t) { + return GET_FLAG(t, nonnull) || GET_FLAG(t, force); +} + typedef enum { et_void, et_int, et_bool, et_char, et_float, et_null, et_compound, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack, diff --git a/include/parse.h b/include/parse.h index 320db9b4..62889984 100644 --- a/include/parse.h +++ b/include/parse.h @@ -81,10 +81,6 @@ xxx_cdef(traverse) ANN m_bool scanx_fdef(const Env, void *, const Func_Def, const _exp_func); -__attribute__((returns_nonnull)) -ANN Type unflag_type(const Type t); -__attribute__((returns_nonnull)) -ANN Type get_type(const Type t); ANN m_bool check_subscripts(const Env, const Array_Sub, const m_bool is_decl); ANN m_bool check_implicit(const Env env, const Exp e, const Type t); ANN m_bool ensure_traverse(const Env env, const Type t); diff --git a/src/emit/emit.c b/src/emit/emit.c index f79bacdf..dc582028 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -166,7 +166,7 @@ ANN m_uint emit_local(const Emitter emit, const Type t) { ANN void emit_ext_ctor(const Emitter emit, const Type t); ANN static inline void maybe_ctor(const Emitter emit, const Type t) { - if(!GET_FLAG(t, nonnull) && GET_FLAG(t, ctor)) + if(!is_special(t) && GET_FLAG(t, ctor)) emit_ext_ctor(emit, t); } @@ -891,12 +891,6 @@ ANN static m_bool emit_exp_post(const Emitter emit, const Exp_Postfix* post) { return op_emit_bool(emit, &opi); } -ANN static inline m_bool is_special(const Emitter emit, const Type t) { - return isa(t, emit->gwion->type[et_object]) < 0 && - isa(t, emit->gwion->type[et_class]) < 0 ? - GW_OK : GW_ERROR; -} - ANN static inline m_bool traverse_emit_func_def(const Emitter emit, const Func_Def fdef) { if(!fdef->base->ret_type) CHECK_BB(traverse_func_def(emit->env, fdef)) @@ -1080,7 +1074,7 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) { instr->m_val2 = -SZ_INT; } } - } else if((f->value_ref->from->owner_class && is_special(emit, f->value_ref->from->owner_class) > 0) || + } else if((f->value_ref->from->owner_class && GET_FLAG(f->value_ref->from->owner_class, struct)) || !f->value_ref->from->owner_class || (GET_FLAG(f, template) && !is_fptr(emit->gwion, f->value_ref->type))) push_func_code(emit, f); diff --git a/src/env/type_special.c b/src/env/type_special.c index baea495e..9a7c8143 100644 --- a/src/env/type_special.c +++ b/src/env/type_special.c @@ -22,7 +22,7 @@ ANN static Type specialtype_create(const Env env, const SpecialType *s) { ADD_REF(t->nspc) t->name = s_name(s->name); t->flag = s->type->flag | s->flag; - t->e->parent = s->type; + t->e->parent = unflag_type(s->type); nspc_add_type_front(s->type->e->owner, s->name, t); mk_class(env, t); return t; @@ -59,4 +59,3 @@ ANN Type special_type(const Env env, const Type t, const uint st_type) { return nspc_lookup_type1(t->e->owner, s.name) ?: specialtype_create(env, &s); } - diff --git a/src/import/oper.c b/src/import/oper.c index 79b41d8e..adcb6004 100644 --- a/src/import/oper.c +++ b/src/import/oper.c @@ -25,15 +25,15 @@ ANN static Type _get_type(const Gwi gwi, const m_str s) { return t; } -ANN2(1) static inline Type get_type(const Gwi gwi, const m_str str) { +ANN2(1) static inline Type gwi_get_type(const Gwi gwi, const m_str str) { return str ? _get_type(gwi, str) : NULL; } ANN2(1,2) static int import_op(const Gwi gwi, const struct OperCK* op, const f_instr f) { - const Type lhs = get_type(gwi, op->lhs), - rhs = get_type(gwi, op->rhs), - ret = get_type(gwi, op->ret); + const Type lhs = gwi_get_type(gwi, op->lhs), + rhs = gwi_get_type(gwi, op->rhs), + ret = gwi_get_type(gwi, op->ret); const struct Op_Func opfunc = { .ck=op->ck, .em=op->em }; const struct Op_Import opi = { .lhs=lhs, .rhs=rhs, .ret=ret, .func=&opfunc, .data=(uintptr_t)f, .pos=gwi->loc, .op=op->sym }; diff --git a/src/lib/object.c b/src/lib/object.c index 77552845..4127707a 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -65,9 +65,7 @@ ANN void __release(const M_Object o, const VM_Shred shred) { MemPool p = shred->info->mp; Type t = o->type_ref; do { - if(GET_FLAG(t, nonnull)) - t = t->e->parent; - if(!t->nspc) + if(!t->nspc || is_special(t)) continue; struct scope_iter iter = { t->nspc->info->value, 0, 0 };\ Value v; diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 5f98c8fb..444b49c1 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -74,10 +74,18 @@ OP_CHECK(opck_post) { return post->exp->info->type; } +ANN Type check_td(const Env env, Type_Decl *td); +ANN static inline Type check_new_td(const Env env, Type_Decl *td) { + if(!td->exp) + return known_type(env, td); + DECL_OO(const Type, t, = check_exp(env, td->exp)) + return actual_type(env->gwion, t); +} + OP_CHECK(opck_new) { const Exp_Unary* unary = (Exp_Unary*)data; SET_FLAG(unary->td, ref); - DECL_ON(const Type, t, = known_type(env, unary->td)) + DECL_ON(const Type, t, = check_new_td(env, unary->td)) if(isa(t, env->gwion->type[et_object]) < 0) ERR_N(exp_self(unary)->pos, _("can't use 'new' on non-object types...\n")) if(type_ref(t)) diff --git a/src/parse/check.c b/src/parse/check.c index b00a7330..85b04535 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -88,7 +88,7 @@ ANN static inline m_bool check_td_exp(const Env env, Type_Decl *td) { RET_NSPC(traverse_exp(env, td->exp)) } -ANN static Type check_td(const Env env, Type_Decl *td) { +ANN Type check_td(const Env env, Type_Decl *td) { CHECK_BO(check_td_exp(env, td)) const Type t = actual_type(env->gwion, td->exp->info->type); assert(t);