From 2832458f85d24b07f27574c48e8f132c92a943db Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 11 Oct 2019 14:35:27 +0200 Subject: [PATCH] :art: Improve lambda and errored functions --- examples/complex/invalid_func0.gw | 2 ++ examples/complex/invalid_func1.gw | 3 +++ examples/implicit_fptr_class.gw | 18 +++++++++++------- src/emit/emit.c | 2 +- src/lib/func.c | 5 ++++- src/oo/context.c | 2 +- src/parse/check.c | 8 +++++--- src/parse/scan2.c | 5 ++++- 8 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 examples/complex/invalid_func0.gw create mode 100644 examples/complex/invalid_func1.gw diff --git a/examples/complex/invalid_func0.gw b/examples/complex/invalid_func0.gw new file mode 100644 index 00000000..bf67fa08 --- /dev/null +++ b/examples/complex/invalid_func0.gw @@ -0,0 +1,2 @@ +#!fun global void global_func_err() { <<< _func__ >>>; } +fun global void global_func_err<~A~>() { <<< _func__ >>>; } diff --git a/examples/complex/invalid_func1.gw b/examples/complex/invalid_func1.gw new file mode 100644 index 00000000..902b4761 --- /dev/null +++ b/examples/complex/invalid_func1.gw @@ -0,0 +1,3 @@ +#! [contains] is errored +#!global_func_err(); +global_func_err<~int~>(); diff --git a/examples/implicit_fptr_class.gw b/examples/implicit_fptr_class.gw index 8c1f0fcc..95a532e7 100644 --- a/examples/implicit_fptr_class.gw +++ b/examples/implicit_fptr_class.gw @@ -1,11 +1,15 @@ class C { -typedef void t_ptr(); -fun void test(t_ptr p) { - <<< p >>>; -} -fun void test() { -} + typedef void t_ptr(); + typedef void t_ptr1(int); + fun void test(t_ptr p) { + <<< p >>>; + } + fun void test() {} -test => test; + test => test; + test $ t_ptr; + \{ <<< __func__ >>>; } $ t_ptr;#!; => test; + \{ <<< __func__ >>>; } => test; + \a{} @=> t_ptr1 ptr1; } C c; diff --git a/src/emit/emit.c b/src/emit/emit.c index efd23324..fe45857a 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1124,7 +1124,7 @@ ANN static m_bool emit_exp_if(const Emitter emit, const Exp_If* exp_if) { ANN static m_bool emit_lambda(const Emitter emit, const Exp_Lambda * lambda) { CHECK_BB(emit_func_def(emit, lambda->def)) - if(GET_FLAG(lambda->def, member)) + if(GET_FLAG(lambda->def, member) && !exp_self(lambda)->emit_var) emit_add_instr(emit, RegPushMem); regpushi(emit, (m_uint)lambda->def->base->func->code); return GW_OK; diff --git a/src/lib/func.c b/src/lib/func.c index 430defb8..4c36b831 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -175,7 +175,10 @@ ANN2(1,3,4) m_bool check_lambda(const Env env, const Type owner, const m_bool ret = _check_lambda(env, l, def); if(owner) env_pop(env, scope); - return ret; + if(ret < 0) + return GW_ERROR; + exp_self(l)->type = l->def->base->func->value_ref->type; + return GW_OK; } ANN static m_bool fptr_lambda(const Env env, struct FptrInfo *info) { diff --git a/src/oo/context.c b/src/oo/context.c index 27164bd8..555dc4fd 100644 --- a/src/oo/context.c +++ b/src/oo/context.c @@ -38,6 +38,6 @@ ANN void unload_context(const Context context, const Env env) { free_map(env->gwion->mp, (Map)map_at(&context->lbls, i)); map_release(&context->lbls); } - REM_REF(context, env->gwion); + REM_REF(context, env->gwion) env->curr = (Nspc)vector_pop(&env->scope->nspc_stack); } diff --git a/src/parse/check.c b/src/parse/check.c index 1956864a..592bd0bf 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -447,7 +447,9 @@ ANN static m_bool func_match_inner(const Env env, const Exp e, const Type t, if(e->type == env->gwion->type[et_lambda] && is_fptr(env->gwion, t)) { const Type owner = nspc_lookup_type1(t->e->owner->parent, insert_symbol(t->e->owner->name)); - return check_lambda(env, owner, &e->d.exp_lambda, t->e->d.func->def); + const m_bool ret = check_lambda(env, owner, &e->d.exp_lambda, t->e->d.func->def); + e->emit_var = 1; + return ret; } if(implicit) return check_implicit(env, e, t); @@ -523,8 +525,6 @@ static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *exp) const Func func = find_func_match(env, f, exp->args); f->next = next; if(func) { - if(func->value_ref->from->ctx->error) - ERR_O(exp_self(exp)->pos, _("function '%s' is errored"), func->name) SET_FLAG(func, checked | ae_flag_template); return func; } @@ -794,6 +794,8 @@ ANN Type check_exp_call1(const Env env, const Exp_Call *exp) { return check_exp_call_template(env, (Exp_Call*)exp); const Func func = find_func_match(env, exp->func->type->e->d.func, exp->args); if((exp_self(exp)->d.exp_call.m_func = func)) { + if(func->value_ref->from->ctx && func->value_ref->from->ctx->error) + ERR_O(exp_self(exp)->pos, _("function '%s' is errored"), func->name) exp->func->type = func->value_ref->type; return func->def->base->ret_type; } diff --git a/src/parse/scan2.c b/src/parse/scan2.c index fa19de23..f9c1e2d8 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -16,6 +16,7 @@ #include "instr.h" #include "import.h" #include "tuple.h" +#include "context.h" ANN static m_bool scan2_stmt(const Env, const Stmt); ANN static m_bool scan2_stmt_list(const Env, Stmt_List); @@ -327,11 +328,11 @@ ANN static Type func_type(const Env env, const Func func) { t->e->tuple = NULL; return t; } - ANN2(1,2) static Value func_value(const Env env, const Func f, const Value overload) { const Type t = func_type(env, f); const Value v = new_value(env->gwion->mp, t, t->name); + valuefrom(env, v->from); CHECK_OO(scan2_func_assign(env, f->def, f, v)) if(!overload) { ADD_REF(v); @@ -505,6 +506,8 @@ ANN m_bool scan2_fdef(const Env env, const Func_Def f) { } ANN m_bool scan2_func_def(const Env env, const Func_Def f) { + if(GET_FLAG(f, global)) + env->context->global = 1; const m_uint scope = !GET_FLAG(f, global) ? env->scope->depth : env_push_global(env); f->stack_depth = (env->class_def && !GET_FLAG(f, static) && !GET_FLAG(f, global)) ? SZ_INT : 0; if(GET_FLAG(f, variadic)) -- 2.43.0