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;
}
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;
}
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;
}
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))
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);
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))
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))
}
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) {
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);
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
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;
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)))
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)
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))
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) {
+++ /dev/null
-#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);
-}