I'm attempting to make a macro that will take an input stream and do something different depending on the contents of the first line read, and then read further input. I'm having trouble just having a macro that will take an input stream and read some values from it.
A contrived example:
(defmacro read-and-print (&optional in)
`(print
,(if (string= (read-line in) "greet")
`(concatenate 'string "hello" (read-line ,in))
`(read-line ,in))))
(with-input-from-string (in "greet
bob") (read-and-print in))
but even that is producing the following error
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION SB-GRAY:STREAM-READ-LINE (1)>
when called with arguments
(IN).
[Condition of type SB-INT:COMPILED-PROGRAM-ERROR]
The thing that's really baffling me is even changing the function to take a string for the first line isn't working:
(defmacro read-and-print (command &optional in)
`(print
,(if (string= command "greet")
`(concatenate 'string "hello " (read-line ,in))
`(read-line ,in))))
(with-input-from-string (in "greet
bob")
(read-and-print (read-string in) in))
This gives me
The value
(READ-LINE IN)
is not of type
(OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING SYMBOL CHARACTER)
when binding SB-IMPL::STRING1
[Condition of type SB-INT:COMPILED-PROGRAM-ERROR]
While this executes completely fine:
(with-input-from-string (in "greet
bob")
(read-and-print "greet" in))
Is there something special about the with-input-from-string
macro that I'm missing? I suspect I'm missing something very obvious about macros, but googling has gotten me nowhere.