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);
#include "import/oper.h"
#include "import/special.h"
+#include "import/checker.h"
OP_CHECK(opck_const_rhs);
OP_CHECK(opck_unary_meta);
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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(>l, ++i))
+ else if(s[i] == '~')
+ CHECK_BO(tl_close(>l, ++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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
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) {
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;
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(>l, ++i))
- else if(s[i] == '~')
- CHECK_BO(tl_close(>l, ++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;
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;
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;
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;
-}