shithub: femtolisp

Download patch

ref: c186019e2661ec8b8c301e5d7dc1bcd99f71f48c
parent: 81fdc5ef972becd6c0f3b76f079c43f1fce8dc48
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Dec 11 00:26:29 EST 2024

apply: make sure last arg is a list

(apply + 1 2 3) should actually fail, not result in 3 silently.

--- a/flisp.c
+++ b/flisp.c
@@ -580,6 +580,8 @@
 		PUSH(car_(v));
 		v = cdr_(v);
 	}
+	if(v != FL(Nil))
+		lerrorf(FL(ArgError), "apply: last argument: not a list");
 	n = FL(sp) - n - 1;
 	v = _applyn(n);
 	POPN(n+1);
@@ -1523,6 +1525,10 @@
 					grow_stack();
 				PUSH(car_(v));
 				v = cdr_(v);
+			}
+			if(v != FL(Nil)){
+				FL(stack)[ipd] = (uintptr_t)ip;
+				lerrorf(FL(ArgError), "apply: last argument: not a list");
 			}
 			n = FL(sp)-n;
 			goto do_call;
--- a/test/unittest.lsp
+++ b/test/unittest.lsp
@@ -433,6 +433,10 @@
 (assert-fail (aset! a 1 1 3 "nope"))
 (assert (equal? a #(#(8 1 2) #(3 #(4 5 9) "hello"))))
 
+;; apply with multiple args
+(assert (equal? 15 (apply + 1 2 '(3 4 5))))
+(assert-fail (apply + 1 2 3)) ; last arg not a list
+
 ;; make many initialized tables large enough not to be stored in-line
 (for 1 100 (λ (i)
   (table eq?      2      eqv?     2