emit_pop_scope(emit);
}
+// scope push problem
ANN static m_bool emit_stmt_flow(const Emitter emit, const Stmt_Flow stmt) {
const m_uint index = emit_code_size(emit);
Instr op = NULL;
return GW_OK;
}
+// scope push problem
ANN static m_bool emit_stmt_for(const Emitter emit, const Stmt_For stmt) {
emit_push_stack(emit);
CHECK_BB(emit_stmt(emit, stmt->c1, 1))
return emit_add_instr(emit, Reg2Mem);
}
+// scope push problem
ANN static m_bool emit_stmt_auto(const Emitter emit, const Stmt_Auto stmt) {
CHECK_BB(emit_exp(emit, stmt->exp, 0))
const Instr s1 = emit_add_instr(emit, MemSetImm);
return GW_OK;
}
+// scope push problem
ANN static m_bool emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt) {
emit_push_stack(emit);
CHECK_BB(emit_exp_pop_next(emit, stmt->cond, 0))
}
ANN static m_bool emit_type_def(const Emitter emit, const Type_Def tdef) {
+ if(SAFE_FLAG(tdef->type->e->def, emit))
+ return GW_OK;
return tdef->type->e->def ? emit_class_def(emit, tdef->type->e->def) : 1;
}
ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) {
const Type parent = cdef->base.type->e->parent;
const Type base = parent->e->d.base_type;
- if(base && !GET_FLAG(base, emit))
+ if(base && base->e->def && !GET_FLAG(base, emit))
CHECK_BB(emit_cdef(emit, base->e->def))
return !GET_FLAG(parent, emit) ? scanx_parent(parent, emit_cdef, emit) : GW_OK;
}
SET_FLAG(nspc->pre_ctor, ctor);
}
+ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) {
+ if(cdef->base.tmpl && cdef->base.tmpl->list)
+ CHECK_BB(template_push_types(emit->env, cdef->base.tmpl))
+ const m_bool ret = scanx_parent(cdef->base.type, emit_parent, emit);
+ if(cdef->base.tmpl && cdef->base.tmpl->list)
+ nspc_pop_type(emit->gwion->mp, emit->env->curr);
+ return ret;
+}
+
ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
+if(GET_FLAG(cdef->base.type, emit))return GW_OK;
const Type type = cdef->base.type;
const Nspc nspc = type->nspc;
- if(cdef->base.ext && cdef->base.ext->types)
- CHECK_BB(scanx_parent(cdef->base.type, emit_parent, emit))
+ if(cdef->base.ext && !GET_FLAG(cdef->base.type->e->parent, emit))
+ CHECK_BB(cdef_parent(emit, cdef))
SET_FLAG(type, emit);
nspc_allocdata(emit->gwion->mp, nspc);
emit_class_code(emit, type->name);
#define check_fptr_def dummy_func
DECL_SECTION_FUNC(check)
-ANN static m_bool check_class_parent(const Env env, const Class_Def cdef) {
+ANN static m_bool check_parent(const Env env, const Class_Def cdef) {
const Type parent = cdef->base.type->e->parent;
const Type_Decl *td = cdef->base.ext;
if(td->array)
vector_copy2(&parent->info->vtable, &nspc->info->vtable);
}
+ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
+ if(cdef->base.tmpl && cdef->base.tmpl->list)
+ CHECK_BB(template_push_types(env, cdef->base.tmpl))
+ const m_bool ret = scanx_parent(cdef->base.type, check_parent, env);
+ if(cdef->base.tmpl && cdef->base.tmpl->list)
+ nspc_pop_type(env->gwion->mp, env->curr);
+ return ret;
+}
+
ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
+if(GET_FLAG(cdef->base.type, checked))return GW_OK;
const Type type = cdef->base.type;
SET_FLAG(type, check);
if(type->e->parent == env->gwion->type[et_undefined]) {
return traverse_cdef(env, cdef);
}
if(cdef->base.ext)
- CHECK_BB(scanx_parent(cdef->base.type, check_class_parent, env))
+ CHECK_BB(cdef_parent(env, cdef))
assert(type->e->parent);
inherit(type);
if(cdef->body)
DECL_SECTION_FUNC(scan1)
ANN static Type scan1_get_parent(const Env env, const Type_Def tdef) {
- DECL_OO(const Type , parent, = tdef->type->e->parent = known_type(env, tdef->ext))
+ const Type parent = known_type(env, tdef->ext);
+ CHECK_OO((tdef->type->e->parent = parent));
Type t = parent;
do if(tdef->type == t)
ERR_O(td_pos(tdef->ext), _("recursive (%s <= %s) class declaration."), tdef->type->name, t->name)
return GW_OK;
}
+ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
+ if(cdef->base.tmpl && cdef->base.tmpl->list)
+ CHECK_BB(template_push_types(env, cdef->base.tmpl))
+ const m_bool ret = scanx_parent(cdef->base.type, scan1_parent, env);
+ if(cdef->base.tmpl && cdef->base.tmpl->list)
+ nspc_pop_type(env->gwion->mp, env->curr);
+ return ret;
+}
+
ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
+ if(GET_FLAG(cdef->base.type, scan1))return GW_OK;
SET_FLAG(cdef->base.type, scan1);
if(cdef->base.ext)
- CHECK_BB(scanx_parent(cdef->base.type, scan1_parent, env))
+ CHECK_BB(cdef_parent(env, cdef))
if(cdef->body)
CHECK_BB(env_body(env, cdef, scan1_section))
SET_FLAG(cdef, scan1);
#define scan2_enum_def dummy_func
DECL_SECTION_FUNC(scan2)
-ANN static m_bool scan2_class_parent(const Env env, const Class_Def cdef) {
+ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) {
const Type parent = cdef->base.type->e->parent;
if(parent->e->def && !GET_FLAG(parent, scan2))
CHECK_BB(scanx_parent(parent, scan2_cdef, env))
return GW_OK;
}
+ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
+ if(cdef->base.tmpl && cdef->base.tmpl->list)
+ CHECK_BB(template_push_types(env, cdef->base.tmpl))
+ const m_bool ret = scanx_parent(cdef->base.type, scan2_parent, env);
+ if(cdef->base.tmpl && cdef->base.tmpl->list)
+ nspc_pop_type(env->gwion->mp, env->curr);
+ return ret;
+}
+
ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
+ if(GET_FLAG(cdef->base.type, scan2))return GW_OK;
SET_FLAG(cdef->base.type, scan2);
if(cdef->base.ext)
- CHECK_BB(scanx_parent(cdef->base.type, scan2_class_parent, env))
+ CHECK_BB(cdef_parent(env, cdef))
if(cdef->body)
CHECK_BB(env_body(env, cdef, scan2_section))
return GW_OK;
DECL_OO(const Symbol, name, = template_id(env, def, call))
if(env->class_def && name == insert_symbol(env->class_def->name))
return env->class_def->e->def;
- const Type t = nspc_lookup_type0(env->curr, name);
+ const Type t = nspc_lookup_type1(env->curr, name);
if(t)
return t->e->def;
const Class_Def c = cpy_class_def(env->gwion->mp, def);
CHECK_BB(scan1_class_def(env, def))
if(!GET_FLAG(def, scan2))
CHECK_BB(scan2_class_def(env, def))
- return check_class_def(env, def);
+ if(!GET_FLAG(def, checked))
+ return check_class_def(env, def);
+ return GW_OK;
}