Documentation
Evaluates the args one at a time. If more than one arg returns true
evaluation stops and NIL is returned. If exactly one arg returns
true that value is retuned.
Source
(defmacro xor (&rest datums)
"Evaluates the args one at a time. If more than one arg returns true
evaluation stops and NIL is returned. If exactly one arg returns
true that value is retuned."
(let ((state (gensym "XOR-state-"))
(block-name (gensym "XOR-block-"))
(arg-temp (gensym "XOR-arg-temp-")))
`(let ((,state nil)
(,arg-temp nil))
(block ,block-name
,@(loop
for arg in datums
collect `(setf ,arg-temp ,arg)
collect `(if ,arg-temp
;; arg is T, this can change the state
(if ,state
;; a second T value, return NIL
(return-from ,block-name nil)
;; a first T, swap the state
(setf ,state ,arg-temp))))
(return-from ,block-name ,state)))))
Source Context