Only evaluate the test once in COND
authorStrigoides <Strigoides@gmail.com>
Fri, 26 Apr 2013 15:43:33 +0000 (03:43 +1200)
committerStrigoides <Strigoides@gmail.com>
Fri, 26 Apr 2013 15:43:33 +0000 (03:43 +1200)
src/boot.lisp
tests/conditionals.lisp

index d30fb79..de32e75 100644 (file)
 
 (defmacro cond (&rest clausules)
   (if (null clausules)
-      nil
-      (if (eq (caar clausules) t)
-        `(progn ,@(cdar clausules))
-        `(if ,(caar clausules)
-           ,(if (null (cdar clausules))
-              (caar clausules)
-              `(progn ,@(cdar clausules)))
-           (cond ,@(cdr clausules))))))
+    nil
+    (if (eq (caar clausules) t)
+      `(progn ,@(cdar clausules))
+      (let ((test-symbol (gensym)))
+        `(let ((,test-symbol ,(caar clausules)))
+           (if ,test-symbol
+             ,(if (null (cdar clausules))
+                test-symbol
+                `(progn ,@(cdar clausules)))
+             (cond ,@(cdr clausules))))))))
 
 (defmacro case (form &rest clausules)
   (let ((!form (gensym)))
index 693fbba..19736e1 100644 (file)
@@ -9,6 +9,9 @@
 ; COND
 (test (eql nil (cond)))
 (test (=   1   (cond (1))))
+(test (= 1
+         (let ((x 0))
+           (cond ((incf x))))))
 (test (=   2   (cond (1 2))))
 (test (=   3   (cond (nil 1) (2 3))))
 (test (eql nil (cond (nil 1) (nil 2))))