plt-r6rs executable and initial r6rs docs

svn: r8859
This commit is contained in:
Matthew Flatt 2008-03-03 21:59:09 +00:00
parent 5f499c1a4d
commit b7cfd2fd00
11 changed files with 459 additions and 41 deletions

View File

@ -1,15 +1,15 @@
(module cm mzscheme (module cm scheme/base
(require syntax/modcode (require syntax/modcode
syntax/modresolve syntax/modresolve
(lib "main-collects.ss" "setup") (lib "main-collects.ss" "setup")
mzlib/file) scheme/file)
(provide make-compilation-manager-load/use-compiled-handler (provide make-compilation-manager-load/use-compiled-handler
managed-compile-zo managed-compile-zo
make-caching-managed-compile-zo make-caching-managed-compile-zo
trust-existing-zos trust-existing-zos
manager-compile-notify-handler manager-compile-notify-handler
(rename trace manager-trace-handler)) (rename-out [trace manager-trace-handler]))
(define manager-compile-notify-handler (make-parameter void)) (define manager-compile-notify-handler (make-parameter void))
(define trace (make-parameter void)) (define trace (make-parameter void))
@ -71,7 +71,7 @@
(with-handlers ([void (lambda (exn) (with-handlers ([void (lambda (exn)
(try-delete-file path) (try-delete-file path)
(raise exn))]) (raise exn))])
(let ([out (open-output-file path 'truncate/replace)]) (let ([out (open-output-file path #:exists 'truncate/replace)])
(dynamic-wind (dynamic-wind
void void
(lambda () (lambda ()
@ -96,7 +96,7 @@
(newline op))))) (newline op)))))
(define (touch path) (define (touch path)
(close-output-port (open-output-file path 'append))) (close-output-port (open-output-file path #:exists 'append)))
(define (compilation-failure mode path zo-name date-path reason) (define (compilation-failure mode path zo-name date-path reason)
(with-handlers ((exn:fail:filesystem? void)) (with-handlers ((exn:fail:filesystem? void))
@ -108,7 +108,7 @@
(display reason p)))) (display reason p))))
(trace-printf "failure")) (trace-printf "failure"))
(define (compile-zo mode path) (define (compile-zo mode path read-src-syntax)
((manager-compile-notify-handler) path) ((manager-compile-notify-handler) path)
(trace-printf "compiling: ~a" path) (trace-printf "compiling: ~a" path)
(parameterize ([indent (string-append " " (indent))]) (parameterize ([indent (string-append " " (indent))])
@ -145,9 +145,9 @@
(cons (path->bytes p) (cons (path->bytes p)
external-deps))))) external-deps)))))
d)))]) d)))])
(get-module-code path mode))] (get-module-code path mode #:source-reader read-src-syntax))]
[code-dir (get-code-dir mode path)]) [code-dir (get-code-dir mode path)])
(if (not (directory-exists? code-dir)) (when (not (directory-exists? code-dir))
(make-directory* code-dir)) (make-directory* code-dir))
(with-compile-output (with-compile-output
zo-name zo-name
@ -214,8 +214,8 @@
(file-or-directory-modify-seconds name))) (file-or-directory-modify-seconds name)))
(apply first-date l))])) (apply first-date l))]))
(define (compile-root mode path up-to-date) (define (compile-root mode path up-to-date read-src-syntax)
(let ([path (simplify-path (expand-path path))]) (let ([path (simplify-path (cleanse-path path))])
(let ((stamp (and up-to-date (let ((stamp (and up-to-date
(hash-table-get up-to-date path #f)))) (hash-table-get up-to-date path #f))))
(cond (cond
@ -235,7 +235,7 @@
(cond (cond
((> path-time path-zo-time) ((> path-time path-zo-time)
(trace-printf "newer src...") (trace-printf "newer src...")
(compile-zo mode path)) (compile-zo mode path read-src-syntax))
(else (else
(let ((deps (with-handlers ((exn:fail:filesystem? (lambda (ex) (list (version))))) (let ((deps (with-handlers ((exn:fail:filesystem? (lambda (ex) (list (version)))))
(call-with-input-file (path-add-suffix (get-compilation-path mode path) #".dep") (call-with-input-file (path-add-suffix (get-compilation-path mode path) #".dep")
@ -244,13 +244,13 @@
((or (not (pair? deps)) ((or (not (pair? deps))
(not (equal? (version) (car deps)))) (not (equal? (version) (car deps))))
(trace-printf "newer version...") (trace-printf "newer version...")
(compile-zo mode path)) (compile-zo mode path read-src-syntax))
((ormap (lambda (d) ((ormap (lambda (d)
;; str => str is a module file name (check transitive dates) ;; str => str is a module file name (check transitive dates)
;; (cons 'ext str) => str is an non-module file (check date) ;; (cons 'ext str) => str is an non-module file (check date)
(let ([t (cond (let ([t (cond
[(bytes? d) (compile-root mode (bytes->path d) up-to-date)] [(bytes? d) (compile-root mode (bytes->path d) up-to-date read-src-syntax)]
[(path? d) (compile-root mode d up-to-date)] [(path? d) (compile-root mode d up-to-date read-src-syntax)]
[(and (pair? d) [(and (pair? d)
(eq? (car d) 'ext) (eq? (car d) 'ext)
(or (bytes? (cdr d)) (or (bytes? (cdr d))
@ -270,19 +270,20 @@
(cons 'ext (main-collects-relative->path (cdr p))) (cons 'ext (main-collects-relative->path (cdr p)))
(main-collects-relative->path p))) (main-collects-relative->path p)))
(cdr deps))) (cdr deps)))
(compile-zo mode path)))))) (compile-zo mode path read-src-syntax))))))
(let ((stamp (get-compiled-time mode path #t))) (let ((stamp (get-compiled-time mode path #t)))
(hash-table-put! up-to-date path stamp) (hash-table-put! up-to-date path stamp)
stamp))))))))) stamp)))))))))
(define (managed-compile-zo zo) (define (managed-compile-zo zo [read-src-syntax read-syntax])
((make-caching-managed-compile-zo) zo)) ((make-caching-managed-compile-zo read-src-syntax) zo))
(define (make-caching-managed-compile-zo) (define (make-caching-managed-compile-zo [read-src-syntax read-syntax])
(let ([cache (make-hash-table 'equal)]) (let ([cache (make-hash-table 'equal)])
(lambda (zo) (lambda (zo)
(parameterize ([current-load/use-compiled (make-compilation-manager-load/use-compiled-handler/table cache)]) (parameterize ([current-load/use-compiled (make-compilation-manager-load/use-compiled-handler/table cache)])
(compile-root (car (use-compiled-file-paths)) (path->complete-path zo) cache))))) (compile-root (car (use-compiled-file-paths)) (path->complete-path zo) cache read-src-syntax)
(void)))))
(define (make-compilation-manager-load/use-compiled-handler) (define (make-compilation-manager-load/use-compiled-handler)
(make-compilation-manager-load/use-compiled-handler/table (make-hash-table 'equal))) (make-compilation-manager-load/use-compiled-handler/table (make-hash-table 'equal)))
@ -330,7 +331,7 @@
(default-handler path mod-name)] (default-handler path mod-name)]
[else [else
(trace-printf "processing: ~a" path) (trace-printf "processing: ~a" path)
(compile-root (car modes) path cache) (compile-root (car modes) path cache read-syntax)
(trace-printf "done: ~a" path) (trace-printf "done: ~a" path)
(default-handler path mod-name)]))]) (default-handler path mod-name)]))])
compilation-manager-load-handler)))) compilation-manager-load-handler))))

