[plt-scheme] changes to file-position aren't captured by read-syntax ?

From: Felix Klock's plt proxy (pltscheme at pnkfx.org)
Date: Thu Jan 22 11:39:28 EST 2004

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)
		


Posted on the users mailing list.