From: Pranav Date: Wed, 7 Oct 2020 10:47:07 +0000 (+0530) Subject: :art: Move find_template_match and helping fns to new file X-Git-Tag: nightly~1238^2 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=cee8a2f5a14d6f7518034d9ae570e19243c8fa1d;p=gwion.git :art: Move find_template_match and helping fns to new file --- diff --git a/include/tmp_resolve.h b/include/tmp_resolve.h new file mode 100644 index 00000000..6577be04 --- /dev/null +++ b/include/tmp_resolve.h @@ -0,0 +1,5 @@ +#ifndef __TMPL_RESOLVE +#define __TMPL_RESOLVE +ANN Func find_template_match(const Env env, const Value value, const Exp_Call* exp); +ANN2(1, 2) Func find_func_match(const Env env, const Func up, const Exp exp); +#endif diff --git a/src/parse/check.c b/src/parse/check.c index 08972de9..652821df 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -13,6 +13,7 @@ #include "match.h" #include "emit.h" #include "specialid.h" +#include "tmp_resolve.h" ANN static m_bool check_stmt_list(const Env env, Stmt_List list); ANN m_bool check_class_def(const Env env, const Class_Def class_def); @@ -469,7 +470,7 @@ ANN2(1,2) static Func find_func_match_actual(const Env env, Func func, const Exp return NULL; } -ANN2(1, 2) static Func find_func_match(const Env env, const Func up, const Exp exp) { +ANN2(1, 2) Func find_func_match(const Env env, const Func up, const Exp exp) { Func func; const Exp args = (exp && isa(exp->info->type, env->gwion->type[et_void]) < 0) ? exp : NULL; if((func = find_func_match_actual(env, up, args, 0, 1)) || @@ -480,22 +481,6 @@ ANN2(1, 2) static Func find_func_match(const Env env, const Func up, const Exp e return NULL; } -ANN static m_bool check_call(const Env env, const Exp_Call* exp) { - ae_exp_t et = exp->func->exp_type; - if(et != ae_exp_primary && et != ae_exp_dot && et != ae_exp_cast) - ERR_B(exp->func->pos, _("invalid expression for function call.")) - CHECK_OB(check_exp(env, exp->func)) - if(exp->args) - CHECK_OB(check_exp(env, exp->args)) - return GW_OK; -} - -ANN static inline Value template_get_ready(const Env env, const Value v, const m_str tmpl, const m_uint i) { - const Symbol sym = func_symbol(env, v->from->owner->name, v->name, tmpl, i); - return v->from->owner_class ? find_value(v->from->owner_class, sym) : - nspc_lookup_value1(v->from->owner, sym); -} - ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) { struct Vector_ v = {}; const m_uint scope = env->scope->depth; @@ -511,22 +496,6 @@ ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) { return ret; } -ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *exp) { - const m_bool ret = GET_FLAG(fdef->base, valid) || check_traverse_fdef(env, fdef) > 0; - if(ret) { - const Func f = fdef->base->func; - const Func next = f->next; - f->next = NULL; - const Func func = find_func_match(env, f, exp->args); - f->next = next; - if(func) { - SET_FLAG(func, valid | ae_flag_template); - return func; - } - } - return NULL; -} - ANN static m_bool check_func_args(const Env env, Arg_List arg_list) { do { const Var_Decl decl = arg_list->var_decl; @@ -543,99 +512,6 @@ ANN static m_bool check_func_args(const Env env, Arg_List arg_list) { return GW_OK; } -ANN static Func _find_template_match(const Env env, const Value v, const Exp_Call* exp) { - CHECK_BO(check_call(env, exp)) - const Type_List types = exp->tmpl->call; - Func m_func = NULL, former = env->func; - DECL_OO(const m_str, tmpl_name, = tl2str(env, types)) - const m_uint scope = env->scope->depth; - struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef, - .scope=scope, .flag=ae_flag_check }; - CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner)) - (void)env_push(env, v->from->owner_class, v->from->owner); - if(is_fptr(env->gwion, v->type)) { - const Symbol sym = func_symbol(env, v->from->owner->name, v->name, tmpl_name, 0); - const Type exists = nspc_lookup_type0(v->from->owner, sym); - if(exists) - m_func = exists->e->d.func; - else { - Func_Def base = v->d.func_ref ? v->d.func_ref->def : exp->func->info->type->e->d.func->def; - Func_Base *fbase = cpy_func_base(env->gwion->mp, base->base); - fbase->xid = sym; - fbase->tmpl->base = 0; - fbase->tmpl->call = cpy_type_list(env->gwion->mp, types); - if(template_push_types(env, fbase->tmpl) > 0) { - const Fptr_Def fptr = new_fptr_def(env->gwion->mp, fbase); - if(traverse_fptr_def(env, fptr) > 0 && - (base->base->ret_type = known_type(env, base->base->td)) && - (!exp->args || !!check_exp(env, exp->args))) { - m_func = find_func_match(env, fbase->func, exp->args); - nspc_pop_type(env->gwion->mp, env->curr); - if(m_func) - nspc_add_type_front(v->from->owner, sym, actual_type(env->gwion, m_func->value_ref->type)); - } - free_fptr_def(env->gwion->mp, fptr); - if(fptr->type) - REM_REF(fptr->type, env->gwion) - } - } - } else { - for(m_uint i = 0; i < v->from->offset + 1; ++i) { - const Value exists = template_get_ready(env, v, tmpl_name, i); - if(exists) { - if(env->func == exists->d.func_ref) { - if(check_call(env, exp) < 0 || - !find_func_match(env, env->func, exp->args)) - continue; - m_func = env->func; - break; - } - if((m_func = ensure_tmpl(env, exists->d.func_ref->def, exp))) - break; - } else { - const Value value = template_get_ready(env, v, "template", i); - if(!value) - continue; - if(GET_FLAG(v, builtin)) { - SET_FLAG(value, builtin); - SET_FLAG(value->d.func_ref, builtin); - } - const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def); - SET_FLAG(fdef->base, template); - fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, types); - fdef->base->tmpl->base = i; - if((m_func = ensure_tmpl(env, fdef, exp))) - break; - } - } - } - free_mstr(env->gwion->mp, tmpl_name); - if(es.run) - envset_pop(&es, v->from->owner_class); - env_pop(env, scope); - env->func = former; - return m_func; -} - -ANN Func find_template_match(const Env env, const Value value, const Exp_Call* exp) { - const Func f = _find_template_match(env, value, exp); - if(f) - return f; - Type t = value->from->owner_class; - while(t && t->nspc) { - Func_Def fdef = value->d.func_ref ? value->d.func_ref->def : value->type->e->d.func->def; - const Value v = nspc_lookup_value0(t->nspc, fdef->base->xid); - if(!v) - goto next; - const Func f = _find_template_match(env, v, exp); - if(f) - return f; - next: - t = t->e->parent; - } - ERR_O(exp_self(exp)->pos, _("arguments do not match for template call")) -} - #define next_arg(type) \ ANN static inline type next_arg_##type(const type e) { \ const type next = e->next; \ diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c new file mode 100644 index 00000000..1dc23451 --- /dev/null +++ b/src/parse/func_resolve_tmpl.c @@ -0,0 +1,141 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "gwion_env.h" +#include "vm.h" +#include "instr.h" +#include "object.h" +#include "traverse.h" +#include "template.h" +#include "gwion.h" +#include "operator.h" +#include "import.h" +#include "parse.h" +#include "match.h" +#include "emit.h" +#include "specialid.h" +#include "tmp_resolve.h" + +ANN static inline Value template_get_ready(const Env env, const Value v, const m_str tmpl, const m_uint i) { + const Symbol sym = func_symbol(env, v->from->owner->name, v->name, tmpl, i); + return v->from->owner_class ? find_value(v->from->owner_class, sym) : + nspc_lookup_value1(v->from->owner, sym); +} + +ANN static m_bool check_call(const Env env, const Exp_Call* exp) { + ae_exp_t et = exp->func->exp_type; + if(et != ae_exp_primary && et != ae_exp_dot && et != ae_exp_cast) + ERR_B(exp->func->pos, _("invalid expression for function call.")) + CHECK_OB(check_exp(env, exp->func)) + if(exp->args) + CHECK_OB(check_exp(env, exp->args)) + return GW_OK; +} + +ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *exp) { + const m_bool ret = GET_FLAG(fdef->base, valid) || check_traverse_fdef(env, fdef) > 0; + if(ret) { + const Func f = fdef->base->func; + const Func next = f->next; + f->next = NULL; + const Func func = find_func_match(env, f, exp->args); + f->next = next; + if(func) { + SET_FLAG(func, valid | ae_flag_template); + return func; + } + } + return NULL; +} + +ANN static Func _find_template_match(const Env env, const Value v, const Exp_Call* exp) { + CHECK_BO(check_call(env, exp)) + const Type_List types = exp->tmpl->call; + Func m_func = NULL, former = env->func; + DECL_OO(const m_str, tmpl_name, = tl2str(env, types)) + const m_uint scope = env->scope->depth; + struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef, + .scope=scope, .flag=ae_flag_check }; + CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner)) + (void)env_push(env, v->from->owner_class, v->from->owner); + if(is_fptr(env->gwion, v->type)) { + const Symbol sym = func_symbol(env, v->from->owner->name, v->name, tmpl_name, 0); + const Type exists = nspc_lookup_type0(v->from->owner, sym); + if(exists) + m_func = exists->e->d.func; + else { + Func_Def base = v->d.func_ref ? v->d.func_ref->def : exp->func->info->type->e->d.func->def; + Func_Base *fbase = cpy_func_base(env->gwion->mp, base->base); + fbase->xid = sym; + fbase->tmpl->base = 0; + fbase->tmpl->call = cpy_type_list(env->gwion->mp, types); + if(template_push_types(env, fbase->tmpl) > 0) { + const Fptr_Def fptr = new_fptr_def(env->gwion->mp, fbase); + if(traverse_fptr_def(env, fptr) > 0 && + (base->base->ret_type = known_type(env, base->base->td)) && + (!exp->args || !!check_exp(env, exp->args))) { + m_func = find_func_match(env, fbase->func, exp->args); + nspc_pop_type(env->gwion->mp, env->curr); + if(m_func) + nspc_add_type_front(v->from->owner, sym, actual_type(env->gwion, m_func->value_ref->type)); + } + free_fptr_def(env->gwion->mp, fptr); + if(fptr->type) + REM_REF(fptr->type, env->gwion) + } + } + } else { + for(m_uint i = 0; i < v->from->offset + 1; ++i) { + const Value exists = template_get_ready(env, v, tmpl_name, i); + if(exists) { + if(env->func == exists->d.func_ref) { + if(check_call(env, exp) < 0 || + !find_func_match(env, env->func, exp->args)) + continue; + m_func = env->func; + break; + } + if((m_func = ensure_tmpl(env, exists->d.func_ref->def, exp))) + break; + } else { + const Value value = template_get_ready(env, v, "template", i); + if(!value) + continue; + if(GET_FLAG(v, builtin)) { + SET_FLAG(value, builtin); + SET_FLAG(value->d.func_ref, builtin); + } + const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def); + SET_FLAG(fdef->base, template); + fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, types); + fdef->base->tmpl->base = i; + if((m_func = ensure_tmpl(env, fdef, exp))) + break; + } + } + } + free_mstr(env->gwion->mp, tmpl_name); + if(es.run) + envset_pop(&es, v->from->owner_class); + env_pop(env, scope); + env->func = former; + return m_func; +} + +ANN Func find_template_match(const Env env, const Value value, const Exp_Call* exp) { + const Func f = _find_template_match(env, value, exp); + if(f) + return f; + Type t = value->from->owner_class; + while(t && t->nspc) { + Func_Def fdef = value->d.func_ref ? value->d.func_ref->def : value->type->e->d.func->def; + const Value v = nspc_lookup_value0(t->nspc, fdef->base->xid); + if(!v) + goto next; + const Func f = _find_template_match(env, v, exp); + if(f) + return f; + next: + t = t->e->parent; + } + ERR_O(exp_self(exp)->pos, _("arguments do not match for template call")) +}