# HG changeset patch # User Steve Losh # Date 1531079254 0 # Node ID 40e426c5982b79518003bc816a8478b6a3835c00 # Parent 57bdaf80a4488e5e478b4c6ff7d57679eadf5753 Clean up if-let diff -r 57bdaf80a448 -r 40e426c5982b Makefile --- a/Makefile Sat Jul 07 21:04:56 2018 +0000 +++ b/Makefile Sun Jul 08 19:47:34 2018 +0000 @@ -28,7 +28,8 @@ test-ecl: $(heading_printer) roman 'ECL' - ecl --load test/run.lisp + # oh for fucks sake, use -- for longopts come on + ecl -load test/run.lisp test-abcl: $(heading_printer) broadway 'ABCL' diff -r 57bdaf80a448 -r 40e426c5982b src/control-flow.lisp --- a/src/control-flow.lisp Sat Jul 07 21:04:56 2018 +0000 +++ b/src/control-flow.lisp Sun Jul 08 19:47:34 2018 +0000 @@ -303,7 +303,7 @@ This macro combines `if` and `let`. It takes a list of bindings and binds them like `let` before executing the `then` branch of `body`, but if any - binding's value evaluate to `nil` the process stops there and the `else` + binding's value evaluates to `nil` the process stops there and the `else` branch is immediately executed (with no bindings in effect). If any `optional-declarations` are included they will only be in effect for @@ -333,31 +333,16 @@ NOPE " - ;; (if-let ((a 1) - ;; (b 2)) - ;; (declare (type fixnum a b)) - ;; (+ a b) - ;; 'nope) - ;; => - ;; (BLOCK #:OUTER632 - ;; (BLOCK #:INNER633 - ;; (LET ((A (OR 1 (RETURN-FROM #:INNER633))) - ;; (B (OR 2 (RETURN-FROM #:INNER633)))) - ;; (DECLARE (TYPE FIXNUM A B)) - ;; (RETURN-FROM #:OUTER632 (+ A B)))) - ;; 'NOPE) (with-gensyms (outer inner) - (loop - :with (body declarations) = (multiple-value-list (parse-body body)) - :with (then else) = (destructuring-bind (then else) body (list then else)) - :for (symbol value) :in bindings - :collect `(,symbol (or ,value (return-from ,inner))) :into let-bindings - :finally (return `(block ,outer - (block ,inner - (let ,let-bindings - ,@declarations - (return-from ,outer ,then))) - ,else))))) + (multiple-value-bind (body declarations) (parse-body body) + (destructuring-bind (then else) body + `(block ,outer + (block ,inner + (let ,(loop :for (symbol value) :in bindings + :collect `(,symbol (or ,value (return-from ,inner)))) + ,@declarations + (return-from ,outer ,then))) + ,else))))) (defmacro if-let* (bindings &body body) "Bind `bindings` sequentially and execute `then` if all are true, or `else` otherwise. @@ -396,31 +381,16 @@ NOPE " - ;; (if-let* ((a 1) - ;; (b 2)) - ;; (declare (type fixnum a b)) - ;; (+ a b) - ;; 'nope) - ;; => - ;; (BLOCK #:OUTER640 - ;; (BLOCK #:INNER641 - ;; (LET* ((A (OR 1 (RETURN-FROM #:INNER641))) - ;; (B (OR 2 (RETURN-FROM #:INNER641)))) - ;; (DECLARE (TYPE FIXNUM A B)) - ;; (RETURN-FROM #:OUTER640 (+ A B)))) - ;; 'NOPE) (with-gensyms (outer inner) - (loop - :with (body declarations) = (multiple-value-list (parse-body body)) - :with (then else) = (destructuring-bind (then else) body (list then else)) - :for (symbol value) :in bindings - :collect `(,symbol (or ,value (return-from ,inner))) :into let-bindings - :finally (return `(block ,outer - (block ,inner - (let* ,let-bindings - ,@declarations - (return-from ,outer ,then))) - ,else))))) + (multiple-value-bind (body declarations) (parse-body body) + (destructuring-bind (then else) body + `(block ,outer + (block ,inner + (let* ,(loop :for (symbol value) :in bindings + :collect `(,symbol (or ,value (return-from ,inner)))) + ,@declarations + (return-from ,outer ,then))) + ,else))))) (defmacro multiple-value-bind* (bindings &body body)