From: fennecdjay Date: Thu, 24 Oct 2019 17:00:04 +0000 (+0200) Subject: :art: split import => more X-Git-Tag: nightly~2116^2~26 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=28ba0cc422001764a12b03d33af8fc865c913c1d;p=gwion.git :art: split import => more --- diff --git a/include/import.h b/include/import.h index 241896c4..ccfe369d 100644 --- a/include/import.h +++ b/include/import.h @@ -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 index 00000000..68e9b00c --- /dev/null +++ b/include/import/checker.h @@ -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 index 00000000..226526ae --- /dev/null +++ b/include/import/typedef.h @@ -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 index 00000000..c2c2dfa0 --- /dev/null +++ b/src/import/checker.c @@ -0,0 +1,271 @@ +#include +#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; +} diff --git a/src/import/typedef.c b/src/import/typedef.c new file mode 100644 index 00000000..15e1b6d2 --- /dev/null +++ b/src/import/typedef.c @@ -0,0 +1,45 @@ +#include +#include +#include +#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 index 00000000..b21a4dca --- /dev/null +++ b/src/import/union.c @@ -0,0 +1,94 @@ +#include +#include +#include +#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; +} diff --git a/src/lib/import.c b/src/lib/import.c index 53ff0fc6..fb42cbdc 100644 --- a/src/lib/import.c +++ b/src/lib/import.c @@ -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(>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; @@ -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; -}