From: fennecdjay Date: Thu, 23 May 2019 08:51:38 +0000 (+0200) Subject: :art: Add template unions X-Git-Tag: nightly~2445^2~46 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=3d485d2e96600c5ee9ad024d9202043f899d5df8;p=gwion.git :art: Add template unions --- diff --git a/ast b/ast index 2f8759c5..8072d3e7 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 2f8759c59db171ce3d4737c7912b3b57d1d6dec6 +Subproject commit 8072d3e7711680521b71fee4f8a9d41363a9f1ce diff --git a/include/parse.h b/include/parse.h index 42dbcd68..0eee6771 100644 --- a/include/parse.h +++ b/include/parse.h @@ -79,4 +79,18 @@ static inline ANN m_bool env_ext(const Env env, const Class_Def cdef, const _exp ANN m_bool scanx_parent(const Type t, const _exp_func f, void *d); #define scanx_parent(a,b,c) scanx_parent(a, (_exp_func)b, c) + + +ANN m_bool scanx_cdef(const Env, void *,const Class_Def, + const _exp_func f_cdef, const _exp_func f_union); + +#define xxx_cdef(prefix) \ +static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \ + return scanx_cdef(env, env, cdef, \ + (_exp_func)prefix##_class_def, (_exp_func)prefix##_stmt_union); \ +} +xxx_cdef(scan1) +xxx_cdef(scan2) +xxx_cdef(check) +xxx_cdef(traverse) #endif diff --git a/src/emit/emit.c b/src/emit/emit.c index c2dcb514..b1158112 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -607,10 +607,11 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_de } ANN static m_bool emit_class_def(const Emitter, const Class_Def); +ANN static m_bool emit_cdef(const Emitter, const Class_Def); ANN static m_bool emit_parent_inner(const Emitter emit, const Class_Def cdef) { - CHECK_BB(traverse_class_def(emit->env, cdef)) - return emit_class_def(emit, cdef); + CHECK_BB(traverse_cdef(emit->env, cdef)) + return emit_cdef(emit, cdef); } ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) { @@ -1378,6 +1379,8 @@ ANN static inline void union_allocdata(MemPool mp, const Stmt_Union stmt) { } ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) { + if(stmt->tmpl) + return GW_OK; Decl_List l = stmt->l; m_uint scope = emit->env->scope->depth; const m_bool global = GET_FLAG(stmt, global); @@ -1724,6 +1727,11 @@ ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) { return scanx_parent(parent, emit_parent_inner, emit); } +ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) { + return scanx_cdef(emit->env, emit, cdef, + (_exp_func)emit_class_def, (_exp_func)emit_stmt_union); +} + ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { const Type type = cdef->base.type; const Nspc nspc = type->nspc; diff --git a/src/lib/prim.c b/src/lib/prim.c index 629c75e1..e33e05c0 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -12,6 +12,7 @@ #include "emit.h" #include "operator.h" #include "driver.h" +#include "traverse.h" #include "parse.h" #define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func) diff --git a/src/oo/switch.c b/src/oo/switch.c index 11a5485c..888f12a0 100644 --- a/src/oo/switch.c +++ b/src/oo/switch.c @@ -11,6 +11,7 @@ #include "type.h" #include "context.h" #include "nspc.h" +#include "traverse.h" #include "parse.h" #include "switch.h" diff --git a/src/oo/type.c b/src/oo/type.c index 2c6b0b28..2505fab7 100644 --- a/src/oo/type.c +++ b/src/oo/type.c @@ -6,12 +6,25 @@ #include "type.h" #include "nspc.h" #include "vm.h" +#include "traverse.h" #include "parse.h" #include "gwion.h" ANN static void free_type(Type a, Gwion gwion) { - if(GET_FLAG(a, template)) + if(GET_FLAG(a, template)) { + if(GET_FLAG(a, union)) { + if(a->e->def->stmt) { + if(GET_FLAG(a, pure)) + free_decl_list(gwion->mp, a->e->def->list); + else { + UNSET_FLAG(&a->e->def->stmt->d.stmt_union, global); + free_stmt(gwion->mp, a->e->def->stmt); + } + } + a->e->def->stmt = NULL; + } free_class_def(gwion->mp, a->e->def); + } if(a->nspc) REM_REF(a->nspc, gwion); mp_free(gwion->mp, Type, a); diff --git a/src/parse/check.c b/src/parse/check.c index 0c57604e..8ec65bec 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -105,7 +105,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { ERR_O(td_pos(decl->td), "can't infer type."); if(GET_FLAG(decl->type , template)) { if(!GET_FLAG(decl->type, check)) - CHECK_BO(traverse_class_def(env, decl->type->e->def)) + CHECK_BO(traverse_cdef(env, decl->type->e->def)) } const m_bool global = GET_FLAG(decl->td, global); const m_uint scope = !global ? env->scope->depth : env_push_global(env); @@ -943,6 +943,8 @@ ANN static m_bool check_stmt_jump(const Env env, const Stmt_Jump stmt) { } ANN m_bool check_stmt_union(const Env env, const Stmt_Union stmt) { + if(stmt->tmpl) + return GW_OK; if(stmt->xid) { if(env->class_def) (!GET_FLAG(stmt, static) ? decl_member : decl_static)(env->curr, stmt->value); @@ -959,8 +961,9 @@ ANN m_bool check_stmt_union(const Env env, const Stmt_Union stmt) { do { CHECK_OB(check_exp(env, l->self)) if(isa(l->self->type, t_object) > 0) { - if(!GET_FLAG(l->self->d.exp_decl.td, ref)) + if(!GET_FLAG(l->self->d.exp_decl.td, ref) && !GET_FLAG(stmt->type, template)) ERR_B(l->self->pos, "In union, Objects must be declared as reference (use '@')") + SET_FLAG(l->self->d.exp_decl.td, ref); Var_Decl_List list = l->self->d.exp_decl.list; do SET_FLAG(list->self->value, pure); while((list = list->next)); @@ -1157,7 +1160,8 @@ ANN static m_bool check_class_parent(const Env env, const Class_Def cdef) { const Type_Decl *td = cdef->base.ext; if(td->array) CHECK_BB(check_exp_array_subscripts(env, td->array->exp)) - CHECK_BB(scanx_parent(parent, traverse_class_def, env)) + if(parent->e->def) + CHECK_BB(scanx_parent(parent, traverse_class_def, env)) if(GET_FLAG(parent, typedef)) SET_FLAG(cdef->base.type, typedef); return GW_OK; @@ -1176,7 +1180,7 @@ ANN m_bool check_class_def(const Env env, const Class_Def cdef) { const Type type = cdef->base.type; if(type->e->parent == t_undefined) { type->e->parent = check_td(env, cdef->base.ext); - return traverse_class_def(env, cdef); + return traverse_cdef(env, cdef); } if(cdef->base.ext) CHECK_BB(env_ext(env, cdef, check_class_parent)) diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 10ac8069..fc56c533 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -8,9 +8,9 @@ #include "func.h" #include "nspc.h" #include "vm.h" -#include "parse.h" #include "traverse.h" #include "template.h" +#include "parse.h" ANN static Value mk_class(const Env env, const Type base) { const Type t = type_copy(env->gwion->mp, t_class); @@ -113,6 +113,8 @@ ANN static Type union_type(const Env env, const Nspc nspc, const Symbol s, const ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { CHECK_BB(env_storage(env, stmt->flag, stmt_self(stmt)->pos)) + const m_uint scope = !GET_FLAG(stmt, global) ? env->scope->depth : + env_push_global(env); if(stmt->xid) { CHECK_BB(scan0_defined(env, stmt->xid, stmt_self(stmt)->pos)) const Nspc nspc = !GET_FLAG(stmt, global) ? @@ -131,6 +133,7 @@ ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { if(!stmt->type_xid) SET_FLAG(t, op); } else if(stmt->type_xid) { + CHECK_BB(scan0_defined(env, stmt->type_xid, stmt_self(stmt)->pos)) const Nspc nspc = !GET_FLAG(stmt, global) ? env->curr : env->global_nspc; stmt->type = union_type(env, nspc, stmt->type_xid, 1); @@ -144,8 +147,23 @@ ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { stmt->value->owner = nspc; nspc_add_value(nspc, stmt->xid, stmt->value); SET_FLAG(stmt->value, checked | stmt->flag); - } + if(stmt->tmpl) { + if(tmpl_base(stmt->tmpl)) { + const Class_Def cdef = new_class_def(env->gwion->mp, stmt->flag, stmt->type_xid, + NULL, (Class_Body)stmt->l, stmt_self(stmt)->pos); + stmt->type->e->def = cdef; + cdef->base.tmpl = stmt->tmpl; + cdef->base.type = stmt->type; + cdef->list = stmt->l; + SET_FLAG(stmt->type, pure); + SET_FLAG(stmt, template); + SET_FLAG(stmt->type, template); + } + SET_FLAG(stmt->type, union); + } + if(GET_FLAG(stmt, global)) + env_pop(env, scope); return GW_OK; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 88ae8fca..4fa0b6be 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -5,11 +5,11 @@ #include "type.h" #include "nspc.h" #include "value.h" -#include "optim.h" +#include "func.h" #include "vm.h" -#include "parse.h" #include "traverse.h" #include "template.h" +#include "parse.h" ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list); ANN static m_bool scan1_stmt(const Env env, Stmt stmt); @@ -35,15 +35,16 @@ ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) { ERR_O(exp_self(decl)->pos, "can't use protected type %s", t->name) if(env->class_def) { if(!env->scope->depth) { - if(!env->func && !GET_FLAG(decl->td, static)) - SET_FLAG(decl->td, member); if(!GET_FLAG(decl->td, ref) && t == env->class_def) ERR_O(exp_self(decl)->pos, "...(note: object of type '%s' declared inside itself)", t->name) + if(!GET_FLAG(decl->td, static)) + SET_FLAG(decl->td, member); } } decl->base = t->e->def; return decl->type = t; } + ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos)) Var_Decl_List list = decl->list; @@ -53,10 +54,10 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { const m_uint scope = !global ? env->scope->depth : env_push_global(env); const Nspc nspc = !global ? env->curr : env->global_nspc; do { - Type t = decl->type; const Var_Decl var = list->self; - const Value former = nspc_lookup_value0(env->curr, var->xid); CHECK_BB(isres(env, var->xid, exp_self(decl)->pos)) + Type t = decl->type; + const Value former = nspc_lookup_value0(env->curr, var->xid); if(former && !decl->td->exp && (!env->class_def || !(GET_FLAG(env->class_def, template) || GET_FLAG(env->class_def, scan1)))) ERR_B(var->pos, "variable %s has already been defined in the same scope...", @@ -65,17 +66,17 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { if(var->array->exp) { if(GET_FLAG(decl->td, ref)) ERR_B(td_pos(decl->td), "ref array must not have array expression.\n" - "e.g: int @my_array[];\nnot: int my_array[2];") + "e.g: int @my_array[];\nnot: @int my_array[2];") CHECK_BB(scan1_exp(env, var->array->exp)) } t = array_type(env, decl->type, var->array->depth); } - const Value v = var->value = former ? former : new_value(env->gwion->mp, t, s_name(var->xid)); + const Value v = var->value = former ?: new_value(env->gwion->mp, t, s_name(var->xid)); nspc_add_value(nspc, var->xid, v); v->flag = decl->td->flag; if(var->array && !var->array->exp) SET_FLAG(v, ref); - if(!env->func && !env->scope->depth && !env->class_def) + if(!env->scope->depth && !env->class_def) SET_FLAG(v, global); v->type = t; v->d.ptr = var->addr; @@ -137,9 +138,8 @@ ANN static m_bool scan1_exp_if(const Env env, const Exp_If* exp_if) { } ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary *unary) { - if((unary->op == op_spork || unary->op == op_fork) && unary->code) { - RET_NSPC(scan1_stmt(env, unary->code)) - } + if((unary->op == op_spork || unary->op == op_fork) && unary->code) + { RET_NSPC(scan1_stmt(env, unary->code)) } return unary->exp ? scan1_exp(env, unary->exp) : GW_OK; } @@ -168,9 +168,8 @@ describe_ret_nspc(if, Stmt_If,, !(scan1_exp(env, stmt->cond) < 0 || (stmt->else_body && scan1_stmt(env, stmt->else_body) < 0)) ? 1 : -1) ANN static inline m_bool scan1_stmt_code(const Env env, const Stmt_Code stmt) { - if(stmt->stmt_list) { - RET_NSPC(scan1_stmt_list(env, stmt->stmt_list)) - } + if(stmt->stmt_list) + { RET_NSPC(scan1_stmt_list(env, stmt->stmt_list)) } return GW_OK; } @@ -201,7 +200,7 @@ ANN m_bool scan1_stmt_enum(const Env env, const Stmt_Enum stmt) { } while((list = list->next)); return GW_OK; } -#include "func.h" + ANN static m_bool scan1_args(const Env env, Arg_List list) { do { const Var_Decl var = list->var_decl; @@ -227,6 +226,8 @@ ANN m_bool scan1_stmt_type(const Env env, const Stmt_Type stmt) { } ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union stmt) { + if(stmt->tmpl) + return GW_OK; if(!stmt->value) CHECK_BB(scan0_stmt_union(env, stmt)) Decl_List l = stmt->l; @@ -288,19 +289,19 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { CHECK_BB(env_storage(env, fdef->flag, td_pos(fdef->base->td))) if(tmpl_base(fdef->base->tmpl)) return GW_OK; + if(GET_FLAG(fdef, dtor) && !env->class_def) + ERR_B(td_pos(fdef->base->td), "dtor must be in class def!!") + if(GET_FLAG(fdef, op) && env->class_def) + SET_FLAG(fdef, static); struct Func_ fake = { .name=s_name(fdef->base->xid) }, *const former = env->func; env->func = &fake; ++env->scope->depth; - if(GET_FLAG(fdef, dtor) && !env->class_def) - ERR_B(td_pos(fdef->base->td), "dtor must be in class def!!") if(fdef->base->td) CHECK_OB((fdef->base->ret_type = known_type(env, fdef->base->td))) if(fdef->base->args) CHECK_BB(scan1_args(env, fdef->base->args)) if(!GET_FLAG(fdef, builtin)) CHECK_BB(scan1_stmt_code(env, &fdef->d.code->d.stmt_code)) - if(GET_FLAG(fdef, op) && env->class_def) - SET_FLAG(fdef, static); env->func = former; --env->scope->depth; return GW_OK; @@ -315,14 +316,14 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) { const Type parent = cdef->base.type->e->parent = known_type(env, cdef->base.ext); CHECK_OB(parent) Type t = parent; - while(t) { + do { if(cdef->base.type == t) ERR_B(pos, "recursive (%s <= %s) class declaration.", cdef->base.type->name, t->name); - t = t->e->parent; - } + } while((t = t->e->parent)); if(isa(parent, t_object) < 0) ERR_B(pos, "cannot extend primitive type '%s'", parent->name) - CHECK_BB(scanx_parent(parent, scan1_class_def, env)) + if(parent->e->def) + CHECK_BB(scanx_parent(parent, scan1_class_def, env)) if(type_ref(parent)) ERR_B(pos, "can't use ref type in class extend") return GW_OK; diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 254967f1..bc4e999e 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -8,20 +8,19 @@ #include "value.h" #include "func.h" #include "template.h" +#include "traverse.h" #include "optim.h" #include "parse.h" #include "nspc.h" #include "operator.h" -ANN /* static */ m_bool scan2_exp(const Env, const Exp); +//ANN /* static */ m_bool scan2_exp(const Env, const Exp); ANN static m_bool scan2_stmt(const Env, const Stmt); ANN static m_bool scan2_stmt_list(const Env, Stmt_List); -extern ANN m_bool scan1_class_def(const Env, const Class_Def); -ANN m_bool scan2_class_def(const Env, const Class_Def); ANN static m_bool scan2_exp_decl_template(const Env env, const Exp_Decl* decl) { - CHECK_BB(scan1_class_def(env, decl->type->e->def)) - CHECK_BB(scan2_class_def(env, decl->type->e->def)) + CHECK_BB(scan1_cdef(env, decl->type->e->def)) + CHECK_BB(scan2_cdef(env, decl->type->e->def)) return GW_OK; } @@ -270,6 +269,8 @@ ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) { } ANN m_bool scan2_stmt_union(const Env env, const Stmt_Union stmt) { + if(stmt->tmpl) + return GW_OK; const m_uint scope = union_push(env, stmt); Decl_List l = stmt->l; do CHECK_BB(scan2_exp(env, l->self)) @@ -450,7 +451,7 @@ ANN static m_str func_tmpl_name(const Env env, const Func_Def f) { vector_add(&v, (vtype)t); tlen += strlen(t->name); } while((id = id->next) && ++tlen); - char tmpl_name[tlen + 1]; + char tmpl_name[tlen + 2]; m_str str = tmpl_name; for(m_uint i = 0; i < vector_size(&v); ++i) { const m_str s = ((Type)vector_at(&v, i))->name; @@ -548,7 +549,8 @@ DECL_SECTION_FUNC(scan2) ANN static m_bool scan2_class_parent(const Env env, const Class_Def cdef) { const Type parent = cdef->base.type->e->parent; - CHECK_BB(scanx_parent(parent, scan2_class_def, env)) + if(parent->e->def) + CHECK_BB(scanx_parent(parent, scan2_cdef, env)) if(cdef->base.ext->array) CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp)) return GW_OK; diff --git a/src/parse/scanx.c b/src/parse/scanx.c index e722b086..492478fa 100644 --- a/src/parse/scanx.c +++ b/src/parse/scanx.c @@ -6,8 +6,9 @@ #include "type.h" #include "nspc.h" #include "vm.h" -#include "parse.h" #include "template.h" +#include "traverse.h" +#include "parse.h" ANN static inline m_bool _body(const Env e, Class_Body b, const _exp_func f) { do CHECK_BB(f(e, b->section)) @@ -24,10 +25,10 @@ ANN static inline m_bool tmpl_push(const Env env, const Tmpl* tmpl) { } ANN static inline m_int _push(const Env env, const Class_Def c) { - const m_uint scope = env_push_type(env, c->base.type); - if(c->base.tmpl && !tmpl_push(env, c->base.tmpl)) - return GW_ERROR; - return scope; + const m_int scope = env_push_type(env, c->base.type); + CHECK_BB(scope) + return (!c->base.tmpl || tmpl_push(env, c->base.tmpl)) ? + scope : GW_ERROR; } ANN static inline void _pop(const Env e, const Class_Def c, const m_uint s) { @@ -36,6 +37,7 @@ ANN static inline void _pop(const Env e, const Class_Def c, const m_uint s) { env_pop(e, s); } +// TODO: 'v' should be 2° argument ANN m_bool scanx_body(const Env e, const Class_Def c, const _exp_func f, void* d) { const m_int scope = _push(e, c); @@ -67,27 +69,18 @@ static inline Class_Def get_type_def(const Type t) { ANN m_bool scanx_parent(const Type t, const _exp_func f, void* d) { + if(t->e->parent == t_union) + return GW_OK; const Class_Def def = get_type_def(t); return def ? f(d, def) : GW_OK; } -/* -struct Parent_ { - void* ptr; - const Type t; - m_bool (*f)(void*, void*); - const ae_flag flag; -}; -ANN m_bool scanx_parent_actual(void* ptr, const Type t, m_bool (*f)(void*, void*), const ae_flag flag) { - if(t->e->def && (t->flag & flag) != flag) - return f(ptr, t->e->def); - return GW_OK; -} -ANN m_bool scanx_parent(void* ptr, const Type t, m_bool (*f)(void*, void*), const ae_flag flag) { - if(t->array_depth) - CHECK_BB(f(ptr, array_base(t))) - else - CHECK_BB(f(ptr, t)) - return GW_OK; +ANN m_bool scanx_cdef(const Env env, void* opt, const Class_Def cdef, + const _exp_func f_cdef, const _exp_func f_union) { + if(cdef->base.type->e->parent != t_union) + return f_cdef(opt, cdef); + CHECK_BB(template_push_types(env, cdef->base.tmpl)) + const m_bool ret = f_union(opt, &cdef->stmt->d.stmt_union); + nspc_pop_type(env->gwion->mp, env->curr); + return ret; } -*/ diff --git a/src/parse/template.c b/src/parse/template.c index f2511a58..5be9e0a3 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -6,6 +6,7 @@ #include "env.h" #include "type.h" #include "nspc.h" +#include "traverse.h" #include "template.h" #include "vm.h" #include "parse.h" @@ -70,9 +71,10 @@ ANN static inline size_t tmpl_set(struct tmpl_info* info, const Type t) { ANN static size_t template_size(const Env env, struct tmpl_info* info) { ID_List base = info->cdef->base.tmpl->list; + Type_List call = info->call; size_t size = tmpl_set(info, info->cdef->base.type); - do size += tmpl_set(info, type_decl_resolve(env, info->call->td)); - while((info->call = info->call->next) && (base = base->next) && ++size); + do size += tmpl_set(info, type_decl_resolve(env, call->td)); + while((call = call->next) && (base = base->next) && ++size); return size + 16 + 3; } @@ -82,7 +84,7 @@ ANN static inline m_str tmpl_get(struct tmpl_info* info, m_str str) { return str += vector_at(&info->size, info->index); } -ANN static void template_name(const Env env, struct tmpl_info* info, m_str s) { +ANN static void template_name(struct tmpl_info* info, m_str s) { m_str str = s; str = tmpl_get(info, str); *str++ = '<'; @@ -91,10 +93,7 @@ ANN static void template_name(const Env env, struct tmpl_info* info, m_str s) { str = tmpl_get(info, str); *str++ = (info->index < size - 1) ? ',' : '>'; } - if(info->cdef->base.type->e->owner == env->global_nspc) - sprintf(str, "%p", (void*)env->curr); - else - *str = '\0'; + *str = '\0'; } ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_List call) { @@ -102,7 +101,7 @@ ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_ vector_init(&info.type); vector_init(&info.size); char name[template_size(env, &info)]; - template_name(env, &info, name); + template_name(&info, name); vector_release(&info.type); vector_release(&info.size); return insert_symbol(name); @@ -158,13 +157,21 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) { return a->base.type; a->base.tmpl = new_tmpl(env->gwion->mp, get_total_type_list(env, t), 0); a->base.tmpl->call = type->types; - - CHECK_BO(scan0_class_def(env, a)) + if(isa(t, t_union) < 0) + CHECK_BO(scan0_class_def(env, a)) + else { + a->stmt = new_stmt_union(env->gwion->mp, (Decl_List)a->body, t->e->def->pos); + a->stmt->d.stmt_union.type_xid = a->base.xid; + CHECK_BO(scan0_stmt_union(env, &a->stmt->d.stmt_union)) + a->base.type = a->stmt->d.stmt_union.type; + a->base.type->e->def = a; + SET_FLAG(a, union); + } SET_FLAG(a->base.type, template | ae_flag_ref); a->base.type->e->owner = t->e->owner; if(GET_FLAG(t, builtin)) SET_FLAG(a->base.type, builtin); - CHECK_BO(scan1_class_def(env, a)) + CHECK_BO(scan1_cdef(env, a)) if(t->nspc->dtor) { a->base.type->nspc->dtor = t->nspc->dtor; SET_FLAG(a->base.type, dtor); diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index b320346d..bc1d4d9d 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -7,6 +7,7 @@ #include "nspc.h" #include "type.h" #include "vm.h" +#include "traverse.h" #include "parse.h" ANN Type type_decl_resolve(const Env env, const Type_Decl* td) { diff --git a/src/parse/type_utils.c b/src/parse/type_utils.c index d0aa6b3e..d27414a8 100644 --- a/src/parse/type_utils.c +++ b/src/parse/type_utils.c @@ -7,6 +7,7 @@ #include "value.h" #include "type.h" #include "vm.h" +#include "traverse.h" #include "parse.h" ANN m_bool isres(const Env env, const Symbol xid, const loc_t pos) { diff --git a/util b/util index 6e10d0bd..e2cb40df 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 6e10d0bd6a9e6731e35cc01d44562e0271755676 +Subproject commit e2cb40dfde5fe6200e3d14954aec316de1883136