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.
 
     
    