From 02b0ee256babc222d99c778fd19043c09e896e37 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Wed, 13 May 2020 11:15:34 +0200 Subject: [PATCH] :art: Utility function --- include/env/env.h | 7 ++++--- include/env/type.h | 1 - include/gwion.h | 9 +++++++++ include/gwion_env.h | 1 + include/parse.h | 2 ++ src/env/type_special.c | 13 ++++++++----- src/lib/object_op.c | 12 +++--------- src/parse/check.c | 10 ++++------ src/parse/scanx.c | 8 +++++++- 9 files changed, 38 insertions(+), 25 deletions(-) diff --git a/include/env/env.h b/include/env/env.h index 3dd54d75..bab36025 100644 --- a/include/env/env.h +++ b/include/env/env.h @@ -42,9 +42,10 @@ ANN Value mk_class(const Env env, const Type base); ANEW ANN m_str tl2str(const Env, const Type_List); // in type_decl.c ANN m_bool compat_func(const __restrict__ Func_Def, const __restrict__ Func_Def); ANN Type known_type(const Env env, Type_Decl*); -ANN Type special_type(SymTable*, const Type, const uint); -#define nonnul_type(a, b) special_type((a)->gwion->st, (b), 0); -#define force_type(a, b) special_type((a)->gwion->st, (b), 1); +__attribute__((returns_nonnull)) +ANN Type special_type(const Env, const Type, const uint); +#define nonnul_type(a, b) special_type(a, (b), 0); +#define force_type(a, b) special_type(a, (b), 1); ANN Type prim_ref(const Env env, const Type t, const Type_Decl* td); ANN m_bool env_access(const Env env, const ae_flag flag, const loc_t pos); ANN m_bool env_storage(const Env env, ae_flag flag, const loc_t pos); diff --git a/include/env/type.h b/include/env/type.h index ea029742..ff7284b0 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -44,7 +44,6 @@ ANN static inline m_uint env_push_type(const Env env, const Type type) { return ANN m_bool is_fptr(const struct Gwion_*, const Type t); ANN m_bool is_class(const struct Gwion_*, const Type t); ANN m_uint get_depth(const Type type); - typedef enum { et_void, et_int, et_bool, et_char, et_float, et_null, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack, diff --git a/include/gwion.h b/include/gwion.h index e95cf71a..caf36790 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -26,4 +26,13 @@ void free_code_instr(const Vector v, const Gwion gwion); ANN void gwion_end_child(const VM_Shred shred, const Gwion gwion); ANN void push_global(const Gwion gwion, const m_str name); ANN Nspc pop_global(const Gwion gwion); +__attribute__((returns_nonnull)) +ANN static inline Value type_value(const Gwion gwion, const Type t) { + return (Value)nspc_lookup_value1(t->e->owner, insert_symbol(gwion->st, t->name)); +} +__attribute__((returns_nonnull)) +ANN static inline Type type_class(const Gwion gwion, const Type t) { + const Value v = nspc_lookup_value1(t->e->owner, insert_symbol(gwion->st, t->name)); + return v->type; +} #endif diff --git a/include/gwion_env.h b/include/gwion_env.h index 61762f18..a97ae2e6 100644 --- a/include/gwion_env.h +++ b/include/gwion_env.h @@ -11,4 +11,5 @@ #include "env/context.h" #include "env/tuple.h" #include "env/envset.h" + #endif diff --git a/include/parse.h b/include/parse.h index 992b1d37..06151839 100644 --- a/include/parse.h +++ b/include/parse.h @@ -85,6 +85,8 @@ 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); diff --git a/src/env/type_special.c b/src/env/type_special.c index b3abc0e2..b03014df 100644 --- a/src/env/type_special.c +++ b/src/env/type_special.c @@ -1,6 +1,8 @@ #include "gwion_util.h" #include "gwion_ast.h" #include "gwion_env.h" +#include "vm.h" +#include "gwion.h" static m_str const special_name[] = { ":nonnull", ":force" }; #define SPECIAL_LEN strlen(special_name[0]) + strlen(special_name[1]) @@ -14,14 +16,15 @@ typedef struct { } SpecialType; -ANN static Type specialtype_create(MemPool p, const SpecialType *s) { - const Type t = type_copy(p, s->type); +ANN static Type specialtype_create(const Env env, const SpecialType *s) { + const Type t = type_copy(env->gwion->mp, s->type); if(t->nspc) ADD_REF(t->nspc) t->name = s_name(s->name); t->flag = s->type->flag | s->flag; t->e->parent = s->type; nspc_add_type_front(s->type->e->owner, s->name, t); + mk_class(env, t); return t; } @@ -50,10 +53,10 @@ ANN static void specialtype_init(SymTable *st, SpecialType *s) { s->name = insert_symbol(st, c); } -ANN Type special_type(SymTable *st, const Type t, const uint st_type) { +ANN Type special_type(const Env env, const Type t, const uint st_type) { SpecialType s = { .type=t, .st_type=st_type }; - specialtype_init(st, &s); + specialtype_init(env->gwion->st, &s); return nspc_lookup_type1(t->e->owner, s.name) ?: - specialtype_create(st->p, &s); + specialtype_create(env, &s); } diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 3541eb86..a3c55f8d 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -404,19 +404,13 @@ ANN static inline Symbol dot_symbol(SymTable *st, const Value v) { return insert_symbol(st, name); } -ANN static inline Type dot_type(SymTable *st, const Value v) { - const Type t = v->from->owner_class; - if(!GET_FLAG(v, static)) - return t; - const Value val = nspc_lookup_value1(t->nspc->parent, insert_symbol(st, t->name)); - return val->type; -} - ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data) { const Value v = prim_self(data)->value; const Exp base = new_prim_id(gwion->mp, dot_symbol(gwion->st, v), loc_cpy(gwion->mp, prim_pos(data))); const Exp dot = new_exp_dot(gwion->mp, base, *data); - dot->d.exp_dot.t_base = dot->d.exp_dot.base->info->type = dot_type(gwion->st, v); + const Type owner = v->from->owner_class; + dot->d.exp_dot.t_base = dot->d.exp_dot.base->info->type = !GET_FLAG(v, static) ? + owner : type_class(gwion, owner); dot->info->type = prim_exp(data)->info->type; exp_setvar(dot, exp_getvar(prim_exp(data))); return dot; diff --git a/src/parse/check.c b/src/parse/check.c index 65666927..830f6b53 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -321,8 +321,7 @@ ANN static Type check_prim_hack(const Env env, const Exp *data) { ANN static Type check_prim_typeof(const Env env, const Exp *exp) { const Exp e = *exp; DECL_OO(const Type, t, = check_exp(env, e)) - DECL_OO(Value, v, = nspc_lookup_value1(t->e->owner, insert_symbol(t->name))) - return v->type; + return type_class(env->gwion, t); } ANN static Type check_prim_interp(const Env env, const Exp* exp) { @@ -713,7 +712,7 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp, const Tmp ANN static Type check_exp_call_template(const Env env, Exp_Call *exp) { const Type t = exp->func->info->type; - DECL_OO(const Value, value, = nspc_lookup_value1(t->e->owner, insert_symbol(t->name))) + DECL_OO(const Value, value, = type_value(env->gwion, t)) const Func_Def fdef = value->d.func_ref ? value->d.func_ref->def : t->e->d.func->def; Tmpl *tm = fdef->base->tmpl; if(tm->call) @@ -825,9 +824,8 @@ ANN static m_bool predefined_call(const Env env, const Type t, const loc_t pos) ANN static Type check_exp_call(const Env env, Exp_Call* exp) { if(exp->tmpl) { CHECK_OO(check_exp(env, exp->func)) - const Type t = actual_type(env->gwion, !GET_FLAG(exp->func->info->type, nonnull) ? - exp->func->info->type : exp->func->info->type->e->parent); - const Value v = nspc_lookup_value1(t->e->owner, insert_symbol(t->name)); + const Type t = actual_type(env->gwion, unflag_type(exp->func->info->type)); + const Value v = type_value(env->gwion, t); if(!GET_FLAG(v, func) && !GET_FLAG(exp->func->info->type, func) ) ERR_O(exp_self(exp)->pos, _("template call of non-function value.")) if(!v->d.func_ref || !v->d.func_ref->def->base->tmpl) diff --git a/src/parse/scanx.c b/src/parse/scanx.c index 21232f87..d4fc4639 100644 --- a/src/parse/scanx.c +++ b/src/parse/scanx.c @@ -43,10 +43,16 @@ scanx_body(const Env e, const Class_Def c, const _exp_func f, void* d) { #undef scanx_parent +__attribute__((returns_nonnull)) +ANN Type unflag_type(const Type t) { + const Type type = !GET_FLAG(t, nonnull) ? t : t->e->parent; + return !GET_FLAG(type, force) ? type : type->e->parent; +} + __attribute__((returns_nonnull)) ANN Type get_type(const Type t) { const Type type = !t->array_depth ? t : array_base(t); - return !GET_FLAG(type, nonnull) ? type : type->e->parent; + return unflag_type(type); } __attribute__((returns_nonnull)) -- 2.43.0