[plt-scheme] changes to file-position aren't captured by read-syntax ?
On Jan 22, 2004, at 8:26 AM, Matthew Flatt wrote:
>
> Bute here's a way to get the behavior that you want:
>
> * When you remember the file position for returning later, also
> remember the port's location information.
>
> * When you move back to the remembered file position, create a fresh
> port that draws from the file port (probably using
> `input-port-append').
>
> * Call `read-syntax' with this fresh port, and supply offsets that
> correspond to the remembered location information.
>
> Note that line and columnn information works out, too. In the example
> code below (a revision of your code), I've enabled line and column
> counting.
>
> Matthew
>
> ----------------------------------------
>
> (require (lib "thread.ss"))
> (let ((fname "isolate-test-file-2")
> (so->d syntax-object->datum))
> (call-with-output-file fname
> (lambda (output)
> (display "\n\n\n " output)
> (write '(car '(a b c)) output)))
> (call-with-input-file fname
> (lambda (input)
> (port-count-lines! input)
> ; Still works if you uncomment the following line
> ; (read-string 4 input)
> (let-values ([(l c p) (port-next-location input)])
> (let* ((start-pos (file-position input))
> (s1 (read-syntax fname input))
> (s1-pos (syntax-position s1)))
> (file-position input start-pos)
> (let* ((s2 (read-syntax fname
> (let ([i (input-port-append #f input)])
> (port-count-lines! i)
> i)
> (list (if l (sub1 l) 0) (or c 0) (sub1 p))))
> (s2-pos (syntax-position s2)))
> (display `((s1: ,(so->d s1) s1-pos: ,s1-pos
> s1-line: ,(syntax-line s1)
> s1-col: ,(syntax-column s1))
> (s2: ,(so->d s2) s2-pos: ,s2-pos
> s2-line: ,(syntax-line s2)
> s2-col: ,(syntax-column s2))))
> (newline)))))))
>
Am I wrong in thinking that to generalize this approach to multiple
repeated read-syntaxes from different spots in the file, I'm not going
to be able to use port-next-location more than once, but instead I am
going to have to keep track of the deltas between positions (and
column/line numbers, etc) and then add them on incrementally?
Here, wait, I'll try a different approach:
Here is a test program that exposes a problem with the approach you
recommend: I cannot repeatedly use port-next-position to decide where I
am in the file after I've done some backtracking with file-position,
because port-next-position returns values based on what the stream has
output.
(require (lib "thread.ss"))
(let ((fname "isolate-test-file-2")
(so->d syntax-object->datum))
(if (file-exists? fname) (delete-file fname))
(call-with-output-file fname
(lambda (output)
(display "\n\n\n " output)
(write '(car '(a b c)) output)
(write '(car '(x y z)) output)
))
(call-with-input-file fname
(lambda (input)
(port-count-lines! input)
; Still works if you uncomment the following line
; (read-string 4 input)
(let ()
(define (test test-name)
(let-values ([(l c p) (port-next-location input)])
(let* ((start-pos (file-position input))
(s1 (read-syntax fname input))
(s1-pos (syntax-position s1)))
(file-position input start-pos)
(let* ((s2 (read-syntax fname
(let ([i (input-port-append #f
input)])
(port-count-lines! i)
i)
(list (if l (sub1 l) 0) (or c 0)
(sub1 p))))
(s2-pos (syntax-position s2)))
(file-position input start-pos)
(let* ((s3 (read-syntax fname
(let ([i (input-port-append #f
input)])
(port-count-lines! i)
i)
(list (if l (sub1 l) 0) (or c 0)
(sub1 p))))
(s3-pos (syntax-position s3)))
(display `(,test-name
(s1: ,(so->d s1) s1-pos: ,s1-pos
s1-line: ,(syntax-line s1)
s1-col: ,(syntax-column s1))
(s2: ,(so->d s2) s2-pos: ,s2-pos
s2-line: ,(syntax-line s2)
s2-col: ,(syntax-column s2))
(s3: ,(so->d s3) s3-pos: ,s3-pos
s3-line: ,(syntax-line s3)
s3-col: ,(syntax-column s3))
))
(newline))))))
(test 'one)
(test 'two))
)))
This prints
(one (s1: (car (quote (a b c))) s1-pos: 7 s1-line: 4 s1-col: 3) (s2:
(car (quote (a b c))) s2-pos: 7 s2-line: 4 s2-col: 3) (s3: (car (quote
(a b c))) s3-pos: 7 s3-line: 4 s3-col: 3) )
(two (s1: (car (quote (x y z))) s1-pos: 28 s1-line: 10 s1-col: 24) (s2:
(car (quote (x y z))) s2-pos: 28 s2-line: 10 s2-col: 24) (s3: (car
(quote (x y z))) s3-pos: 28 s3-line: 10 s3-col: 24) )
note that while all of the s1/s2/s3's are internally consistent, test
two is totally out of whack with respect to the original file (and so
my stack traces will still be totally goofy)
So it seems like I'm going to have to keep track of the
position/line/column for the file itself separately (by calculating the
delta's every time I call file-position) and then pass those in to
read-syntax. It seems a shame that there isn't something simpler
provided by the libraries...
(As an alternative approach, I am guessing that instead of using
port-next-position to grab the info to pass to read-syntax, I could
just use file-position and pass in zeroes as the line and column
numbers)
Also, I don't see documentation for input-port-append in the appendix
for MzLib... where is it documented?
-Felix
----
"i'm a nerd
i just saw you log in in building 4, and
i had the riff from "bad to the bone" go through my head...."
-josh
----
"...and e to the a quantity to the b is e to the ab and this
you knew since the age of two! When you were still in your crib,
crying for your mama!" -G.C. Rota (10/8/97)