View File

@ -82,7 +82,7 @@ By default, @exec{plt-r5rs} departs from @|r5rs| conformance in one
crucial way: the initial bindings of primitives correspond to module crucial way: the initial bindings of primitives correspond to module
imports into the top-level environment, instead of variable bindings. imports into the top-level environment, instead of variable bindings.
This difference is visible if the name of a primitive is redefined at This difference is visible if the name of a primitive is redefined at
the top level. Use the @as-index{@DFlag{slow}} command-line the top level. Use the @as-index{@DFlag{no-prim}} command-line
flag---before a file to load, if any---to obtain the standard behavior flag---before a file to load, if any---to obtain the standard behavior
for primitive bindings (at the cost of performance). for primitive bindings (at the cost of performance).
@ -110,7 +110,7 @@ corresponds to @|r5rs|. Use @scheme[(namespace-require/copy 'r5rs)]
with an empty namespace to maximize conformance with @|r5rs|; Using with an empty namespace to maximize conformance with @|r5rs|; Using
@scheme[(namespace-require 'r5rs)], in contrast, creates primitive @scheme[(namespace-require 'r5rs)], in contrast, creates primitive
bindings as imports, which is the same as using bindings as imports, which is the same as using
@seclink["plt-r5rs"]{@exec{plt-r5rs}} without the @DFlag{slow} flag. @seclink["plt-r5rs"]{@exec{plt-r5rs}} without the @DFlag{no-prim} flag.
More simply, use @scheme[(scheme-report-environment 5)]. See also More simply, use @scheme[(scheme-report-environment 5)]. See also
@schememodname[r5rs/init], which sets reader and printer parameters to @schememodname[r5rs/init], which sets reader and printer parameters to
increase conformance. increase conformance.

View File

@ -6,7 +6,7 @@
(define-values (main args) (define-values (main args)
(command-line (command-line
#:once-each #:once-each
[("--slow") "disable assumption that primitives are never redefined" [("--no-prim") "(slow) disable assumption that primitives are never redefined"
(slow #t)] (slow #t)]
#:handlers #:handlers
(case-lambda (case-lambda

View File

@ -1 +1,7 @@
#lang setup/infotab #lang setup/infotab
(define scribblings '(("scribblings/r6rs.scrbl" (multi-page))))
(define doc-categories '((languages -1)))
(define mzscheme-launcher-names '("PLT R6RS"))
(define mzscheme-launcher-libraries '("run.ss"))

181
collects/r6rs/run.ss Normal file
View File

@ -0,0 +1,181 @@
#lang scheme/base
(require scheme/cmdline
compiler/cm
(prefix-in r6rs: "lang/reader.ss")
syntax/modcode
setup/dirs
scheme/port
scheme/file
"private/readtable.ss")
(define install-mode (make-parameter #f))
(define compile-mode (make-parameter #f))
(define install-all-users (make-parameter #f))
(define install-force (make-parameter #f))
(define-values (main args)
(command-line
#:once-any
[("--install") "install libraries from <file>, or stdin if no <file> provided"
(install-mode #t)]
[("--compile") "compile <file> and all dependencies"
(compile-mode #t)]
#:once-each
[("--all-users") "install into main installation"
(install-all-users #t)]
[("--force") "overwrite existing libraries"
(install-force #t)]
#:handlers
(case-lambda
[(x) (values #f null)]
[(x file . args) (values file args)])
'("file" "arg")))
(current-command-line-arguments (apply vector-immutable args))
(define (r6rs-read-syntax . args)
(datum->syntax #f (apply r6rs:read-syntax args)))
(define (extract-libraries orig)
(let loop ([last-pos 0])
(let ([peeker (let-values ([(line col pos) (port-next-location orig)])
(let ([p (peeking-input-port orig)])
(port-count-lines! p)
(relocate-input-port p line col pos)))])
(port-count-lines! peeker)
(let ([lib-stx (with-r6rs-reader-parameters
(lambda ()
(read-syntax (object-name orig) peeker)))])
(if (eof-object? lib-stx)
null
(let ([lib (syntax->datum lib-stx)])
(unless (and (list? lib)
((length lib) . >= . 2)
(eq? 'library (car lib)))
(raise-syntax-error
'library
"not an R6RS library form"
lib-stx))
(let ([name (cadr lib)])
(unless (valid-name? name)
(error (format
"~a: invalid library name: ~e"
(find-system-path 'run-file)
name)))
(let ([path (name->path name)])
(unless (install-force)
(when (file-exists? path)
(error (format "~a: file already exists: ~a for library: ~e"
(find-system-path 'run-file)
path
name))))
(let ([code (open-output-bytes)])
(let ([pos (file-position peeker)])
(copy-port (make-limited-input-port orig (- pos last-pos)) code)
(cons (cons path (get-output-bytes code #t))
(loop pos))))))))))))
(define (install-libraries orig)
(port-count-lines! orig)
(let ([libs (extract-libraries orig)])
(for-each (lambda (lib)
(let ([path (car lib)]
[code (cdr lib)])
(printf " [installing ~a]\n" path)
(let-values ([(base name dir?) (split-path path)])
(make-directory* base))
(call-with-output-file*
path
#:exists (if (install-force) 'truncate/replace 'error)
(lambda (out)
(display "#!r6rs\n" out)
(display code out)
(display "\n" out)))))
libs)
(for-each (lambda (lib)
(compile-file (car lib)))
libs)))
(define (valid-name? name)
(and (list? name)
(pair? name)
(symbol? (car name))
(let loop ([name name])
(cond
[(null? (cdr name))
(or (symbol? (car name))
(and (list? (car name))
(andmap exact-nonnegative-integer? (car name))))]
[else (and (symbol? (car name))
(loop (cdr name)))]))))
(define (name->path name)
(let* ([name (if (or (= (length name) 1)
(and (= (length name) 2)
(not (symbol? (cadr name)))))
(list* (car name) 'main (cdr name))
name)])
(apply build-path
(if (install-all-users)
(find-collects-dir)
(find-user-collects-dir))
(let loop ([name name])
(cond
[(and (pair? (cdr name))
(null? (cddr name))
(not (symbol? (cadr name))))
;; versioned:
(list
(format "~a~a.ss"
(car name)
(apply
string-append
(map (lambda (v)
(format "-~a" v))
(cadr name)))))]
[(null? (cdr name))
;; unversioned:
(list (format "~a.ss" (car name)))]
[else
(cons (symbol->string (car name))
(loop (cdr name)))])))))
;; ----------------------------------------
(define (compile-file src)
(parameterize ([manager-compile-notify-handler
(lambda (p)
(printf " [Compiling ~a]\n" p))])
(managed-compile-zo src r6rs-read-syntax)))
;; ----------------------------------------
(cond
[(install-mode)
(if main
(call-with-input-file* main install-libraries)
(install-libraries (current-input-port)))]
[(compile-mode)
(unless main
(error (format "~a: need a file to compile" (find-system-path 'run-file))))
(compile-file main)]
[else
(unless main
(error (format "~a: need a file to run" (find-system-path 'run-file))))
(let* ([main (path->complete-path main)]
[zo (let-values ([(base name dir?) (split-path main)])
(build-path base
"compiled"
(path-add-suffix name #".zo")))])
(if ((file-or-directory-modify-seconds zo #f (lambda () -inf.0))
. > .
(file-or-directory-modify-seconds main #f (lambda () -inf.0)))
;; .zo will be used; no need to set reader:
(dynamic-require main #f)
;; need to read with R6RS reader
(let ([code (get-module-code main #:source-reader r6rs-read-syntax)]
[rpath (module-path-index-resolve
(module-path-index-join main #f))])
(parameterize ([current-module-declare-name rpath])
(eval code))
(dynamic-require rpath #f))))])

View File

@ -0,0 +1,196 @@
#lang scribble/doc
@(require scribble/manual
scribble/bnf
(for-label setup/dirs
rnrs/programs-6))
@(define guide-src '(lib "scribblings/guide/guide.scrbl"))
@(define r6rs @elem{R@superscript{6}RS})
@title{@bold{R6RS}: Standard Language}
The ``The Revised@superscript{6} Report on the Algorithmic Language
Scheme'' @cite["Sperber07"] defines a dialect of Scheme. We use
@defterm{@|r6rs|} to refer to both the standard and the language
defined by the standard.
@|r6rs| defines both @defterm{libraries} and @defterm{top-level
programs}. Both correspond to PLT Scheme @defterm{modules} (see
@secref[#:doc guide-src "modules"]). That is, although @|r6rs| defines
top-level programs as entry points, you can just as easily treat a
library as an entry point when using PLT Scheme. The only difference
is that an @|r6rs| top-level program cannot export any bindings to
other modules.
@table-of-contents[]
@; ----------------------------------------
@section{Running Top-Level Programs}
To run a top-level program, either:
@itemize{
@item{Use the @exec{plt-r6rs} executable, supplying the file that
contains the program on the command line:
@commandline{plt-r6rs @nonterm{program-file}}
Additional command-line arguments are propagated as
command-line arguments to the program (accessed via
@scheme[command-line]).
To compile the file to bytecode (to speed future runs of the
program), use @exec{plt-r6rs} with the @DFlag{compile} flag:
@commandline{plt-r6rs --compile @nonterm{program-file}}
The bytecode file is written in a @filepath{compiled}
sub-directory next to @nonterm{program-file}.
For example, if @filepath{hi.scm} contains
@schemeblock[
(import (rnrs))
(display "hello\n")
]
then
@commandline{plt-r6rs hi.scm}
prints ``hello.''}
@item{Prefix the program with @schememetafont{#!r6rs}, which counts
as a comment from the @|r6rs| perspective, but is a synonym for
@scheme[#,(hash-lang) r6rs] from the PLT Scheme perspective.
Such files can be run like any other PLT Scheme module, such as
using @exec{mzscheme}:
@commandline{mzscheme @nonterm{program-file}}
or using DrScheme with the @onscreen{Module} language. The
file can also be compiled to bytecode using @exec{mzc}:
@commandline{mzc @nonterm{program-file}}
For example, if @filepath{hi.ss} contains
@schemeblock[
#,(schememetafont "#!r6rs")
(import (rnrs))
(display "hello\n")
]
then
@commandline{mzscheme hi.ss}
prints ``hello.'' Similarly, opening @filepath{hi.ss} in
DrScheme and clicking @onscreen{Run} prints ``hello'' within
the DrScheme interactions window.}
}
@; ----------------------------------------
@section{Installing Libraries}
To reference an @|r6rs| library from a top-level program or another
library, it must be installed as a collection-based library in PLT
Scheme.
One way to produce an @|r6rs| installed library is to create in
a @techlink[#:doc guide-src]{collection} a file that starts with
@schememetafont{#!r6rs} and that contains a @scheme[library] form. For
example, the following file might be created in a @filepath{hello.ss}
file within a @filepath{examples} collection directory:
@schemeblock[
#,(schememetafont "#!r6rs")
(library (examples hello)
(export greet)
(import (rnrs))
(define (greet)
(display "hello\n")))
]
Alternately, the @exec{plt-r6rs} executable with the @DFlag{install}
flag accepts a sequence of @scheme[library] declarations and installs
them into separate files in a collection directory, based on the
declared name of each library:
@commandline{plt-r6rs --install @nonterm{libraries-file}}
By default, libraries are installed into the user-specific collection
directory (see @scheme[find-user-collects-dir]). The @DFlag{all-users}
flag causes the libraries to be installed into the main installation,
instead (see @scheme[find-collects-dir]):
@commandline{plt-r6rs --install --all-users @nonterm{libraries-file}}
See @secref["libpaths"] for information on how @|r6rs| library names
are turned into collection-based module paths, which determines where
the files are written. Libraries installed by @exec{plt-r6rs
@DFlag{install}} are automatically compiled to bytecode form.
@; ----------------------------------------
@section[#:tag "libpaths"]{Libraries and Collections}
An @|r6rs| library name is sequence of symbols, optionally followed by
a version as a sequence of exact, non-negative integers. Such a name
is converted to a PLT Scheme module pathname (see @secref[#:doc
guide-src "module-paths"]) by concatenating the symbols with a
@litchar{/} separator, and then appending the version integers each
with a preceeding @litchar{-}. As a special case, when an @|r6rs| path
contains a single symbol followed by a version, a @schemeidfont{main}
symbol is effectively inserted after the initial symbol.
Examples:
@schemeblock[
(rnrs io simple (6)) #, @elem{corresponds to} rnrs/io/simple-6
(rnrs) #, @elem{corresponds to} rnrs
(rnrs (6)) #, @elem{corresponds to} rnrs/main-6
]
When an @|r6rs| library or top-level program refers to another
library, it can supply version constraints rather than naming a
specific version. The version constraint is resolved at compile time
by searching the set of installed files.
@; ----------------------------------------
@section{Scheme Interoperability}
Using the conversion rules in @secref["libpaths"], and @r6rs library
can refer to modules that are implemented in other dialects supported
by PLT Scheme, and other PLT Scheme modules can refer to libraries
that are implemented in @|r6rs|.
Beware that a @defterm{pair} in @|r6rs| corresponds to a
@defterm{mutable pair} in @schememodname[scheme/base]. Otherwise,
@|r6rs| libraries and @schememodname[scheme/base] share the same
datatype for numbers, characters, strings, bytevectors (a.k.a. byte
strings), vectors, hash tables, and so on. Input and output
ports from @schememodname[scheme/base] can be used directly as binary
ports with @|r6rs| libraries, and all @|r6rs| ports can be used as
ports in @schememodname[scheme/base] programs, but only textual ports
created via @|r6rs| libraries can be used by other @|r6rs| operations
that expect textual ports.
@; ----------------------------------------------------------------------
@(bibliography
(bib-entry #:key "Sperber07"
#:author "Michael Sperber, R. Kent Dybvig, Matthew Flatt, and Anton van Straaten (editors)"
#:title @elem{The Revised@superscript{6} Report on the Algorithmic Language Scheme}
#:date "2007"
#:url "http://www.r6rs.org/")
)

View File

@ -121,7 +121,7 @@
(define/private (convert-key prefix k) (define/private (convert-key prefix k)
(case (car k) (case (car k)
[(part tech) [(part tech cite)
(let ([rhs (cadr k)]) (let ([rhs (cadr k)])
(if (or (string? rhs) (pair? rhs)) (if (or (string? rhs) (pair? rhs))
(list (car k) (cons prefix (if (pair? rhs) (list (car k) (cons prefix (if (pair? rhs)

View File

@ -1,7 +1,8 @@
#lang scribble/doc #lang scribble/doc
@(require scribble/manual @(require scribble/manual
scribble/eval scribble/eval
"guide-utils.ss") "guide-utils.ss"
(for-label setup/dirs))
@title[#:tag "module-basics"]{Module Basics} @title[#:tag "module-basics"]{Module Basics}
@ -49,9 +50,10 @@ references on all platforms, much like relative URLs.)
Library modules that are distributed with PLT Scheme are usually Library modules that are distributed with PLT Scheme are usually
referenced through an unquoted, suffixless path. The path is relative referenced through an unquoted, suffixless path. The path is relative
(roughly) to the library installation directory. The module below to the library installation directory, which contains directories for
refers to the @filepath{date.ss} library that is part of the individual library @deftech{collections}. The module below refers to
@filepath{scheme} collection. the @filepath{date.ss} library that is part of the @filepath{scheme}
@tech{collection}.
@schememod[ @schememod[
scheme scheme
@ -62,5 +64,22 @@ scheme
(date->string (seconds->date (current-seconds)))) (date->string (seconds->date (current-seconds))))
] ]
In addition to the main @tech{collection} directory, which contains
all collections that are part of the installation, collections can
also be installed in a user-specific location. Finally, additional
collection directories can be specified n configuration files or
through the @envvar{PLTCOLLECTS} search path. Try running the
following program to find out where your collections are:
@schememod[
scheme
(require setup/dirs)
(find-collects-dir) (code:comment #, @t{main collection directory})
(find-user-collects-dir) (code:comment #, @t{user-specific collection directory})
(get-collects-search-dirs) (code:comment #, @t{complete search path})
]
We discuss more forms of module reference later in We discuss more forms of module reference later in
@secref["module-paths"]. @secref["module-paths"].

View File

@ -195,13 +195,20 @@ modules may produce compiled files with inconsistent timestamps and/or
@filepath{.dep} files with incorrect information.} @filepath{.dep} files with incorrect information.}
@defproc[(managed-compile-zo [file path-string?]) void?]{ @defproc[(managed-compile-zo [file path-string?]
[read-src-syntax (any/c input-port? . -> . syntax?) read-syntax])
void?]{
Compiles the given module source file to a @filepath{.zo}, installing Compiles the given module source file to a @filepath{.zo}, installing
a compilation-manager handler while the file is compiled (so that a compilation-manager handler while the file is compiled (so that
required modules are also compiled), and creating a @filepath{.dep} file required modules are also compiled), and creating a @filepath{.dep} file
to record the timestamps of immediate files used to compile the source to record the timestamps of immediate files used to compile the source
(i.e., files @scheme[require]d in the source).} (i.e., files @scheme[require]d in the source).
If @scheme[file] is compiled from source, then
@scheme[read-src-syntax] is used in the same way as
@scheme[read-syntax] to read the source module. The normal
@scheme[read-syntax] is used for any required files, however.}
@defboolparam[trust-existing-zos trust?]{ @defboolparam[trust-existing-zos trust?]{
@ -212,12 +219,13 @@ compilation-manager @scheme[load/use-compiled] handler to ``touch''
out-of-date @filepath{.zo} files instead of re-compiling from source.} out-of-date @filepath{.zo} files instead of re-compiling from source.}
@defproc[(make-caching-managed-compile-zo) @defproc[(make-caching-managed-compile-zo
[read-src-syntax (any/c input-port? . -> . syntax?)])
(path-string? . -> . void?)]{ (path-string? . -> . void?)]{
Returns a procedure that behaves like @scheme[managed-compile-zo], but Returns a procedure that behaves like @scheme[managed-compile-zo]
a cache of timestamp information is preserved across calls to the (providing the same @scheme[read-src-syntax] each time), but a cache
procedure.} of timestamp information is preserved across calls to the procedure.}
@defparam[manager-compile-notify-handler notify (path? . -> . any)]{ @defparam[manager-compile-notify-handler notify (path? . -> . any)]{

View File

@ -37,7 +37,7 @@
(file-or-directory-modify-seconds a))]) (file-or-directory-modify-seconds a))])
(or (and (not bm) am) (and am bm (>= am bm)))))) (or (and (not bm) am) (and am bm (>= am bm))))))
(define (read-one orig-path path src?) (define (read-one orig-path path src? read-src-syntax)
(let ([p ((moddep-current-open-input-file) path)]) (let ([p ((moddep-current-open-input-file) path)])
(when src? (port-count-lines! p)) (when src? (port-count-lines! p))
(dynamic-wind (dynamic-wind
@ -53,7 +53,7 @@
(if (path? base) (if (path? base)
base base
(current-directory)))]) (current-directory)))])
(read-syntax path p))))]) (read-src-syntax path p))))])
(when (eof-object? v) (when (eof-object? v)
(error 'read-one (error 'read-one
"empty file; expected a module declaration in: ~a" path)) "empty file; expected a module declaration in: ~a" path))
@ -77,7 +77,8 @@
(define (get-module-code path (define (get-module-code path
[sub-path "compiled"] [compiler compile] [extension-handler #f] [sub-path "compiled"] [compiler compile] [extension-handler #f]
#:choose [choose (lambda (src zo so) #f)] #:choose [choose (lambda (src zo so) #f)]
#:notify [notify void]) #:notify [notify void]
#:source-reader [read-src-syntax read-syntax])
(unless (path-string? path) (unless (path-string? path)
(raise-type-error 'get-module-code "path or string (sans nul)" path)) (raise-type-error 'get-module-code "path or string (sans nul)" path))
(let*-values ([(path) (resolve path)] (let*-values ([(path) (resolve path)]
@ -106,7 +107,7 @@
(and (not prefer) (and (not prefer)
(date>=? zo path-d))) (date>=? zo path-d)))
(notify zo) (notify zo)
(read-one path zo #f)] (read-one path zo #f read-syntax)]
;; Maybe there's an .so? Use it only if we don't prefer source. ;; Maybe there's an .so? Use it only if we don't prefer source.
[(or (eq? prefer 'so) [(or (eq? prefer 'so)
(and (not prefer) (and (not prefer)
@ -124,7 +125,7 @@
[(or (eq? prefer 'src) [(or (eq? prefer 'src)
path-d) path-d)
(notify path) (notify path)
(with-dir (lambda () (compiler (read-one path path #t))))] (with-dir (lambda () (compiler (read-one path path #t read-src-syntax))))]
;; Report a not-there error ;; Report a not-there error
[else (raise (make-exn:get-module-code [else (raise (make-exn:get-module-code
(format "get-module-code: no such file: ~e" path) (format "get-module-code: no such file: ~e" path)

View File

@ -15,7 +15,10 @@
. -> . . -> .
(or/c (symbols 'src 'zo 'so) false/c)) (or/c (symbols 'src 'zo 'so) false/c))
(lambda (src zo so) #f)] (lambda (src zo so) #f)]
[#:notify notify-proc (any/c . -> . any) void]) [#:notify notify-proc (any/c . -> . any) void]
[#:src-reader read-syntax-proc
(any/c input-port? . -> . syntax?)
read-syntax])
any]{ any]{
Returns a compiled expression for the declaration of the module Returns a compiled expression for the declaration of the module
@ -58,7 +61,10 @@ or an exception is raised (to report that an extension file cannot be
used) when @scheme[ext-proc] is @scheme[#f]. used) when @scheme[ext-proc] is @scheme[#f].
If @scheme[notify-proc] is supplied, it is called for the file If @scheme[notify-proc] is supplied, it is called for the file
(source, @filepath{.zo} or extension) that is chosen.} (source, @filepath{.zo} or extension) that is chosen.
If @scheme[read-syntax-proc] is provided, it is used to read the
module from a source file (but not from a bytecode file).}
@defparam[moddep-current-open-input-file proc (path-string? . -> . input-port?)]{ @defparam[moddep-current-open-input-file proc (path-string? . -> . input-port?)]{