On 11-Jun-09, at 11:11 PM, Taylor Venable wrote:
Is there any way to seek through string ports? When I try to use input-port-byte-position I get this:
(call-with-input-string "asdf" (either (char/exactly #\c) (char/ exactly #\s)))
*** ERROR IN #<procedure #10>, "tcv-gambit-parse.scm"@66.20 -- (Argument 1) Device INPUT PORT expected (input-port-byte-position '#<input-port #11 (string)>)
(I'm doubtful that input-port-byte-position would be what I want anyway if the string included characters that weren't encoded as single bytes, but that's a digression.)
String ports are implemented in such a way that the consumed part of the string is garbage collected. A repositioning operation can't be implemented without losing this important feature.
I'm trying to write a parser combinator library, and part of that entails some rewinding of streams for ordered-choice operations (as illustrated above). A potential alternative would be to duplicate the port's contents and use a different port for each alternative, but I am not aware of any API to do this either. Any ideas on how to accomplish this objective? I need something that works for at least string ports and device ports.
How about:
(define (my-open-input-string str) (cons str 0))
(define (my-read-char p) (let ((str (car p)) (pos (cdr p))) (if (< pos (string-length str))) (begin (set-cdr! p (+ pos 1)) (string-ref str pos)) '#!eof)))
(define (my-input-port-position-set! p pos) (set-cdr! p pos))
Marc