]> Nishi Git Mirror - gwion.git/commitdiff
:art: split import => more
authorfennecdjay <astor.jeremie@wanadoo.fr>
Thu, 24 Oct 2019 17:00:04 +0000 (19:00 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Thu, 24 Oct 2019 17:00:04 +0000 (19:00 +0200)
include/import.h
include/import/checker.h [new file with mode: 0644]
include/import/typedef.h [new file with mode: 0644]
src/import/checker.c [new file with mode: 0644]
src/import/typedef.c [new file with mode: 0644]
src/import/union.c [new file with mode: 0644]
src/lib/import.c

index 241896c44954ad2069f709d353682ea8a41609bd..ccfe369d5d3f6e6a62ba4afacdebfee1a271e515 100644 (file)
@@ -47,8 +47,7 @@ ANN m_int gwi_class_end(const Gwi gwi);
 ANN m_int gwi_fptr_ini(const Gwi gwi, const m_str __restrict__ type, const __restrict__ m_str name);
 ANN Type gwi_fptr_end(const Gwi gwi, const ae_flag flag);
 
-ANN m_int gwi_typedef_ini(const Gwi gwi, const restrict m_str type, const restrict m_str name);
-ANN Type gwi_typedef_end(const Gwi gwi, const ae_flag flag);
+#include "import/typedef.h"
 
 ANN m_int gwi_tmpl_ini(const Gwi gwi, const m_uint n, const m_str *name);
 ANN m_int gwi_tmpl_end(const Gwi gwi);
@@ -65,6 +64,7 @@ ANN m_int gwi_func_end(const Gwi gwi, const ae_flag flag);
 
 #include "import/oper.h"
 #include "import/special.h"
+#include "import/checker.h"
 
 OP_CHECK(opck_const_rhs);
 OP_CHECK(opck_unary_meta);
diff --git a/include/import/checker.h b/include/import/checker.h
new file mode 100644 (file)
index 0000000..68e9b00
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __IMPORT_CHECKER
+#define __IMPORT_CHECKER
+
+struct func_checker { // name_checker ?
+  m_str name;
+  ID_List tmpl;
+  const ae_flag flag;
+};
+
+struct array_checker {
+  m_str str;
+  Exp base, exp;
+  m_uint depth;
+  loc_t pos;
+  m_bool is_exp;
+};
+
+ANN void func_checker_clean(const Gwi gwi, struct func_checker *ck);
+ANN Type_Decl* import_td(const Gwi gwi, const m_str name, const m_bool is_exp);
+ANN m_bool check_typename_def(const Gwi gwi, struct func_checker *ck);
+ANN ID_List tmpl_valid(const Gwi gwi, const m_str str);
+#endif
diff --git a/include/import/typedef.h b/include/import/typedef.h
new file mode 100644 (file)
index 0000000..226526a
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __IMPORT_TYPEDEF
+#define __IMPORT_TYPEDEF
+
+ANN m_int gwi_typedef_ini(const Gwi gwi, const restrict m_str type, const restrict m_str name);
+ANN Type gwi_typedef_end(const Gwi gwi, const ae_flag flag);
+
+#endif
diff --git a/src/import/checker.c b/src/import/checker.c
new file mode 100644 (file)
index 0000000..c2c2dfa
--- /dev/null
@@ -0,0 +1,271 @@
+#include <ctype.h>
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "oo.h"
+#include "vm.h"
+#include "env.h"
+#include "type.h"
+#include "value.h"
+#include "traverse.h"
+#include "instr.h"
+#include "object.h"
+#include "emit.h"
+#include "func.h"
+#include "nspc.h"
+#include "gwion.h"
+#include "operator.h"
+#include "import.h"
+#include "gwi.h"
+
+ANN static m_bool check_illegal(const char c, const m_uint i) {
+   return isalnum(c) || c == '_' || (!i && c == '@');
+}
+
+ANN ID_List path_valid(const Env env, const m_str path, const loc_t pos) {
+  const size_t sz = strlen(path);
+  if(path[0] == '.' || path[sz] == '.')
+    ENV_ERR_O(pos, _("path '%s' must not ini or end with '.'."), path)
+  char curr[sz + 1];
+  m_uint i;
+  for(i = 0; i < sz; ++i) {
+    const char c = path[i];
+    if(c != '.') {
+      if(!check_illegal(c, i))
+        ENV_ERR_O(pos, _("illegal character '%c' in path '%s'."), c, path)
+      curr[i] = c;
+    } else
+      break;
+  }
+  curr[i++] = '\0';
+  const ID_List list = new_id_list(env->gwion->mp,
+      insert_symbol(env->gwion->st, curr), loc_cpy(env->gwion->mp, pos));
+  if(i < sz)
+    list->next = path_valid(env, path + i, pos);
+  return list;
+}
+
+struct tmpl_checker {
+  const m_str str;
+  ID_List list;
+  const loc_t pos;
+};
+
+ANN static m_bool tmpl_list(const Gwion gwion, struct tmpl_checker *ck) {
+  m_str s = ck->str;
+  const size_t sz = strlen(s);
+  char c[sz + 1];
+  for(m_uint i = 0; i < sz; ++i) {
+    if(isalnum(s[i]) || s[i] == '_') {
+      c[i] = s[i];
+      continue;
+    }
+    if(s[i] == '~') {
+      if(!i || s[i+1] != '>')
+        break;
+      c[i] = '\0';
+      ck->list = new_id_list(gwion->mp, insert_symbol(gwion->st, c),
+          loc_cpy(gwion->mp, ck->pos));
+      return GW_OK;
+    }
+    if(s[i] == ',') {
+      if(!i)break;
+      c[i] = '\0';
+      ck->list = new_id_list(gwion->mp, insert_symbol(gwion->st, c),
+          loc_cpy(gwion->mp, ck->pos));
+      struct tmpl_checker _ck = { .str=ck->str + i + 1, .pos=ck->pos };
+      CHECK_BB(tmpl_list(gwion, &_ck))
+      ck->list->next = _ck.list;
+      return GW_OK;
+    }
+    break;
+  }
+  return GW_ERROR;
+}
+
+ANN static m_bool tmpl_check(const m_str str) {
+  if(str[0] != '<')
+    return 0; // TODO: make it GW_PASS
+  if(str[1] != '~')
+    return GW_ERROR;
+  return GW_OK;
+}
+
+ANN static ID_List _tmpl_valid(const Gwi gwi, const m_str str) {
+  const m_bool ret = tmpl_check(str);
+  if(ret == GW_ERROR)
+    return (ID_List)GW_ERROR;
+  if(!ret)
+    return NULL;
+  struct tmpl_checker ck = { .str=str+2, .pos=gwi->loc };
+  if(tmpl_list(gwi->gwion, &ck) == GW_ERROR)
+    return (ID_List)GW_ERROR;
+  return ck.list;
+}
+
+ANN ID_List tmpl_valid(const Gwi gwi, const m_str str) {
+  const ID_List ret = _tmpl_valid(gwi, str);
+  if(ret == (ID_List)GW_ERROR)
+    env_err(gwi->gwion->env, gwi->loc, _("invalid templating definition"));
+  return ret;
+}
+
+ANN ID_List str2list(const Env env, const m_str path,
+      m_uint* array_depth, const loc_t pos) {
+  const m_uint sz = strlen(path);
+  m_uint len = sz, depth = 0;
+  while(len > 2 && path[len - 1] == ']' && path[len - 2] == '[') {
+    depth++;
+    len -= 2;
+  }
+  *array_depth = depth;
+  char curr[sz + 1];
+  memcpy(curr, path, len);
+  curr[len] = '\0';
+  return path_valid(env, curr, pos);
+}
+
+ANN Type_List _str2tl(const Env env, const m_str s, const loc_t pos) {
+  m_uint depth;
+  DECL_OO(Type_Decl*, td, = str2decl(env, s, &depth, pos))
+  if(depth) {
+    td->array = new_array_sub(env->gwion->mp, NULL);
+    td->array->depth = depth;
+  }
+//    td->array = import_array(env->gwion->mp, NULL, &depth, 0);
+  return new_type_list(env->gwion->mp, td, NULL);
+}
+
+ANN Type_List tlnext(const Env env, const m_str s, size_t split, const loc_t pos) {
+  char curr[split+1];
+  strncpy(curr, s, split);
+  curr[split] = '\0';
+  const Type_List tl = _str2tl(env, curr, pos);
+  tl->next = str2tl(env, s + split + 1, pos);
+  return tl;
+}
+
+struct GetTl {
+  const m_str str;
+  m_uint i;
+  m_uint lvl;
+  const size_t sz;
+};
+
+#define tl_xxx(name, tgt, op)                             \
+ANN m_bool tl_##name(struct GetTl *gtl, const m_uint i) { \
+  if(!(i < gtl->sz && gtl->str[i] == tgt))                \
+    return GW_ERROR;                                      \
+  op gtl->lvl;                                            \
+  return GW_OK;                                           \
+}
+tl_xxx(open,  '~', ++)
+tl_xxx(close, '>', --)
+
+ANN Type_List str2tl(const Env env, const m_str s, const loc_t pos) {
+  struct GetTl gtl = { .str=s, .sz = strlen(s) };
+  for(m_uint i = 0; i < gtl.sz; ++i) {
+    if(s[i] == '<')
+      CHECK_BO(tl_open(&gtl, ++i))
+    else if(s[i] == '~')
+      CHECK_BO(tl_close(&gtl, ++i))
+    else if(s[i] == ',' && !gtl.lvl)
+      return tlnext(env, s, i, pos);
+  }
+  return _str2tl(env, s, pos);
+}
+
+ANN Type_Decl* str2decl(const Env env, const m_str s, m_uint *depth, const loc_t pos) {
+  DECL_OO(const m_str, type_name, = get_type_name(env, s, 0))
+  DECL_OO(ID_List, id, = str2list(env, type_name, depth, pos))
+  Type_Decl* td = new_type_decl(env->gwion->mp, id);
+  const m_str tl_name = get_type_name(env, s, 1);
+  if(tl_name) {
+    if(!(td->types = str2tl(env, tl_name, pos)) || !type_decl_resolve(env, td)) {
+      free_type_decl(env->gwion->mp, td);
+      return NULL;
+    }
+  }
+  return td;
+}
+
+ANN static void array_add_exp(struct array_checker *ck, const Exp exp) {
+  if(ck->exp)
+    ck->exp = (ck->exp->next = exp);
+  else
+    ck->base = ck->exp = exp;
+  ++ck->depth;
+  ++ck->is_exp;
+}
+
+ANN m_bool array_check(const Env env, struct array_checker *ck) {
+  const size_t sz = strlen(ck->str);
+  char tmp[sz + 1];
+  for(m_uint i = 0; i < sz; ++i) {
+    const char c = ck->str[i];
+    if(c == ']') {
+      const m_bool is_end = ck->str[i + 1] == '\0';
+      if(!is_end && ck->str[i + 1] != '[')
+        break;
+      if(i) {
+        if(ck->is_exp == GW_ERROR)
+          ENV_ERR_B(ck->pos, _("subscript must be empty"))
+        if(!ck->is_exp && ck->depth)
+          break;
+        tmp[i] = '\0';
+        const m_uint num = strtol(tmp, NULL, 10);// migth use &endptr and check errno
+        const Exp exp = new_exp_prim_int(env->gwion->mp, num, loc_cpy(env->gwion->mp, ck->pos));
+        array_add_exp(ck, exp);
+        ck->str += i + 2;
+        return is_end ? GW_OK : array_check(env, ck);
+      } else {
+        if(ck->is_exp)
+          break;
+        ++ck->depth;
+        return array_check(env, ck);
+      }
+    }
+    if(isdigit(c))
+      tmp[i] = c;
+    else
+      ENV_ERR_B(ck->pos, _("invalid subscript '%c' in '%s'"), c, ck->str)
+  }
+  ENV_ERR_B(ck->pos, _("incoherent subscript '%s'"), ck->str)
+}
+
+ANN void func_checker_clean(const Gwi gwi, struct func_checker *ck) {
+  if(ck->tmpl)
+    free_id_list(gwi->gwion->mp, ck->tmpl);
+}
+
+ANN m_bool check_typename_def(const Gwi gwi, struct func_checker *ck) {
+  const m_str base = ck->name;
+  const m_str c = strchr(ck->name, '>');
+  ck->name = !c ? ck->name : c + 1;
+  CHECK_BB(name_valid(gwi, ck->name))
+  if((ck->tmpl = tmpl_valid(gwi, base)) == (ID_List)GW_ERROR)
+    return GW_ERROR;
+  return GW_OK;
+}
+
+
+ANN Array_Sub import_array_sub(const Gwi gwi, const m_str str, const m_bool is_exp) {
+  struct array_checker ck = { .str=str + 1, .pos=gwi->loc, .is_exp=is_exp };
+  CHECK_BO(array_check(gwi->gwion->env, &ck))
+  return new_array_sub(gwi->gwion->mp, ck.exp);
+}
+
+ANN Type_Decl* import_td(const Gwi gwi, const m_str name, const m_bool is_exp) {
+  const m_str subscript = strchr(name, '[');
+  const size_t sz = strlen(name), sub_sz = subscript ? strlen(subscript) : 0,
+    tmp_sz = sz - sub_sz;
+  char str[tmp_sz + 1];
+  strncpy(str, name, tmp_sz);
+  str[tmp_sz] = '\0';
+  DECL_OO(const ID_List, type_path, = path_valid(gwi->gwion->env, str, gwi->loc))
+  Type_Decl* td = new_type_decl(gwi->gwion->mp, type_path);
+  if(subscript && (td->array = import_array_sub(gwi, subscript, is_exp))) {
+    free_type_decl(gwi->gwion->mp, td);
+    return NULL;
+  }
+  return td;
+}
diff --git a/src/import/typedef.c b/src/import/typedef.c
new file mode 100644 (file)
index 0000000..15e1b6d
--- /dev/null
@@ -0,0 +1,45 @@
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "oo.h"
+#include "vm.h"
+#include "env.h"
+#include "type.h"
+#include "value.h"
+#include "traverse.h"
+#include "instr.h"
+#include "object.h"
+#include "emit.h"
+#include "func.h"
+#include "nspc.h"
+#include "gwion.h"
+#include "operator.h"
+#include "import.h"
+#include "gwi.h"
+
+ANN m_int gwi_typedef_ini(const Gwi gwi, const restrict m_str type, const restrict m_str name) {
+  gwi->val.type = type;
+  gwi->val.name = name;
+  return GW_OK;
+}
+
+ANN Type gwi_typedef_end(const Gwi gwi, const ae_flag flag) {
+  struct func_checker ck = { .name=gwi->val.name, .flag=flag };
+  CHECK_BO(check_typename_def(gwi, &ck))
+  Type_Decl* td = import_td(gwi, gwi->val.type, 0); // TODO: make it GW_PASS
+  if(td) {
+    td->flag |= flag;
+    const Symbol sym = insert_symbol(gwi->gwion->st, ck.name);
+    const Type_Def tdef = new_type_def(gwi->gwion->mp, td, sym);
+    if(ck.tmpl)
+      tdef->tmpl = new_tmpl(gwi->gwion->mp, ck.tmpl, -1);
+    traverse_type_def(gwi->gwion->env, tdef);
+    const Type t = tdef->type;
+    free_type_def(gwi->gwion->mp, tdef);
+    return t;
+  }
+  func_checker_clean(gwi, &ck);
+  return NULL;
+}
diff --git a/src/import/union.c b/src/import/union.c
new file mode 100644 (file)
index 0000000..b21a4dc
--- /dev/null
@@ -0,0 +1,94 @@
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "oo.h"
+#include "vm.h"
+#include "env.h"
+#include "type.h"
+#include "value.h"
+#include "traverse.h"
+#include "instr.h"
+#include "object.h"
+#include "emit.h"
+#include "func.h"
+#include "nspc.h"
+#include "gwion.h"
+#include "operator.h"
+#include "import.h"
+#include "gwi.h"
+
+ANN static Exp make_exp(const Gwi gwi, const m_str type, const m_str name) {
+  const Env env = gwi->gwion->env;
+  m_uint array_depth;
+  Array_Sub array = NULL;
+  DECL_OO(const ID_List, id_list, = str2list(env, type, &array_depth, gwi->loc))
+  if(array_depth) {
+    array = new_array_sub(env->gwion->mp, NULL);
+    array->depth = array_depth;
+  }
+  Type_Decl *type_decl = new_type_decl(env->gwion->mp, id_list);
+  const Var_Decl var_decl = new_var_decl(env->gwion->mp,
+      insert_symbol(env->gwion->st, name), array, loc_cpy(env->gwion->mp, gwi->loc));
+  const Var_Decl_List var_decl_list = new_var_decl_list(env->gwion->mp, var_decl, NULL);
+  return new_exp_decl(env->gwion->mp, type_decl, var_decl_list);
+}
+
+ANN2(1) m_int gwi_union_ini(const Gwi gwi, const m_str type, const m_str name) {
+  gwi->union_data.type_name = type;
+  gwi->union_data.name = name;
+  return GW_OK;
+}
+
+ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type, const restrict m_str name) {
+  DECL_OB(const Exp, exp, = make_exp(gwi, type, name))
+  SET_FLAG(exp->d.exp_decl.td, ref);
+  gwi->union_data.list = new_decl_list(gwi->gwion->mp, exp, gwi->union_data.list);
+  return GW_OK;
+}
+
+ANN static Type union_type(const Gwi gwi, const Union_Def udef) {
+  CHECK_BO(scan0_union_def(gwi->gwion->env, udef))
+  CHECK_BO(traverse_union_def(gwi->gwion->env, udef))
+  if(!udef->tmpl)
+    emit_union_offset(udef->l, udef->o);
+  if(gwi->gwion->env->class_def && !GET_FLAG(udef, static))
+      gwi->gwion->env->class_def->nspc->info->offset =
+      udef->o + udef->s;
+  if(udef->xid || !udef->type_xid) {
+    SET_FLAG(udef->value, builtin);
+    const M_Object o = new_object(gwi->gwion->mp, NULL, udef->value->type);
+    udef->value->d.ptr = (m_uint*)o;
+   return udef->value->type;
+  }
+  return udef->type;
+}
+
+ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) {
+  if(!gwi->union_data.list)
+    GWI_ERR_O(_("union is empty"));
+  if(gwi->union_data.name)
+    CHECK_BO(name_valid(gwi, gwi->union_data.name))
+  struct func_checker ck = { .name=gwi->union_data.type_name, .flag=flag };
+  if(gwi->union_data.type_name)
+    CHECK_BO(check_typename_def(gwi, &ck))
+  const Symbol xid = gwi->union_data.name ? insert_symbol(gwi->gwion->st, gwi->union_data.name) : NULL;
+  const Symbol type_xid = gwi->union_data.type_name ? insert_symbol(gwi->gwion->st, ck.name) : NULL;
+  const Union_Def udef = new_union_def(gwi->gwion->mp, gwi->union_data.list, loc_cpy(gwi->gwion->mp, gwi->loc));
+  udef->flag = flag;
+  udef->xid = xid;
+  udef->type_xid = type_xid;
+  if(ck.tmpl) {
+    if(udef->xid)
+      GWI_ERR_O(_("Template union type can't declare union"));
+    udef->tmpl = new_tmpl(gwi->gwion->mp, ck.tmpl, -1);
+  }
+  const Type t = union_type(gwi, udef);
+  if(!SAFE_FLAG(t, template))
+    free_union_def(gwi->gwion->mp, udef);
+  gwi->union_data.list = NULL;
+  gwi->union_data.name  = NULL;
+  gwi->union_data.type_name  = NULL;
+  return t;
+}
index 53ff0fc6b86a0900e39ecff3f2285ccd831f4b2d..fb42cbdc64fb23c9abb9e0c6a6292bde76e9be3a 100644 (file)
@@ -30,7 +30,7 @@
 struct Path {
   m_str path, curr;
   m_uint len;
-  YYLTYPE loc;
+  loc_t loc;
 };
 
 ANN static ID_List templater_def(SymTable *st, const Gwi gwi) {
@@ -85,113 +85,6 @@ ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_s
   return GW_OK;
 }
 
