General reformat, and move the new comment about #%module-begin to the end of the section

svn: r17194
This commit is contained in:
Eli Barzilay 2009-12-05 02:41:35 +00:00
parent 49df9502a4
commit ac0a1dc7d8

View File

@ -2,7 +2,8 @@
@(require "common.ss") @(require "common.ss")
@(require (for-label syntax/module-reader @(require (for-label syntax/module-reader
(only-in scribble/reader read-syntax-inside read-inside))) (only-in scribble/reader
read-syntax-inside read-inside)))
@title[#:tag "module-reader"]{Module Reader} @title[#:tag "module-reader"]{Module Reader}
@ -15,16 +16,17 @@ is the name of the module that will be used in the language position
of read modules; using keywords, the resulting readers can be of read modules; using keywords, the resulting readers can be
customized in a number of ways. customized in a number of ways.
@defform*/subs[[(#%module-begin module-path) @defform*/subs[
(#%module-begin module-path reader-option ... body ....) [(#%module-begin module-path)
(#%module-begin reader-option ... body ....)] (#%module-begin module-path reader-option ... body ....)
([reader-option (code:line #:language lang-expr) (#%module-begin reader-option ... body ....)]
(code:line #:read read-expr) ([reader-option (code:line #:language lang-expr)
(code:line #:read-syntax read-syntax-expr) (code:line #:read read-expr)
(code:line #:info info-expr) (code:line #:read-syntax read-syntax-expr)
(code:line #:wrapper1 wrapper1-expr) (code:line #:info info-expr)
(code:line #:wrapper2 wrapper2-expr) (code:line #:wrapper1 wrapper1-expr)
(code:line #:whole-body-readers? whole?-expr)])]{ (code:line #:wrapper2 wrapper2-expr)
(code:line #:whole-body-readers? whole?-expr)])]{
Causes a module written in the @schememodname[syntax/module-reader] Causes a module written in the @schememodname[syntax/module-reader]
language to define and provide @schemeidfont{read} and language to define and provide @schemeidfont{read} and
@ -37,16 +39,15 @@ That is, a module @scheme[_something]@scheme[/lang/reader] implemented
as as
@schemeblock[ @schemeblock[
(module reader syntax/module-reader (module reader syntax/module-reader
module-path) module-path)
] ]
creates a reader that converts @scheme[#,(hash-lang)_something] creates a reader that converts @scheme[#,(hash-lang)_something] into
into
@schemeblock[ @schemeblock[
(module _name-id module-path (module _name-id module-path
(#%module-begin ....)) (#%module-begin ....))
] ]
where @scheme[_name-id] is derived from the name of the port used by where @scheme[_name-id] is derived from the name of the port used by
@ -55,8 +56,8 @@ the reader.
For example, @scheme[scheme/base/lang/reader] is implemented as For example, @scheme[scheme/base/lang/reader] is implemented as
@schemeblock[ @schemeblock[
(module reader syntax/module-reader (module reader syntax/module-reader
scheme/base) scheme/base)
] ]
The reader functions can be customized in a number of ways, using The reader functions can be customized in a number of ways, using
@ -68,10 +69,10 @@ reading. For example, you can implement a
using: using:
@schemeblock[ @schemeblock[
(module reader syntax/module-reader (module reader syntax/module-reader
honu honu
#:read read-honu #:read read-honu
#:read-syntax read-honu-syntax) #:read-syntax read-honu-syntax)
] ]
Similarly, the @scheme[#:info] keyword supplies a procedure to be used Similarly, the @scheme[#:info] keyword supplies a procedure to be used
@ -82,17 +83,17 @@ procedure (to be called with the key and default result for default
handling). If @scheme[#:info] is not supplied, the default handling). If @scheme[#:info] is not supplied, the default
info-getting procedure is used. info-getting procedure is used.
You can also use the (optional) module @scheme[body] forms to provide more You can also use the (optional) module @scheme[body] forms to provide
definitions that might be needed to implement your reader functions. more definitions that might be needed to implement your reader
For example, here is a case-insensitive reader for the functions. For example, here is a case-insensitive reader for the
@scheme[scheme/base] language: @scheme[scheme/base] language:
@schemeblock[ @schemeblock[
(module reader syntax/module-reader (module reader syntax/module-reader
scheme/base scheme/base
#:read (wrap read) #:read-syntax (wrap read-syntax) #:read (wrap read) #:read-syntax (wrap read-syntax)
(define ((wrap reader) . args) (define ((wrap reader) . args)
(parameterize ([read-case-sensitive #f]) (apply reader args)))) (parameterize ([read-case-sensitive #f]) (apply reader args))))
] ]
In many cases, however, the standard @scheme[read] and In many cases, however, the standard @scheme[read] and
@ -105,11 +106,11 @@ alternative definition of the case-insensitive language using
@scheme[#:wrapper1]: @scheme[#:wrapper1]:
@schemeblock[ @schemeblock[
(module reader syntax/module-reader (module reader syntax/module-reader
scheme/base scheme/base
#:wrapper1 (lambda (t) #:wrapper1 (lambda (t)
(parameterize ([read-case-sensitive #f]) (parameterize ([read-case-sensitive #f])
(t)))) (t))))
] ]
Note that using a @tech[#:doc refman]{readtable}, you can implement Note that using a @tech[#:doc refman]{readtable}, you can implement
@ -125,11 +126,11 @@ that corresponds to a file). Here is the case-insensitive implemented
using this option: using this option:
@schemeblock[ @schemeblock[
(module reader syntax/module-reader (module reader syntax/module-reader
scheme/base scheme/base
#:wrapper2 (lambda (in r) #:wrapper2 (lambda (in r)
(parameterize ([read-case-sensitive #f]) (parameterize ([read-case-sensitive #f])
(r in)))) (r in))))
] ]
In some cases, the reader functions read the whole file, so there is In some cases, the reader functions read the whole file, so there is
@ -138,13 +139,6 @@ no need to iterate them (e.g., Scribble's @scheme[read-inside] and
@scheme[#:whole-body-readers?] as @scheme[#t] --- the readers are @scheme[#:whole-body-readers?] as @scheme[#t] --- the readers are
expected to return a list of expressions in this case. expected to return a list of expressions in this case.
[If such whole-body reader functions return a list with a single
expression that begins with @scheme[#%module-begin], then the
@scheme[syntax/module-reader] language will not inappropriately add
another. This for backwards-compatibility with older code: having a
whole-body reader functions or wrapper functions that return a
@scheme[#%module-begin]-wrapped body is deprectaed.]
In addition, the two wrappers can return a different value than the In addition, the two wrappers can return a different value than the
wrapped function. This introduces two more customization points for wrapped function. This introduces two more customization points for
the resulting readers: the resulting readers:
@ -155,10 +149,9 @@ the resulting readers:
following reader defines a ``language'' that ignores the contents following reader defines a ``language'' that ignores the contents
of the file, and simply reads files as if they were empty: of the file, and simply reads files as if they were empty:
@schemeblock[ @schemeblock[
(module ignored syntax/module-reader (module ignored syntax/module-reader
scheme/base scheme/base
#:wrapper1 (lambda (t) (t) '())) #:wrapper1 (lambda (t) (t) '()))]
]
Note that it is still performing the read, otherwise the module Note that it is still performing the read, otherwise the module
loader will complain about extra expressions.} loader will complain about extra expressions.}
@item{The reader function that is passed to a @scheme[#:wrapper2] @item{The reader function that is passed to a @scheme[#:wrapper2]
@ -175,22 +168,22 @@ scribble syntax, and the first datum in the file determines the actual
language (which means that the library specification is effectively language (which means that the library specification is effectively
ignored): ignored):
@schemeblock[ @schemeblock[
(module reader syntax/module-reader (module reader syntax/module-reader
-ignored- -ignored-
#:wrapper2 #:wrapper2
(lambda (in rd stx?) (lambda (in rd stx?)
(let* ([lang (read in)] (let* ([lang (read in)]
[mod (parameterize ([current-readtable [mod (parameterize ([current-readtable
(make-at-readtable)]) (make-at-readtable)])
(rd in))] (rd in))]
[mod (if stx? mod (datum->syntax #f mod))] [mod (if stx? mod (datum->syntax #f mod))]
[r (syntax-case mod () [r (syntax-case mod ()
[(module name lang* . body) [(module name lang* . body)
(with-syntax ([lang (datum->syntax (with-syntax ([lang (datum->syntax
#'lang* lang #'lang*)]) #'lang* lang #'lang*)])
(syntax/loc mod (module name lang . body)))])]) (syntax/loc mod (module name lang . body)))])])
(if stx? r (syntax->datum r)))) (if stx? r (syntax->datum r))))
(require scribble/reader)) (require scribble/reader))
] ]
This ability to change the language position in the resulting module This ability to change the language position in the resulting module
@ -198,22 +191,33 @@ expression can be useful in cases such as the above, where the base
language module is chosen based on the input. To make this more language module is chosen based on the input. To make this more
convenient, you can omit the @scheme[module-path] and instead specify convenient, you can omit the @scheme[module-path] and instead specify
it via a @scheme[#:language] expression. This expression can evaluate it via a @scheme[#:language] expression. This expression can evaluate
to a datum or syntax object that is used as a language, or it can evaluate to a thunk. to a datum or syntax object that is used as a language, or it can
In the latter case, the thunk is invoked to obtain such a datum evaluate to a thunk. In the latter case, the thunk is invoked to
before reading the module body begins, in a dynamic extent where obtain such a datum before reading the module body begins, in a
@scheme[current-input-port] is the source input. A syntax object is converted dynamic extent where @scheme[current-input-port] is the source
using @scheme[syntax->datum] when a datum is needed (for @scheme[read] instead of @scheme[read-syntax]). input. A syntax object is converted using @scheme[syntax->datum] when
Using @scheme[#:language], the last a datum is needed (for @scheme[read] instead of @scheme[read-syntax]).
example above can be written more concisely: Using @scheme[#:language], the last example above can be written more
concisely:
@schemeblock[ @schemeblock[
(module reader syntax/module-reader (module reader syntax/module-reader
#:language read #:language read
#:wrapper2 (lambda (in rd stx?) #:wrapper2 (lambda (in rd stx?)
(parameterize ([current-readtable (parameterize ([current-readtable
(make-at-readtable)]) (make-at-readtable)])
(rd in))) (rd in)))
(require scribble/reader)) (require scribble/reader))
] ]
Note: if such whole-body reader functions return a list with a single
expression that begins with @scheme[#%module-begin], then the
@scheme[syntax/module-reader] language will not inappropriately add
another. This for backwards-compatibility with older code: having a
whole-body reader functions or wrapper functions that return a
@scheme[#%module-begin]-wrapped body is deprectaed.
} }
@ -234,7 +238,8 @@ procedures chains to another language that is specified in an input
stream. stream.
@margin-note{The @schememodname[at-exp], @schememodname[reader], and @margin-note{The @schememodname[at-exp], @schememodname[reader], and
@schememodname[planet] languages are implemented using this function.} @schememodname[planet] languages are implemented using this
function.}
The generated functions expect a target language description in the The generated functions expect a target language description in the
input stream that is provided to @scheme[read-spec]. The default input stream that is provided to @scheme[read-spec]. The default
@ -246,8 +251,9 @@ reader exception is raised, and @scheme[path-desc-str] is used as a
description of the expected language form in the error message. description of the expected language form in the error message.
@margin-note{The @schememodname[reader] language supplies @margin-note{The @schememodname[reader] language supplies
@scheme[read] for @scheme[read-spec]. The @schememodname[at-exp] and @scheme[read] for @scheme[read-spec]. The @schememodname[at-exp] and
@schememodname[planet] languages use the default @scheme[read-spec].} @schememodname[planet] languages use the default
@scheme[read-spec].}
The result of @scheme[read-spec] is converted to a module path using The result of @scheme[read-spec] is converted to a module path using
@scheme[module-path-parser]. If @scheme[module-path-parser] produces @scheme[module-path-parser]. If @scheme[module-path-parser] produces
@ -263,9 +269,9 @@ passed to @scheme[convert-read], @scheme[convert-read-syntax], or
@scheme[convert-get-info], respectively. @scheme[convert-get-info], respectively.
@margin-note{The @schememodname[at-exp] language supplies @margin-note{The @schememodname[at-exp] language supplies
@scheme[convert-read] and @scheme[convert-read-syntax] to add @scheme[convert-read] and @scheme[convert-read-syntax] to add
@"@"-expression support to the current readtable before chaining to @"@"-expression support to the current readtable before chaining to
the given procedures.} the given procedures.}
The procedures generated by @scheme[make-meta-reader] are not meant The procedures generated by @scheme[make-meta-reader] are not meant
for use with the @schememodname[syntax/module-reader] language; they for use with the @schememodname[syntax/module-reader] language; they
@ -293,5 +299,5 @@ arguments are used to construct the syntax object for the language
position of the module. The result is roughly position of the module. The result is roughly
@schemeblock[ @schemeblock[
`(module ,_name-id ,mod-path ,@_lst) `(module ,_name-id ,mod-path ,@_lst)
]} ]}