From: Strigoides Date: Fri, 26 Apr 2013 15:43:33 +0000 (+1200) Subject: Only evaluate the test once in COND X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=ec5a0cce4f4b450e991db0d47f0e7998dbeda662;p=jscl.git Only evaluate the test once in COND --- diff --git a/src/boot.lisp b/src/boot.lisp index d30fb79..de32e75 100644 --- a/src/boot.lisp +++ b/src/boot.lisp @@ -213,14 +213,16 @@ (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))) diff --git a/tests/conditionals.lisp b/tests/conditionals.lisp index 693fbba..19736e1 100644 --- a/tests/conditionals.lisp +++ b/tests/conditionals.lisp @@ -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))))