]> Nishi Git Mirror - gwion.git/commitdiff
:art: Introduce special_type
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Sun, 10 May 2020 21:51:19 +0000 (23:51 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Sun, 10 May 2020 21:51:19 +0000 (23:51 +0200)
include/env/env.h
src/env/type_special.c [new file with mode: 0644]
src/parse/type_decl.c

index 256dfbcd82b35190f61bea5b5ac3f3b385eb356d..3dd54d755c8d60674d281ebb077daf04375c46e8 100644 (file)
@@ -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 (file)
index 0000000..b3abc0e
--- /dev/null
@@ -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);
+}
+
index 806492500b6850984809dca9482ba6bac08ace50..4a9582243788d43fb474fbe9b617b38285ec42b4 100644 (file)
@@ -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))