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);
--- /dev/null
+#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);
+}
+
#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))