From: fennecdjay Date: Sun, 16 Jun 2019 22:12:03 +0000 (+0200) Subject: :art: Intern Func_Def templating X-Git-Tag: nightly~2442^2 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=refs%2Fpull%2F125%2Fhead;p=gwion.git :art: Intern Func_Def templating --- diff --git a/src/emit/emit.c b/src/emit/emit.c index 4ae60771..42d2fb5e 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -686,7 +686,7 @@ ANN static inline m_int push_tmpl_func(const Emitter emit, const Func f) { is_fptr(v->type)) return emit->env->scope->depth; const m_uint scope = emit_push(emit, v->owner_class, v->owner); - CHECK_BB(traverse_func_template(emit->env, f->def)) + CHECK_BB(traverse_func_def(emit->env, f->def)) return (m_int)scope; } @@ -696,10 +696,8 @@ ANN static m_bool emit_exp_call_template(const Emitter emit, const Exp_Call* exp exp_call->m_func->def->base->tmpl->call = exp_call->tmpl->call; DECL_BB(const m_int,scope, = push_tmpl_func(emit, exp_call->m_func)) CHECK_BB(prepare_call(emit, exp_call)) - if(!is_fptr(exp_call->m_func->value_ref->type)) { - emit_pop_type(emit); + if(!is_fptr(exp_call->m_func->value_ref->type)) emit_pop(emit, (m_uint)scope); - } UNSET_FLAG(exp_call->m_func, checked); return GW_OK; } @@ -757,10 +755,8 @@ ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) { emit_push_type(emit, dt->owner_class) : emit_push(emit, NULL, dt->owner); m_bool ret = GW_ERROR; dt->def->base->tmpl->call = dt->tl;// in INSTR - if(!dt->def->base->func && traverse_func_template(emit->env, dt->def) > 0) { + if(!dt->def->base->func && traverse_func_def(emit->env, dt->def) > 0) ret = emit_func_def(emit, dt->def); - emit_pop_type(emit); - } emit_pop(emit, scope); return ret; } @@ -1688,7 +1684,7 @@ ANN static void emit_func_def_code(const Emitter emit, const Func func) { func->def->stack_depth = func->code->stack_depth; } -ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) { +ANN static m_bool _fdef_body(const Emitter emit, const Func_Def fdef) { if(fdef->base->args) emit_func_def_args(emit, fdef->base->args); if(GET_FLAG(fdef, variadic)) @@ -1699,6 +1695,18 @@ ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) { return GW_OK; } +ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) { + vector_add(&emit->variadic, 0); + CHECK_BB(_fdef_body(emit, fdef)) + if(GET_FLAG(fdef, variadic)) { + if(!get_variadic(emit)) + ERR_B(fdef->pos, "invalid variadic use") + if(!GET_FLAG(fdef->base->func, empty)) + ERR_B(fdef->pos, "invalid variadic use") + } + return GW_OK; +} + ANN static m_bool tmpl_rettype(const Emitter emit, const Func_Def fdef) { CHECK_BB(template_push_types(emit->env, fdef->base->tmpl)) const m_bool ret = emit_parent_inner(emit, fdef->base->ret_type->e->def); @@ -1709,12 +1717,8 @@ ANN static m_bool tmpl_rettype(const Emitter emit, const Func_Def fdef) { ANN static m_bool emit_func_def(const Emitter emit, const Func_Def fdef) { const Func func = get_func(emit->env, fdef); const Func former = emit->env->func; - if(func->code) - return GW_OK; - if(tmpl_base(fdef->base->tmpl)) { - UNSET_FLAG(fdef, template); + if(tmpl_base(fdef->base->tmpl)) return GW_OK; - } if(GET_FLAG(fdef->base->ret_type, template) && !GET_FLAG(fdef->base->ret_type, emit)) CHECK_BB(tmpl_rettype(emit, fdef)) if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template)) @@ -1724,23 +1728,17 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def fdef) { emit_func_def_init(emit, func); if(GET_FLAG(func, member)) stack_alloc_this(emit); - emit_push_scope(emit); emit->env->func = func; - vector_add(&emit->variadic, 0); + emit_push_scope(emit); + if(fdef->base->tmpl) + CHECK_BB(template_push_types(emit->env, fdef->base->tmpl)) CHECK_BB(emit_func_def_body(emit, fdef)) - if(GET_FLAG(fdef, variadic)) { - if(!get_variadic(emit)) - ERR_B(fdef->pos, "invalid variadic use") - if(!GET_FLAG(func, empty)) - ERR_B(fdef->pos, "invalid variadic use") - } - vector_pop(&emit->variadic); emit_func_def_return(emit); emit_func_def_code(emit, func); - emit->env->func = former; + if(fdef->base->tmpl) + emit_pop_type(emit); emit_pop_code(emit); - if(GET_FLAG(fdef, op)) - SET_FLAG(func->code, op); + emit->env->func = former; if(!emit->env->class_def && !GET_FLAG(fdef, global) && !fdef->base->tmpl) emit_func_def_global(emit, func->value_ref); if(emit->memoize && GET_FLAG(func, pure)) diff --git a/src/parse/check.c b/src/parse/check.c index 29a683a9..f7237760 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -410,9 +410,7 @@ ANN static inline Value template_get_ready(const Env env, const Value v, const m } static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *exp) { - CHECK_BO(template_push_types(env, fdef->base->tmpl)) const m_bool ret = traverse_func_def(env, fdef); - nspc_pop_type(env->gwion->mp, env->curr); if(ret > 0) { const Func f = fdef->base->func; if(check_call(env, exp) > 0) { @@ -1142,12 +1140,12 @@ ANN m_bool check_func_def(const Env env, const Func_Def fdef) { m_bool ret = GW_OK; if(tmpl_base(fdef->base->tmpl)) return env->class_def ? check_parent_match(env, fdef) : 1; - if(fdef->base->td && !fdef->base->td->xid) { + if(fdef->base->td && !fdef->base->td->xid) { // tmpl ? fdef->base->ret_type = check_td(env, fdef->base->td); return traverse_func_def(env, fdef); } CHECK_BB(check_func_def_override(env, fdef)) - if(env->class_def) + if(env->class_def) // tmpl ? CHECK_BB(check_parent_match(env, fdef)) else if(GET_FLAG(fdef, global)) env_push_global(env); @@ -1155,6 +1153,8 @@ ANN m_bool check_func_def(const Env env, const Func_Def fdef) { env->func = func; ++env->scope->depth; nspc_push_value(env->gwion->mp, env->curr); + if(fdef->base->tmpl) + CHECK_BB(template_push_types(env, fdef->base->tmpl)) if(!fdef->base->args) UNSET_FLAG(fdef->base->func, pure); else @@ -1171,6 +1171,8 @@ ANN m_bool check_func_def(const Env env, const Func_Def fdef) { else if(GET_FLAG(fdef, op)) operator_func(func); } + if(fdef->base->tmpl) + nspc_pop_type(env->gwion->mp, env->curr); nspc_pop_value(env->gwion->mp, env->curr); --env->scope->depth; env->func = former; diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 4240b335..834b14d4 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -317,6 +317,16 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) { return GW_OK; } +ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) { + 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) && fdef->d.code) + CHECK_BB(scan1_stmt_code(env, &fdef->d.code->d.stmt_code)) + return GW_OK; +} + ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { if(fdef->base->td) CHECK_BB(env_storage(env, fdef->flag, td_pos(fdef->base->td))) @@ -329,15 +339,14 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { struct Func_ fake = { .name=s_name(fdef->base->xid) }, *const former = env->func; env->func = &fake; ++env->scope->depth; - 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) && fdef->d.code) - CHECK_BB(scan1_stmt_code(env, &fdef->d.code->d.stmt_code)) + if(fdef->base->tmpl) + CHECK_BB(template_push_types(env, fdef->base->tmpl)) + const m_bool ret = scan1_fdef(env, fdef); + if(fdef->base->tmpl) + nspc_pop_type(env->gwion->mp, env->curr); env->func = former; --env->scope->depth; - return GW_OK; + return ret; } DECL_SECTION_FUNC(scan1) diff --git a/src/parse/scan2.c b/src/parse/scan2.c index b800ee17..a3e56c75 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -497,37 +497,20 @@ ANN2(1,2) static m_str func_name(const Env env, const Func_Def f, const Value v) return template_helper(env, f); } -ANN m_bool scan2_func_def(const Env env, const Func_Def f) { - const m_uint scope = !GET_FLAG(f, global) ? env->scope->depth : env_push_global(env); - const Value overload = nspc_lookup_value0(env->curr, f->base->xid); - const Value res = nspc_lookup_value1(env->global_nspc, f->base->xid); - if(res) - ERR_B(f->pos, "'%s' already declared as type", s_name(f->base->xid)) - f->stack_depth = (env->class_def && !GET_FLAG(f, static) && !GET_FLAG(f, global)) ? SZ_INT : 0; - if(GET_FLAG(f, variadic)) - f->stack_depth += SZ_INT; - if(overload) - CHECK_BB(scan2_func_def_overload(env, f, overload)) - if(tmpl_base(f->base->tmpl)) - return scan2_func_def_template(env, f, overload); + +ANN m_bool scan2_fdef(const Env env, const Func_Def f, const Value overload) { const m_str name = func_name(env, f, overload); if((m_int)name <= GW_OK) return (m_bool)(m_uint)name; -// scan2 prelude const Func base = get_func(env, f); if(!base) CHECK_OB(func_create(env, f, overload, name)) else f->base->func = base; -// body if(f->base->args) CHECK_BB(scan2_args(env, f)) if(!GET_FLAG(f, builtin) && f->d.code) CHECK_BB(scan2_func_def_code(env, f)) -// gpop - if(GET_FLAG(f, global)) - env_pop(env, scope); - if(!base) { if(GET_FLAG(f, op)) CHECK_BB(scan2_func_def_op(env, f)) @@ -536,6 +519,27 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { return GW_OK; } +ANN m_bool scan2_func_def(const Env env, const Func_Def f) { + const m_uint scope = !GET_FLAG(f, global) ? env->scope->depth : env_push_global(env); + const Value overload = nspc_lookup_value0(env->curr, f->base->xid); + const Value res = nspc_lookup_value1(env->global_nspc, f->base->xid); + if(res) + ERR_B(f->pos, "'%s' already declared as type", s_name(f->base->xid)) + f->stack_depth = (env->class_def && !GET_FLAG(f, static) && !GET_FLAG(f, global)) ? SZ_INT : 0; + if(GET_FLAG(f, variadic)) + f->stack_depth += SZ_INT; + if(overload) + CHECK_BB(scan2_func_def_overload(env, f, overload)) + if(f->base->tmpl) + CHECK_BB(template_push_types(env, f->base->tmpl)) + const m_bool ret = (!tmpl_base(f->base->tmpl) ? scan2_fdef : scan2_func_def_template)(env, f, overload); + if(f->base->tmpl) + nspc_pop_type(env->gwion->mp, env->curr); + if(GET_FLAG(f, global)) + env_pop(env, scope); + return ret; +} + DECL_SECTION_FUNC(scan2) ANN static m_bool scan2_class_parent(const Env env, const Class_Def cdef) { diff --git a/src/parse/traverse_template.c b/src/parse/traverse_template.c deleted file mode 100644 index 8b32476f..00000000 --- a/src/parse/traverse_template.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "oo.h" -#include "env.h" -#include "nspc.h" -#include "traverse.h" -#include "template.h" -#include "vm.h" -#include "gwion.h" - -ANN m_bool traverse_func_template(const Env env, const Func_Def def) { - CHECK_BB(template_push_types(env, def->base->tmpl)) - return traverse_func_def(env, def); -}