diff --git a/libc3/env.c b/libc3/env.c
index e0afa1c..8cb4038 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -147,6 +147,7 @@ bool env_eval_call_fn (s_env *env, const s_call *call, s_tag *dest)
s_list *args = NULL;
s_frame frame;
s_fn *fn;
+ s_fn *fn2;
s_tag tag;
s_list *tmp = NULL;
assert(env);
@@ -156,23 +157,30 @@ bool env_eval_call_fn (s_env *env, const s_call *call, s_tag *dest)
assert(fn);
frame_init(&frame, env->frame);
env->frame = &frame;
+ fn2 = fn;
if (call->arguments) {
if (! env_eval_call_arguments(env, call->arguments, &args)) {
env->frame = frame_clean(&frame);
return false;
}
- if (! env_eval_equal_list(env, fn->pattern, args, &tmp)) {
+ while (fn2 && ! env_eval_equal_list(env, fn2->pattern, args, &tmp))
+ fn2 = fn2->next_clause;
+ if (! fn2) {
err_puts("env_eval_call_fn: no clause matching.\nTried clauses :\n");
- err_inspect_list(fn->pattern);
+ fn2 = fn;
+ while (fn2) {
+ err_inspect_fn_pattern(fn2->pattern);
+ fn2 = fn2->next_clause;
+ }
err_puts("\nArguments :\n");
- err_inspect_list(args);
+ err_inspect_fn_pattern(args);
err_puts("\n");
list_delete_all(args);
env->frame = frame_clean(&frame);
return false;
}
}
- if (! env_eval_progn(env, fn->algo, &tag)) {
+ if (! env_eval_progn(env, fn2->algo, &tag)) {
list_delete_all(args);
list_delete_all(tmp);
env->frame = frame_clean(&frame);
@@ -300,9 +308,9 @@ bool env_eval_call_special_operator (s_env *env, const s_call *call,
env->frame = &frame;
if (! env_eval_equal_list(env, fn->pattern, call->arguments, &tmp)) {
err_puts("env_eval_call_fn: no clause matching.\nTried clauses :\n");
- err_inspect_list(fn->pattern);
+ err_inspect_fn_pattern(fn->pattern);
err_puts("\nArguments :\n");
- err_inspect_list(call->arguments);
+ err_inspect_fn_pattern(call->arguments);
err_puts("\n");
env->frame = frame_clean(&frame);
return false;
diff --git a/libc3/io.c b/libc3/io.c
index c9225b6..7ee1db0 100644
--- a/libc3/io.c
+++ b/libc3/io.c
@@ -23,6 +23,14 @@ sw err_inspect (const s_tag *tag)
return r;
}
+sw err_inspect_fn_pattern (const s_list *list)
+{
+ sw r;
+ r = buf_inspect_fn_pattern(&g_c3_env.err, list);
+ buf_flush(&g_c3_env.err);
+ return r;
+}
+
sw err_inspect_list (const s_list *list)
{
sw r;
diff --git a/libc3/io.h b/libc3/io.h
index 99624cd..7c52705 100644
--- a/libc3/io.h
+++ b/libc3/io.h
@@ -17,6 +17,7 @@
/* error output */
sw err_inspect (const s_tag *tag);
+sw err_inspect_fn_pattern (const s_list *list);
sw err_inspect_list (const s_list *list);
sw err_puts (const s8 *s);
diff --git a/test/ic3/fn.in b/test/ic3/fn.in
index 5d4daf3..a16d710 100644
--- a/test/ic3/fn.in
+++ b/test/ic3/fn.in
@@ -6,11 +6,15 @@ quote fn {
((x | _y)) { x }
(_) { :error }
}
-fn (x) { x }
-fn (x, _y) { x }
-fn ((x | _y)) { x }
-fn {
+a = fn (x) { x }
+a(1)
+b = fn (x, _y) { x }
+b(1, 2)
+c = fn ((x | _y)) { x }
+c((1, 2))
+d = fn {
(()) { :error }
((x | _y)) { x }
- (_) { :error }
+ (_) { :error2 }
}
+d((1, 2))
diff --git a/test/ic3/fn.out.expected b/test/ic3/fn.out.expected
index 5d4daf3..9ef8205 100644
--- a/test/ic3/fn.out.expected
+++ b/test/ic3/fn.out.expected
@@ -7,10 +7,14 @@ quote fn {
(_) { :error }
}
fn (x) { x }
+1
fn (x, _y) { x }
+1
fn ((x | _y)) { x }
+1
fn {
(()) { :error }
((x | _y)) { x }
- (_) { :error }
+ (_) { :error2 }
}
+1