The reader tokenizes before it tries to make sense of a # sequence, so
#&( will be a missing-close-paren error long before you get to the
*#readers* handlers.  For most other cases you might be able to use
port-position which is settable:

(set! *#readers*
      (cons
       (cons #\& (lambda (str)
                   (if (= (string-length str) 1) ; #& followed by a reader 
delimiter
                       (read)
                       (begin
                         (set! (port-position (current-input-port))
                               (- (port-position (current-input-port))
                                  (string-length str)
                                  -1))
                         (string (string-ref str 1))))))
       ()))

(with-input-from-string "#&N"
  (lambda ()
    (display (read)) (newline)
    (display (read)) (newline)))

N
#<eof>

(with-input-from-string "#&Newton"
  (lambda ()
    (display (read)) (newline)
    (display (read)) (newline)
    (display (read)) (newline)))

N
ewton
#<eof>

(with-input-from-string "#&N#&123"
  (lambda ()
    (display (read)) (newline)
    (display (read)) (newline)
    (display (read)) (newline)
    (display (read)) (newline)))

N
1
23
#<eof>

(with-input-from-string "#&(123)"
  (lambda ()
    (display (read)) (newline)
    (display (read)) (newline)))

(123)
#<eof>

I don't want the arity of the *#reader* function to be a flag meaning
"read one character" -- this would only have one use, would require
hand-waving in the documentation, and would make error checking less
reliable.

_______________________________________________
Cmdist mailing list
[email protected]
https://cm-mail.stanford.edu/mailman/listinfo/cmdist

Reply via email to