[racket] read-syntax for an entire .rkt file

From: Greg Hendershott (greghendershott at gmail.com)
Date: Fri Feb 20 19:38:17 EST 2015

A few more points I've discovered:

- If you might want source position info, you need to use
  `port-count-lines!`.

- If the file has relative requires -- e.g. `(require "foo.rkt")` -- you
  need to set `current-load-relative-directory`. And you want to do the
  `expand` while this is set.

- `with-input-from-file` is handy to close the port for you.

Here's a `file->syntax` function I have in racket-mode:

;; Return a syntax object (or #f) for the contents of `file`.
(define (file->syntax file #:expand? expand?)
  (define-values (base _ __) (split-path file))
  (parameterize ([current-load-relative-directory base]
                 [current-namespace (make-base-namespace)])
    (define stx (with-handlers ([exn:fail? (const #f)])
                  (with-module-reading-parameterization
                   (thunk
                    (with-input-from-file file read-syntax/count-lines)))))
    (if expand?
        (expand stx) ;; do this while current-load-relative-directory is set
        stx)))

(define (read-syntax/count-lines)
  (port-count-lines! (current-input-port))
  (read-syntax))

Posted on the users mailing list.