From faabb71a5440aac48b3d9999c2cc3c9e3fc0c5fe Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Wed, 9 Oct 2019 02:50:08 +0200 Subject: [PATCH] :art: Improve templating --- src/emit/emit.c | 22 +++++++++++++++++++--- src/parse/check.c | 14 ++++++++++++-- src/parse/scan1.c | 15 +++++++++++++-- src/parse/scan2.c | 14 ++++++++++++-- src/parse/template.c | 2 +- src/parse/traverse.c | 4 +++- 6 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index a3b8b166..7d82d2aa 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1249,6 +1249,7 @@ ANN static void emit_pop_stack(const Emitter emit, const m_uint index) { 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; @@ -1268,6 +1269,7 @@ ANN static m_bool emit_stmt_flow(const Emitter emit, const Stmt_Flow stmt) { 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)) @@ -1293,6 +1295,7 @@ ANN static Instr emit_stmt_autoptr_init(const Emitter emit, const Type type) { 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); @@ -1319,6 +1322,7 @@ ANN static m_bool emit_stmt_auto(const Emitter emit, const Stmt_Auto stmt) { 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)) @@ -1357,6 +1361,8 @@ ANN static m_bool emit_stmt_jump(const Emitter emit, const Stmt_Jump stmt) { } 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; } @@ -1864,7 +1870,7 @@ ANN Code* emit_class_code(const Emitter emit, const m_str name) { 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; } @@ -1879,13 +1885,23 @@ ANN void emit_class_finish(const Emitter emit, const Nspc nspc) { 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); diff --git a/src/parse/check.c b/src/parse/check.c index 3e6fa6f0..87c5fc5a 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1405,7 +1405,7 @@ ANN m_bool check_func_def(const Env env, const Func_Def fdef) { #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) @@ -1424,9 +1424,19 @@ ANN static inline void inherit(const Type t) { 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]) { @@ -1434,7 +1444,7 @@ ANN m_bool check_class_def(const Env env, const Class_Def cdef) { 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) diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 17d85f5f..7c96c839 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -416,7 +416,8 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { 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) @@ -440,12 +441,22 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) { 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); diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 39ee67a2..f9ee49bd 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -519,7 +519,7 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { #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)) @@ -528,12 +528,22 @@ ANN static m_bool scan2_class_parent(const Env env, const Class_Def cdef) { 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; diff --git a/src/parse/template.c b/src/parse/template.c index 7c66afb8..82d7778d 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -130,7 +130,7 @@ ANN static Class_Def template_class(const Env env, const Class_Def def, const Ty 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); diff --git a/src/parse/traverse.c b/src/parse/traverse.c index 9442b6a5..dba8c910 100644 --- a/src/parse/traverse.c +++ b/src/parse/traverse.c @@ -59,5 +59,7 @@ ANN m_bool traverse_class_def(const Env env, const Class_Def 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; } -- 2.43.0