diff options
-rw-r--r-- | lib.c | 18 | ||||
-rw-r--r-- | tests/012/lambda.tl | 27 |
2 files changed, 38 insertions, 7 deletions
@@ -8525,7 +8525,9 @@ val funcall1(val fun, val arg) case 4: return vm_funcall4(fun, z(arg), colon_k, colon_k, colon_k); default: - { + if (!fun->f.variadic && fun->f.fixparam == 0) { + wrongargs(fun); + } else { args_decl_constsize(args, ARGS_MIN); args_add(args, arg); return vm_execute_closure(fun, args); @@ -8604,7 +8606,9 @@ val funcall2(val fun, val arg1, val arg2) case 4: return vm_funcall4(fun, z(arg1), z(arg2), colon_k, colon_k); default: - { + if (!fun->f.variadic && fun->f.fixparam < 2) { + wrongargs(fun); + } else { args_decl_constsize(args, ARGS_MIN); args_add2(args, arg1, arg2); return vm_execute_closure(fun, args); @@ -8685,7 +8689,9 @@ val funcall3(val fun, val arg1, val arg2, val arg3) case 4: return vm_funcall4(fun, z(arg1), z(arg2), z(arg3), colon_k); default: - { + if (!fun->f.variadic && fun->f.fixparam < 3) { + wrongargs(fun); + } else { args_decl_constsize(args, ARGS_MIN); args_add3(args, arg1, arg2, arg3); return vm_execute_closure(fun, args); @@ -8761,12 +8767,14 @@ val funcall4(val fun, val arg1, val arg2, val arg3, val arg4) wrongargs(fun); if (fun->f.functype == FVM) { - if (fun->f.fixparam == 4) + if (fun->f.fixparam == 4) { return vm_funcall4(fun, z(arg1), z(arg2), z(arg3), z(arg4)); - else { + } else if (fun->f.variadic || fun->f.fixparam > 4) { args_decl(args, ARGS_MIN); args_add4(args, arg1, arg2, arg3, arg4); return vm_execute_closure(fun, args); + } else { + wrongargs(fun); } } diff --git a/tests/012/lambda.tl b/tests/012/lambda.tl index ec3b2cae..811dbcfc 100644 --- a/tests/012/lambda.tl +++ b/tests/012/lambda.tl @@ -3,12 +3,28 @@ (defun call-lambda (fn . args) [fn . args]) +(defun call-lambda-fixed (fn . args) + (tree-case args + (() [fn]) + ((a1) [fn a1]) + ((a1 a2) [fn a1 a2]) + ((a1 a2 a3) [fn a1 a2 a3]) + ((a1 a2 a3 a4) [fn a1 a2 a3 a4]) + ((a1 a2 a3 a4 a5) [fn a1 a2 a3 a4 a5]) + ((a1 . r) [fn a1 . r]) + ((a1 a2 . r) [fn a1 a2 . r]) + ((a1 a2 a3 . r) [fn a1 a2 a3 . r]) + ((a1 a2 a3 a4 . r) [fn a1 a2 a3 a4 . r]) + ((a1 a2 a3 a4 a5 . r) [fn a1 a2 a3 a4 a5 . r]) + (r [fn . r]))) + (defmacro ltest (:match :form f) (([(lambda . @rest) . @args] @expected) (if *compile-test* ^(progn (test [(lambda ,*rest) ,*args] ,expected) - (test (call-lambda (lambda ,*rest) ,*args) ,expected)) + (test (call-lambda (lambda ,*rest) ,*args) ,expected) + (test (call-lambda-fixed (lambda ,*rest) ,*args) ,expected)) ^(test [(lambda ,*rest) ,*args] ,expected))) ((@else . rest) (compile-error f "bad syntax"))) @@ -17,17 +33,22 @@ (mltest [(lambda ())] nil + [(lambda ()) 1] :error [(lambda (a) a)] :error [(lambda (a) a) 1] 1 + [(lambda (a) a) 1 2] :error [(lambda (a b) (list a b)) 1] :error [(lambda (a b) (list a b)) 1 2] (1 2) + [(lambda (a b) (list a b)) 1 2 3] :error [(lambda (a b c) (list a b c)) 1 2] :error - [(lambda (a b c) (list a b c)) 1 2 3] (1 2 3)) + [(lambda (a b c) (list a b c)) 1 2 3] (1 2 3) + [(lambda (a b c) (list a b c)) 1 2 3 4] :error) (mltest [(lambda (: a) a)] nil [(lambda (: (a 1)) a)] 1 [(lambda (: (a 1)) a) 2] 2 + [(lambda (: (a 1)) a) 2 3] :error [(lambda (: (a 1 a-p)) (list a a-p))] (1 nil) [(lambda (: (a 1 a-p)) (list a a-p)) 2] (2 t)) @@ -35,6 +56,8 @@ [(lambda (x : a) (list x a))] :error [(lambda (x : (a 1)) (list x a))] :error [(lambda (x : (a 1)) (list x a)) 2] (2 1) + [(lambda (x : (a 1)) (list x a)) 2 3] (2 3) + [(lambda (x : (a 1)) (list x a)) 2 3 4] :error [(lambda (x : (a 1 a-p)) (list x a a-p))] :error [(lambda (x : (a 1 a-p)) (list x a a-p)) 2] (2 1 nil)) |