From: fennecdjay Date: Wed, 2 Oct 2019 23:09:18 +0000 (+0200) Subject: :art: Introduce scanx_fdef X-Git-Tag: nightly~2198^2~166 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=66e1e977f7a7365b0e01eff3f57abcad0ee77b2a;p=gwion.git :art: Introduce scanx_fdef --- diff --git a/include/parse.h b/include/parse.h index 8b41eed8..a37ff5c8 100644 --- a/include/parse.h +++ b/include/parse.h @@ -88,6 +88,8 @@ xxx_cdef(scan2) xxx_cdef(check) xxx_cdef(traverse) +ANN m_bool scanx_fdef(const Env, void *, const Func_Def, const _exp_func); + __attribute__((returns_nonnull)) ANN Type get_type(const Type t); ANN m_bool check_subscripts(const Env, const Array_Sub); diff --git a/src/emit/emit.c b/src/emit/emit.c index 192b100f..afcde902 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1749,7 +1749,6 @@ ANN static void emit_func_def_return(const Emitter emit) { instr->m_val = val; } vector_clear(&emit->code->stack_return); - emit_pop_scope(emit); if(emit->info->memoize && GET_FLAG(emit->env->func, pure)) emit_add_instr(emit, MemoizeStore); } @@ -1803,6 +1802,22 @@ ANN static m_bool tmpl_rettype(const Emitter emit, const Func_Def fdef) { return ret; } +ANN static m_bool emit_fdef(const Emitter emit, const Func_Def fdef) { + CHECK_BB(emit_func_def_body(emit, fdef)) + emit_func_def_return(emit); + return GW_OK; +} + +ANN static void emit_fdef_finish(const Emitter emit, const Func_Def fdef) { + const Func func = fdef->base->func; + func->code = emit_func_def_code(emit, func); + if(!emit->env->class_def && !GET_FLAG(fdef, global) && !fdef->base->tmpl) + emit_func_def_global(emit, func->value_ref); + if(emit->info->memoize && GET_FLAG(func, pure)) + func->code->memoize = memoize_ini(emit, func, + kindof(fdef->base->ret_type->size, !fdef->base->ret_type->size)); +} + ANN static m_bool emit_func_def(const Emitter emit, const Func_Def fdef) { const Func func = fdef->base->func; const Func former = emit->env->func; @@ -1819,22 +1834,11 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def fdef) { stack_alloc_this(emit); emit->env->func = func; emit_push_scope(emit); - if(fdef->base->tmpl) - CHECK_BB(template_push_types(emit->env, fdef->base->tmpl)) - const m_bool ret = emit_func_def_body(emit, fdef); + const m_bool ret = scanx_fdef(emit->env, emit, fdef, (_exp_func)emit_fdef); + emit_pop_scope(emit); + emit->env->func = former; if(ret > 0) - emit_func_def_return(emit); - if(fdef->base->tmpl) - emit_pop_type(emit); - if(ret > 0) { - func->code = emit_func_def_code(emit, func); - 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->info->memoize && GET_FLAG(func, pure)) - func->code->memoize = memoize_ini(emit, func, - kindof(func->def->base->ret_type->size, !func->def->base->ret_type->size)); - } + emit_fdef_finish(emit, fdef); return ret; } diff --git a/src/parse/check.c b/src/parse/check.c index 007b0c07..214816aa 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1327,7 +1327,7 @@ ANN static Value set_variadic(const Env env) { return variadic; } -ANN m_bool _check_func_def(const Env env, const Func_Def fdef) { +ANN m_bool check_fdef(const Env env, const Func_Def fdef) { if(fdef->base->args) CHECK_BB(check_func_args(env, fdef->base->args)) else @@ -1343,15 +1343,6 @@ ANN m_bool _check_func_def(const Env env, const Func_Def fdef) { return GW_OK; } -ANN m_bool _check_func_def_tmpl(const Env env, const Func_Def fdef) { - if(fdef->base->tmpl) - CHECK_BB(template_push_types(env, fdef->base->tmpl)) - const m_bool ret = _check_func_def(env, fdef); - if(fdef->base->tmpl) - nspc_pop_type(env->gwion->mp, env->curr); - return ret; -} - ANN m_bool check_func_def(const Env env, const Func_Def fdef) { const Func func = fdef->base->func; assert(func == fdef->base->func); @@ -1369,7 +1360,7 @@ 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); - const m_bool ret = _check_func_def_tmpl(env, fdef); + const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)check_fdef); 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 6bf8923e..976e3d31 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -397,15 +397,6 @@ ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) { return GW_OK; } -ANN static m_bool _scan1_func_def(const Env env, const Func_Def fdef) { - 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); - return ret; -} - 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))) @@ -414,7 +405,7 @@ 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; - const m_bool ret = _scan1_func_def(env, fdef); + const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)scan1_fdef); --env->scope->depth; env->func = former; return ret; diff --git a/src/parse/scan2.c b/src/parse/scan2.c index ea00c452..9bd15dd6 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -352,7 +352,7 @@ ANN2(1,2) static Value func_value(const Env env, const Func f, return v; } -ANN2(1, 2) static m_bool scan2_func_def_template(const Env env, const Func_Def f, const Value overload) { +ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const Value overload) { const m_str name = s_name(f->base->xid); const Func func = scan_new_func(env, f, name); const Value value = func_value(env, func, overload); @@ -500,8 +500,7 @@ ANN2(1,2) static m_str func_name(const Env env, const Func_Def f, const Value v) return template_helper(env, f); } - -ANN2(1,2) m_bool scan2_fdef(const Env env, const Func_Def f, const Value overload) { +ANN2(1,2) m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value overload) { const m_str name = func_name(env, f, overload ?: NULL); if((m_int)name <= GW_OK) return (m_bool)(m_uint)name; @@ -522,16 +521,11 @@ ANN2(1,2) m_bool scan2_fdef(const Env env, const Func_Def f, const Value overloa return GW_OK; } -ANN m_bool _scan2_func_def(const Env env, const Func_Def f) { +ANN m_bool scan2_fdef(const Env env, const Func_Def f) { const Value overload = nspc_lookup_value0(env->curr, f->base->xid); 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); - return ret; + return (!tmpl_base(f->base->tmpl) ? scan2_fdef_std : scan2_fdef_tmpl)(env, f, overload); } ANN m_bool scan2_func_def(const Env env, const Func_Def f) { @@ -539,7 +533,7 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { 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; - const m_bool ret = _scan2_func_def(env, f); + const m_bool ret = scanx_fdef(env, env, f, (_exp_func)scan2_fdef); if(GET_FLAG(f, global)) env_pop(env, scope); return ret; diff --git a/src/parse/scanx.c b/src/parse/scanx.c index b94925ac..7414900d 100644 --- a/src/parse/scanx.c +++ b/src/parse/scanx.c @@ -75,3 +75,13 @@ ANN m_bool scanx_cdef(const Env env, void* opt, const Class_Def cdef, nspc_pop_type(env->gwion->mp, env->curr); return ret; } + +ANN m_bool scanx_fdef(const Env env, void *data, + const Func_Def fdef, const _exp_func func) { + if(fdef->base->tmpl) + CHECK_BB(template_push_types(env, fdef->base->tmpl)) + const m_bool ret = func(data, fdef); + if(fdef->base->tmpl) + nspc_pop_type(env->gwion->mp, env->curr); + return ret; +}