From: Jérémie Astor Date: Sun, 10 May 2020 21:51:19 +0000 (+0200) Subject: :art: Introduce special_type X-Git-Tag: nightly~1585 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=506d0eabdd80e8752ef8b0636f381aa77e5d29ff;p=gwion.git :art: Introduce special_type --- diff --git a/include/env/env.h b/include/env/env.h index 256dfbcd..3dd54d75 100644 --- a/include/env/env.h +++ b/include/env/env.h @@ -42,8 +42,9 @@ 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 nonnul_type(const Env env, const Type base); -ANN Type force_type(const Env env, const Type t); +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); 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/src/env/type_special.c b/src/env/type_special.c new file mode 100644 index 00000000..b3abc0e2 --- /dev/null +++ b/src/env/type_special.c @@ -0,0 +1,59 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "gwion_env.h" + +static m_str const special_name[] = { ":nonnull", ":force" }; +#define SPECIAL_LEN strlen(special_name[0]) + strlen(special_name[1]) +static const ae_flag special_flag[] = { ae_flag_nonnull, ae_flag_force }; + +typedef struct { + const Type type; + Symbol name; + ae_flag flag; + uint st_type; +} SpecialType; + + +ANN static Type specialtype_create(MemPool p, const SpecialType *s) { + const Type t = type_copy(p, 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); + return t; +} + +static inline int get_flag(const Type t, const ae_flag flag) { + return (t->flag & flag) == flag; +} + + +ANN static void specialtype_flag(SpecialType *s, m_str c, const uint i) { + const ae_flag flag = special_flag[i]; + if(i == s->st_type || get_flag(s->type, flag)) { + strcat(c, special_name[0]); + s->flag |= flag; + } +} + +ANN static void specialtype_init(SymTable *st, SpecialType *s) { + const size_t sz = strlen(s->type->name); + char c[sz + SPECIAL_LEN + 1]; + strcpy(c, s->type->name); + m_str flagged = strchr(c, ':'); + if(flagged) + *flagged = '\0'; + specialtype_flag(s, c, 0); + specialtype_flag(s, c, 1); + s->name = insert_symbol(st, c); +} + +ANN Type special_type(SymTable *st, const Type t, const uint st_type) { + SpecialType s = { .type=t, .st_type=st_type }; + specialtype_init(st, &s); + return nspc_lookup_type1(t->e->owner, s.name) ?: + specialtype_create(st->p, &s); +} + diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index 80649250..4a958224 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -5,47 +5,6 @@ #include "traverse.h" #include "parse.h" -#define STR_NONNULL ":nonnull" -#define STRLEN_NONNULL strlen(STR_NONNULL) - -ANN Type nonnul_type(const Env env, const Type base) { - char c[strlen(base->name) + 9]; - sprintf(c, "%s%s", base->name, STR_NONNULL); - const Symbol sym = insert_symbol(c); - const Type exist = nspc_lookup_type1(base->e->owner, sym); - if(exist) - return exist; - const Type t = type_copy(env->gwion->mp, base); - t->e->parent = base; - if(t->nspc) - ADD_REF(t->nspc) - t->name = s_name(sym); - t->flag = base->flag | ae_flag_nonnull; - nspc_add_type_front(t->e->owner, sym, t); - return t; -} - -#define STR_FORCE ":force" -#define STRLEN_FORCE strlen(STR_FORCE) - -ANN static inline Type new_force_type(MemPool p, const Type t, const Symbol sym) { - const Type ret = type_copy(p, t); - if(ret->nspc) - ADD_REF(ret->nspc) - ret->name = s_name(sym); - ret->flag = t->flag | ae_flag_force; - nspc_add_type_front(t->e->owner, sym, ret); - return ret; - } - -ANN Type force_type(const Env env, const Type t) { - const size_t len = strlen(t->name); - char name[len + STRLEN_FORCE + 2]; - strcpy(name, t->name); - strcpy(name + len, STR_FORCE); - const Symbol sym = insert_symbol(name); - return nspc_lookup_type1(t->e->owner, sym) ?: new_force_type(env->gwion->mp, t, sym); -} ANN Type type_decl_resolve(const Env env, Type_Decl* td) { DECL_OO(const Type, base, = find_type(env, td))