-ANN static m_bool check_illegal(const char c, const m_uint i) {
-  return isalnum(c) || c == '_' || (!i && c == '@');
-}
-
-ANN static ID_List path_valid(const Env env, const m_str path, const loc_t pos) {
-  const size_t sz = strlen(path);
-  if(path[0] == '.' || path[sz] == '.')
-    ENV_ERR_O(pos, _("path '%s' must not ini or end with '.'."), path)
-  char curr[sz + 1];
-  m_uint i;
-  for(i = 0; i < sz; ++i) {
-    const char c = path[i];
-    if(c != '.') {
-      if(!check_illegal(c, i))
-        ENV_ERR_O(pos, _("illegal character '%c' in path '%s'."), c, path)
-      curr[i] = c;
-    } else
-      break;
-  }
-  curr[i++] = '\0';
-  const ID_List list = new_id_list(env->gwion->mp,
-      insert_symbol(env->gwion->st, curr), loc_cpy(env->gwion->mp, pos));
-  if(i < sz)
-    list->next = path_valid(env, path + i, pos);
-  return list;
-}
-
-struct tmpl_checker {
-  const m_str str;
-  ID_List list;
-  const loc_t pos;
-};
-
-ANN static m_bool tmpl_list(const Gwion gwion, struct tmpl_checker *ck) {
-  m_str s = ck->str;
-  const size_t sz = strlen(s);
-  char c[sz + 1];
-  for(m_uint i = 0; i < sz; ++i) {
-    if(isalnum(s[i]) || s[i] == '_') {
-      c[i] = s[i];
-      continue;
-    }
-    if(s[i] == '~') {
-      if(!i || s[i+1] != '>')
-        break;
-      c[i] = '\0';
-      ck->list = new_id_list(gwion->mp, insert_symbol(gwion->st, c),
-          loc_cpy(gwion->mp, ck->pos));
-      return GW_OK;
-    }
-    if(s[i] == ',') {
-      if(!i)break;
-      c[i] = '\0';
-      ck->list = new_id_list(gwion->mp, insert_symbol(gwion->st, c),
-          loc_cpy(gwion->mp, ck->pos));
-      struct tmpl_checker _ck = { .str=ck->str + i + 1, .pos=ck->pos };
-      CHECK_BB(tmpl_list(gwion, &_ck))
-      ck->list->next = _ck.list;
-      return GW_OK;
-    }
-    break;
-  }
-  return GW_ERROR;
-}
-
-ANN static m_bool tmpl_check(const m_str str) {
-  if(str[0] != '<')
-    return 0; // TODO: make it GW_PASS
-  if(str[1] != '~')
-    return GW_ERROR;
-  return GW_OK;
-}
-
-ANN static ID_List _tmpl_valid(const Gwi gwi, const m_str str) {
-  const m_bool ret = tmpl_check(str);
-  if(ret == GW_ERROR)
-    return (ID_List)GW_ERROR;
-  if(!ret)
-    return NULL;
-  struct tmpl_checker ck = { .str=str+2, .pos=gwi->loc };
-  if(tmpl_list(gwi->gwion, &ck) == GW_ERROR)
-    return (ID_List)GW_ERROR;
-  return ck.list;
-}
-
-ANN static ID_List tmpl_valid(const Gwi gwi, const m_str str) {
-  const ID_List ret = _tmpl_valid(gwi, str);
-  if(ret == (ID_List)GW_ERROR)
-    env_err(gwi->gwion->env, gwi->loc, _("invalid templating definition"));
-  return ret;
-}
-
-ANN ID_List str2list(const Env env, const m_str path,
-      m_uint* array_depth, const loc_t pos) {
-  const m_uint sz = strlen(path);
-  m_uint len = sz, depth = 0;
-  while(len > 2 && path[len - 1] == ']' && path[len - 2] == '[') {
-    depth++;
-    len -= 2;
-  }
-  *array_depth = depth;
-  char curr[sz + 1];
-  memcpy(curr, path, len);
-  curr[len] = '\0';
-  return path_valid(env, curr, pos);
-}
-
 ANN static m_bool mk_gack(MemPool p, const Type type, const f_gack d) {
   const VM_Code code = new_vm_code(p, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@gack");
   code->native_func = (m_uint)d;
@@ -324,67 +217,6 @@ static Array_Sub make_dll_arg_list_array(MemPool p, Array_Sub array_sub,
   return array_sub;
 }
 
-ANN Type_List _str2tl(const Env env, const m_str s, const loc_t pos) {
-  m_uint depth;
-  DECL_OO(Type_Decl*, td, = str2decl(env, s, &depth, pos))
-  if(depth)
-    td->array = make_dll_arg_list_array(env->gwion->mp, NULL, &depth, 0);
-  return new_type_list(env->gwion->mp, td, NULL);
-}
-
-ANN Type_List tlnext(const Env env, const m_str s, size_t split, const loc_t pos) {
-  char curr[split+1];
-  strncpy(curr, s, split);
-  curr[split] = '\0';
-  const Type_List tl = _str2tl(env, curr, pos);
-  tl->next = str2tl(env, s + split + 1, pos);
-  return tl;
-}
-
-struct GetTl {
-  const m_str str;
-  m_uint i;
-  m_uint lvl;
-  const size_t sz;
-};
-
-#define tl_xxx(name, tgt, op)                             \
-ANN m_bool tl_##name(struct GetTl *gtl, const m_uint i) { \
-  if(!(i < gtl->sz && gtl->str[i] == tgt))                \
-    return GW_ERROR;                                      \
-  op gtl->lvl;                                            \
-  return GW_OK;                                           \
-}
-tl_xxx(open,  '~', ++)
-tl_xxx(close, '>', --)
-
-ANN Type_List str2tl(const Env env, const m_str s, const loc_t pos) {
-  struct GetTl gtl = { .str=s, .sz = strlen(s) };
-  for(m_uint i = 0; i < gtl.sz; ++i) {
-    if(s[i] == '<')
-      CHECK_BO(tl_open(&gtl, ++i))
-    else if(s[i] == '~')
-      CHECK_BO(tl_close(&gtl, ++i))
-    else if(s[i] == ',' && !gtl.lvl)
-      return tlnext(env, s, i, pos);
-  }
-  return _str2tl(env, s, pos);
-}
-
-ANN Type_Decl* str2decl(const Env env, const m_str s, m_uint *depth, const loc_t pos) {
-  DECL_OO(const m_str, type_name, = get_type_name(env, s, 0))
-  DECL_OO(ID_List, id, = str2list(env, type_name, depth, pos))
-  Type_Decl* td = new_type_decl(env->gwion->mp, id);
-  const m_str tl_name = get_type_name(env, s, 1);
-  if(tl_name) {
-    if(!(td->types = str2tl(env, tl_name, pos)) || !type_decl_resolve(env, td)) {
-      free_type_decl(env->gwion->mp, td);
-      return NULL;
-    }
-  }
-  return td;
-}
-
 ANN static Arg_List make_dll_arg_list(const Gwi gwi, DL_Func * dl_fun) {
   const Env env = gwi->gwion->env;
   Arg_List arg_list    = NULL;
@@ -413,90 +245,7 @@ ANN static Arg_List make_dll_arg_list(const Gwi gwi, DL_Func * dl_fun) {
   return arg_list;
 }
 
-struct array_checker {
-  m_str str;
-  Exp base, exp;
-  m_uint depth;
-  loc_t pos;
-  m_bool is_exp;
-};
-
-
-ANN static void array_add_exp(struct array_checker *ck, const Exp exp) {
-  if(ck->exp)
-    ck->exp = (ck->exp->next = exp);
-  else
-    ck->base = ck->exp = exp;
-  ++ck->depth;
-  ++ck->is_exp;
-}
-
-ANN static m_bool array_check(const Env env, struct array_checker *ck) {
-  const size_t sz = strlen(ck->str);
-  char tmp[sz + 1];
-  for(m_uint i = 0; i < sz; ++i) {
-    const char c = ck->str[i];
-    if(c == ']') {
-      const m_bool is_end = ck->str[i + 1] == '\0';
-      if(!is_end && ck->str[i + 1] != '[')
-        break;
-      if(i) {
-        if(ck->is_exp == GW_ERROR)
-          ENV_ERR_B(ck->pos, _("subscript must be empty"))
-        if(!ck->is_exp && ck->depth)
-          break;
-        tmp[i] = '\0';
-        const m_uint num = strtol(tmp, NULL, 10);// migth use &endptr and check errno
-        const Exp exp = new_exp_prim_int(env->gwion->mp, num, loc_cpy(env->gwion->mp, ck->pos));
-        array_add_exp(ck, exp);
-        ck->str += i + 2;
-        return is_end ? GW_OK : array_check(env, ck);
-      } else {
-        if(ck->is_exp)
-          break;
-        ++ck->depth;
-        return array_check(env, ck);
-      }
-    }
-    if(isdigit(c))
-      tmp[i] = c;
-    else
-      ENV_ERR_B(ck->pos, _("invalid subscript '%c' in '%s'"), c, ck->str)
-  }
-  ENV_ERR_B(ck->pos, _("incoherent subscript '%s'"), ck->str)
-}
-
-
-ANN static Array_Sub import_array_sub(const Gwi gwi, const m_str str, const m_bool is_exp) {
-  struct array_checker ck = { .str=str + 1, .pos=gwi->loc, .is_exp=is_exp };
-  CHECK_BO(array_check(gwi->gwion->env, &ck))
-  return new_array_sub(gwi->gwion->mp, ck.exp);
-}
-
-ANN static Type_Decl* import_td(const Gwi gwi, const m_str name, const m_bool is_exp) {
-  const m_str subscript = strchr(name, '[');
-  const size_t sz = strlen(name), sub_sz = subscript ? strlen(subscript) : 0,
-    tmp_sz = sz - sub_sz;
-  char str[tmp_sz + 1];
-  strncpy(str, name, tmp_sz);
-  str[tmp_sz] = '\0';
-  DECL_OO(const ID_List, type_path, = path_valid(gwi->gwion->env, str, gwi->loc))
-  Type_Decl* td = new_type_decl(gwi->gwion->mp, type_path);
-  if(subscript && (td->array = import_array_sub(gwi, subscript, is_exp))) {
-    free_type_decl(gwi->gwion->mp, td);
-    return NULL;
-  }
-  return td;
-}
-struct func_checker { // name_checker ?
-  m_str name;
-  ID_List tmpl;
-  const ae_flag flag;
-};
-
-//ANN static Func_Def make_dll_as_fun(const Gwi gwi, DL_Func * dl_fun, ae_flag flag) {
 ANN static Func_Def make_dll_as_fun(const Gwi gwi, const struct func_checker *ck) {
-//DL_Func * dl_fun, ae_flag flag) {
   const MemPool mp = gwi->gwion->mp;
   DECL_OO(Type_Decl*, type_decl, = import_td(gwi, gwi->func.type, GW_ERROR))
   const m_str name = gwi->func.name;
@@ -520,21 +269,6 @@ ANN static m_bool error_fdef(const Gwi gwi, const Func_Def fdef) {
   return GW_ERROR;
 }
 
-ANN static inline void func_checker_clean(const Gwi gwi, struct func_checker *ck) {
-  if(ck->tmpl)
-    free_id_list(gwi->gwion->mp, ck->tmpl);
-}
-
-ANN static m_bool check_typename_def(const Gwi gwi, struct func_checker *ck) {
-  const m_str base = ck->name;
-  const m_str c = strchr(ck->name, '>');
-  ck->name = !c ? ck->name : c + 1;
-  CHECK_BB(name_valid(gwi, ck->name))
-  if((ck->tmpl = tmpl_valid(gwi, base)) == (ID_List)GW_ERROR)
-    return GW_ERROR;
-  return GW_OK;
-}
-
 ANN2(1) static Func_Def template_fdef(const Gwi gwi, const struct func_checker *ck) {
   const Arg_List arg_list = make_dll_arg_list(gwi, &gwi->func);
   m_uint depth;
@@ -601,104 +335,3 @@ ANN Type gwi_fptr_end(const Gwi gwi, const ae_flag flag) {
   free_fptr_def(gwi->gwion->mp, fptr);
   return t;
 }
-
-ANN m_int gwi_typedef_ini(const Gwi gwi, const restrict m_str type, const restrict m_str name) {
-  gwi->val.type = type;
-  gwi->val.name = name;
-  return GW_OK;
-}
-
-ANN Type gwi_typedef_end(const Gwi gwi, const ae_flag flag) {
-  struct func_checker ck = { .name=gwi->val.name, .flag=flag };
-  CHECK_BO(check_typename_def(gwi, &ck))
-// we need to be able to parse e.g int[2][3] here.
-// as well as other_type[][]
-  Type_Decl* td = import_td(gwi, gwi->val.type, 0); // TODO: make it GW_PASS
-  if(td) {
-    td->flag |= flag;
-    const Symbol sym = insert_symbol(gwi->gwion->st, ck.name);
-    const Type_Def tdef = new_type_def(gwi->gwion->mp, td, sym);
-    if(ck.tmpl)
-      tdef->tmpl = new_tmpl(gwi->gwion->mp, ck.tmpl, -1);
-    traverse_type_def(gwi->gwion->env, tdef);
-    const Type t = tdef->type;
-    free_type_def(gwi->gwion->mp, tdef);
-    return t;
-  }
-  func_checker_clean(gwi, &ck);
-  return NULL;
-}
-
-ANN static Exp make_exp(const Gwi gwi, const m_str type, const m_str name) {
-  const Env env = gwi->gwion->env;
-  m_uint array_depth;
-  Array_Sub array = NULL;
-  DECL_OO(const ID_List, id_list, = str2list(env, type, &array_depth, gwi->loc))
-  if(array_depth) {
-    array = new_array_sub(env->gwion->mp, NULL);
-    array->depth = array_depth;
-  }
-  Type_Decl *type_decl = new_type_decl(env->gwion->mp, id_list);
-  const Var_Decl var_decl = new_var_decl(env->gwion->mp,
-      insert_symbol(env->gwion->st, name), array, loc_cpy(env->gwion->mp, gwi->loc));
-  const Var_Decl_List var_decl_list = new_var_decl_list(env->gwion->mp, var_decl, NULL);
-  return new_exp_decl(env->gwion->mp, type_decl, var_decl_list);
-}
-
-ANN2(1) m_int gwi_union_ini(const Gwi gwi, const m_str type, const m_str name) {
-  gwi->union_data.type_name = type;
-  gwi->union_data.name = name;
-  return GW_OK;
-}
-
-ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type, const restrict m_str name) {
-  DECL_OB(const Exp, exp, = make_exp(gwi, type, name))
-  SET_FLAG(exp->d.exp_decl.td, ref);
-  gwi->union_data.list = new_decl_list(gwi->gwion->mp, exp, gwi->union_data.list);
-  return GW_OK;
-}
-
-ANN static Type union_type(const Gwi gwi, const Union_Def udef) {
-  CHECK_BO(scan0_union_def(gwi->gwion->env, udef))
-  CHECK_BO(traverse_union_def(gwi->gwion->env, udef))
-  if(!udef->tmpl)
-    emit_union_offset(udef->l, udef->o);
-  if(gwi->gwion->env->class_def && !GET_FLAG(udef, static))
-      gwi->gwion->env->class_def->nspc->info->offset =
-      udef->o + udef->s;
-  if(udef->xid || !udef->type_xid) {
-    SET_FLAG(udef->value, builtin);
-    const M_Object o = new_object(gwi->gwion->mp, NULL, udef->value->type);
-    udef->value->d.ptr = (m_uint*)o;
-   return udef->value->type;
-  }
-  return udef->type;
-}
-
-ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) {
-  if(!gwi->union_data.list)
-    GWI_ERR_O(_("union is empty"));
-  if(gwi->union_data.name)
-    CHECK_BO(name_valid(gwi, gwi->union_data.name))
-  struct func_checker ck = { .name=gwi->union_data.type_name, .flag=flag };
-  if(gwi->union_data.type_name)
-    CHECK_BO(check_typename_def(gwi, &ck))
-  const Symbol xid = gwi->union_data.name ? insert_symbol(gwi->gwion->st, gwi->union_data.name) : NULL;
-  const Symbol type_xid = gwi->union_data.type_name ? insert_symbol(gwi->gwion->st, ck.name) : NULL;
-  const Union_Def udef = new_union_def(gwi->gwion->mp, gwi->union_data.list, loc_cpy(gwi->gwion->mp, gwi->loc));
-  udef->flag = flag;
-  udef->xid = xid;
-  udef->type_xid = type_xid;
-  if(ck.tmpl) {
-    if(udef->xid)
-      GWI_ERR_O(_("Template union type can't declare union"));
-    udef->tmpl = new_tmpl(gwi->gwion->mp, ck.tmpl, -1);
-  }
-  const Type t = union_type(gwi, udef);
-  if(!SAFE_FLAG(t, template))
-    free_union_def(gwi->gwion->mp, udef);
-  gwi->union_data.list = NULL;
-  gwi->union_data.name  = NULL;
-  gwi->union_data.type_name  = NULL;
-  return t;
-}