]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve lambda and errored functions
authorfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 11 Oct 2019 12:35:27 +0000 (14:35 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 11 Oct 2019 12:35:27 +0000 (14:35 +0200)
examples/complex/invalid_func0.gw [new file with mode: 0644]
examples/complex/invalid_func1.gw [new file with mode: 0644]
examples/implicit_fptr_class.gw
src/emit/emit.c
src/lib/func.c
src/oo/context.c
src/parse/check.c
src/parse/scan2.c

diff --git a/examples/complex/invalid_func0.gw b/examples/complex/invalid_func0.gw
new file mode 100644 (file)
index 0000000..bf67fa0
--- /dev/null
@@ -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 (file)
index 0000000..902b476
--- /dev/null
@@ -0,0 +1,3 @@
+#! [contains] is errored
+#!global_func_err();
+global_func_err<~int~>();
index 8c1f0fcc2ad50f2237aff42ff559b480b2c3ad29..95a532e7716574bf1ac659ebf6e22ebda1f964b2 100644 (file)
@@ -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;
index efd233244af801f2cfa7fb92befcef5b40098c14..fe45857a89ae3e9f74830620cb0f910865c4c1ff 100644 (file)
@@ -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;
index 430defb81e756809e34bd2b9ca35ea7e6a6d8b21..4c36b831ac60f190155068c75de832deb734d067 100644 (file)
@@ -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) {
index 27164bd8ee374337c774aa66e72cadaf09b6d041..555dc4fd5811850ff8e1bcdafe8d073432c41cbe 100644 (file)
@@ -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);
 }
index 1956864a1e69c1008f24250e7f2c20fcc60782c3..592bd0bf8cf494d9d019d37de88aaf4c202f320d 100644 (file)
@@ -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;
   }
index fa19de238d29b5438215f51a2517bcef7fb1d390..f9c1e2d82856a875e5964120cd1e010a6860e39e 100644 (file)
@@ -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))