[gambit-list] Seekable String Ports

Marc Feeley feeley at iro.umontreal.ca
Fri Jun 12 00:43:09 EDT 2009


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




More information about the Gambit-list mailing list