ANN struct Func_Base_* cpy_func_base(MemPool, struct Func_Base_*);
ANN Class_Def cpy_class_def(MemPool, Class_Def);
ANN Type_List cpy_type_list(MemPool p, const Type_List src);
+ANN Decl_List cpy_decl_list(MemPool p, const Decl_List src);
#endif
xxx_cdef(scan2)
xxx_cdef(check)
xxx_cdef(traverse)
+
+__attribute__((returns_nonnull))
+ANN Type get_type(const Type t);
#endif
ANN static void emit_pre_ctor(const Emitter emit, const Type type) {
if(type->e->parent)
emit_pre_ctor(emit, type->e->parent);
- if(type->nspc->pre_ctor)
+ if(type->nspc->pre_ctor && !GET_FLAG(type, nonnull))
emit_ext_ctor(emit, type->nspc->pre_ctor);
if(GET_FLAG(type, template) && GET_FLAG(type, builtin)) {
const Type t = template_parent(emit->env, type);
ANN static m_bool emit_cdef(const Emitter, const Class_Def);
ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) {
- const Type t = decl->type;
+ const Type t = get_type(decl->type);
return !GET_FLAG(t, emit) ? emit_cdef(emit, t->e->def) : GW_OK;
}
static OP_CHECK(opck_spork) {
const Exp_Unary* unary = (Exp_Unary*)data;
+ if(exp_self(unary)->next)
+ ERR_O(exp_self(unary)->pos, _("spork/fork must not have next expression"))
if(unary->op == insert_symbol("fork") && !unary->fork_ok)
ERR_O(exp_self(unary)->pos, _("forks must be stored in a value:\n"
"fork xxx @=> Fork f"))
MemPool p = shred->info->mp;
Type t = o->type_ref;
do {
+ if(GET_FLAG(t, nonnull))
+ t = t->e->parent;
struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
Value v;
while(scope_iter(&iter, &v) > 0) {
ANN static void free_type(Type a, Gwion gwion) {
if(GET_FLAG(a, template)) {
if(GET_FLAG(a, union)) {
- if(a->e->def->union_def && !GET_FLAG(a, pure)) { // <=> decl_list
+ if(a->e->def->union_def) {
+ if(!GET_FLAG(a, pure)) { // <=> decl_list
UNSET_FLAG(a->e->def->union_def, global);
free_union_def(gwion->mp, a->e->def->union_def);
+ } else
+ free_decl_list(gwion->mp, a->e->def->list);
}
a->e->def->union_def = NULL;
} else if(a->e->def)
}
if(!decl->type)
ERR_O(td_pos(decl->td), _("can't infer type."));
- if(GET_FLAG(decl->type , template) && !GET_FLAG(decl->type, check))
- CHECK_BO(check_cdef(env, decl->type->e->def))
+{
+ const Type t = get_type(decl->type);
+ if(GET_FLAG(t, template) && !GET_FLAG(t, check))
+ CHECK_BO(check_cdef(env, t->e->def))
+}
const m_bool global = GET_FLAG(decl->td, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
do {
cpy_vec(p, &a->d.vec, &src->d.vec);
break;
default:
- a->d.exp = cpy_exp(p, src->d.exp);
+ if(src->d.exp)
+ a->d.exp = cpy_exp(p, src->d.exp);
break;
}
a->primary_type = src->primary_type;
return a;
}
-ANN static Decl_List cpy_decl_list(MemPool p, const Decl_List src) {
+ANN /*static */Decl_List cpy_decl_list(MemPool p, const Decl_List src) {
Decl_List a = mp_calloc(p, Decl_List);
a->self = cpy_exp(p, src->self);
if(src->next)
#include "traverse.h"
#include "template.h"
#include "parse.h"
+#include "cpy_ast.h"
static inline void add_type(const Env env, const Nspc nspc, const Type t) {
map_set(&nspc->info->type->map, (m_uint)insert_symbol(t->name), (m_uint)t);
udef->value->owner = nspc;
nspc_add_value(nspc, udef->xid, udef->value);
add_type(env, nspc, t);
- SET_FLAG(t, scan1);
+ SET_FLAG(t, scan1 | ae_flag_union);
SET_FLAG(udef->value, checked | udef->flag);
if(env->class_def && !GET_FLAG(udef, static)) {
SET_FLAG(udef->value, member);
env->curr : env->global_nspc;
udef->type = union_type(env, nspc, udef->type_xid, 1);
SET_FLAG(udef->type, checked);
- SET_FLAG(udef->type, scan1);
+ SET_FLAG(udef->type, scan1 | ae_flag_union);
} else {
const Nspc nspc = !GET_FLAG(udef, global) ?
env->curr : env->global_nspc;
nspc_add_value(nspc, udef->xid, udef->value);
add_type(env, nspc, t);
SET_FLAG(udef->value, checked | udef->flag);
- SET_FLAG(t, scan1);
+ SET_FLAG(t, scan1 | ae_flag_union);
}
if(udef->tmpl) {
if(tmpl_base(udef->tmpl)) {
udef->type->e->def = cdef;
cdef->base.tmpl = udef->tmpl;
cdef->base.type = udef->type;
- cdef->list = udef->l;
+ cdef->list = cpy_decl_list(env->gwion->mp, udef->l);
SET_FLAG(cdef, union);
SET_FLAG(udef->type, pure);
SET_FLAG(udef, template);
return GW_OK;
}
-ANN m_bool scan0_class_def(const Env env, const Class_Def cdef) {
- CHECK_BB(scan0_class_def_pre(env, cdef))
+ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef)))
SET_FLAG(cdef->base.type, scan0);
if(cdef->body) {
if(call)cdef->base.tmpl->call = NULL;
}
(void)mk_class(env, cdef->base.type);
+ return GW_OK;
+}
+
+ANN m_bool scan0_class_def(const Env env, const Class_Def cdef) {
+ CHECK_BB(scan0_class_def_pre(env, cdef))
+ const m_bool ret = scan0_class_def_inner(env, cdef);
if(GET_FLAG(cdef, global))
env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
- return GW_OK;
+ return ret;
}
ANN m_bool scan0_ast(const Env env, Ast ast) {
ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
ANN static Type void_type(const Env env, const Type_Decl* td) {
- DECL_OO(const Type, t, = known_type_noref(env, td))
- if(t->e->def && !GET_FLAG(t, scan1))
+ DECL_OO(const Type, type, = known_type_noref(env, td))
+// if(t->e->def && !GET_FLAG(t, scan1))
+{
+ const Type t = get_type(type);
+ if(GET_FLAG(t, template) && !GET_FLAG(t, scan1))
CHECK_BO(scan1_cdef(env, t->e->def))
- if(t->size)
- return t;
+}
+ if(type->size)
+ return type;
ERR_O(td_pos(td), _("cannot declare variables of size '0' (i.e. 'void')..."))
}
return isa(tdef->type, t_fptr) < 0 ? scan1_cdef(env, tdef->type->e->def) : GW_OK;
}
+ANN m_bool scan1_union_def_action(const Env env, const Union_Def udef,
+ const Decl_List l) {
+ const Exp_Decl decl = l->self->d.exp_decl;
+ SET_FLAG(decl.td, checked | udef->flag);
+ const m_bool global = GET_FLAG(udef, global);
+ if(global)
+ UNSET_FLAG(decl.td, global);
+ if(GET_FLAG(udef, member))
+ SET_FLAG(decl.td, member);
+ else if(GET_FLAG(udef, static))
+ SET_FLAG(decl.td, static);
+ CHECK_BB(scan1_exp(env, l->self))
+ if(global)
+ SET_FLAG(decl.td, global);
+ return GW_OK;
+}
+
+ANN m_bool scan1_union_def_inner(const Env env, const Union_Def udef) {
+ Decl_List l = udef->l;
+ do CHECK_BB(scan1_union_def_action(env, udef, l))
+ while((l = l->next));
+ return GW_OK;
+}
+
ANN m_bool scan1_union_def(const Env env, const Union_Def udef) {
if(tmpl_base(udef->tmpl))
return GW_OK;
- Decl_List l = udef->l;
const m_uint scope = union_push(env, udef);
if(udef->xid || udef->type_xid) {
UNSET_FLAG(udef, private);
UNSET_FLAG(udef, protect);
}
- do {
- const Exp_Decl decl = l->self->d.exp_decl;
- SET_FLAG(decl.td, checked | udef->flag);
- const m_bool global = GET_FLAG(udef, global);
- if(global)
- UNSET_FLAG(decl.td, global);
- if(GET_FLAG(udef, member))
- SET_FLAG(decl.td, member);
- else if(GET_FLAG(udef, static))
- SET_FLAG(decl.td, static);
- CHECK_BB(scan1_exp(env, l->self))
- if(global)
- SET_FLAG(decl.td, global);
- } while((l = l->next));
+ const m_bool ret = scan1_union_def_inner(env, udef);
union_pop(env, udef, scope);
SET_FLAG(udef, scan1);
- return GW_OK;
+ return ret;
}
static const _exp_func stmt_func[] = {
const m_bool global = GET_FLAG(decl->td, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
const Type type = decl->type;
- if(type->e->def && /*GET_FLAG(type, template) &&*/ !GET_FLAG(type, scan2))
- CHECK_BB(scan2_cdef(env, decl->type->e->def))
+{
+ const Type t = get_type(decl->type);
+ if(GET_FLAG(t, template) && !GET_FLAG(t, scan2))
+ CHECK_BB(scan2_cdef(env, t->e->def))
+}
Var_Decl_List list = decl->list;
do {
const Var_Decl var = list->self;
return ret;
}
#undef scanx_parent
+
__attribute__((returns_nonnull))
-static inline Type get_type(const Type t) {
-// return !t->array_depth ? t : array_base(t);
+ANN Type get_type(const Type t) {
const Type type = !t->array_depth ? t : array_base(t);
return !GET_FLAG(type, nonnull) ? type : type->e->parent;
}
__attribute__((returns_nonnull))
static inline Class_Def get_type_def(const Type t) {
- return get_type(t)->e->def;
+ const Type type = get_type(t);
+ return type->e->def;
}
ANN m_bool
CHECK_BO(scan0_class_def(env, a))
map_set(&env->curr->info->type->map, (vtype)a->base.xid, (vtype)a->base.type);
} else {
- a->union_def = new_union_def(env->gwion->mp, a->list, t->e->def->pos);
+ a->union_def = new_union_def(env->gwion->mp, a->list,
+ loc_cpy(env->gwion->mp, t->e->def->pos));
a->union_def->type_xid = a->base.xid;
CHECK_BO(scan0_union_def(env, a->union_def))
a->base.type = a->union_def->type;