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

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Jan 22 08:26:20 EST 2004

At Fri, 16 Jan 2004 17:03:10 -0500, "Felix Klock's plt proxy" wrote:
> Specifically, it seems like when you change the file position, and then 
> do read-syntax, read-syntax acts like the stream has not been changed, 
> and continues assigning location numbers incrementally.

Right - this is because due to the way "position" for syntax
information is defined:

 MzScheme keeps track of the _position_ in a port as the number of
 characters that have been read from any input port (independent of the
 read/write position, which is accessed or changed with file-position).

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)))))))



Posted on the users mailing list.