[gambit-list] Seekable String Ports
Taylor Venable
taylor at metasyntax.net
Thu Jun 11 23:11:30 EDT 2009
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.)
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.
My current code, for background:
(define char/exactly
(lambda (c)
(lambda (stream)
(let ((char (read-char stream)))
(cond ((eof-object? char) #f)
((not (char=? char c)) #f)
(else char))))))
(define either
(lambda combinators
(lambda (stream)
(let loop ((c combinators))
(cond ((null? c) #f)
((apply (car c) (list stream)) #t)
(else (loop (cdr c))))))))
As defined here, the either function will not undo the changes done by
char/exactly (in the example above), thus each choice will advance the
stream by one character. We could work around it here by using
peek-char rather than read-char but that wouldn't scale to when either
is used on functions that read large chunks of data before failing.
Thanks for any ideas,
--
Taylor Christopher Venable
http://real.metasyntax.net:2357/
More information about the Gambit-list
mailing list