I've recently started to learn lisp, and to exercise what I've learnt I've started writing a simple connect 4 game. I want to write a macro to check if a number of positions are on the board. Using inspiration from the sbcl source code for the AND macro as a example of writing macros which work on an unlimited number of parameters using &rest, I first wrote this:
Code: Select all
(defmacro on-board-p (&rest positions)
(cond ((endp positions) t)
((endp (rest positions))
`(and (>= ,(first positions) 0)
(< ,(first positions) +board-size)))
(t
`(and (>= ,(first positions) 0)
(< ,(first positions) +board-size)
(on-board-p ,@(rest positions))))))
Code: Select all
(defmacro on-board-p (&rest positions)
`(labels ((test (p)
(and (>= p 0)
(< p +board-size))))
,(cond ((endp positions) t)
((endp (rest positions)) `(test ,(first positions)))
(t
`(and (test ,(first positions))
(on-board-p ,@(rest positions)))))))
By the way, I originally tried to start writing this as a function, but I couldn't work out how to send (rest positions) through to the recursive call, it would just complain that was was being sent through for the recursion was 'not of type REAL'. If this can be more easily written as a function, then I'd like to hear how. (Although even if in this case I'm better off with a function, I'd still like to know how to mix LABELS with macros in cases like this, just for educational purposes.)
Thanks!