doc work, especially I/O reference
svn: r6803
This commit is contained in:
parent
fe4857ee3c
commit
987982cd8d
|
@ -180,7 +180,7 @@
|
|||
|
||||
;; ----------------------------------------
|
||||
|
||||
(provide defproc defproc* defstruct defthing defparam
|
||||
(provide defproc defproc* defstruct defthing defparam defboolparam
|
||||
defform defform* defform/subs defform*/subs defform/none
|
||||
specform specform/subs
|
||||
specsubform specsubform/subs specspecsubform specspecsubform/subs specsubform/inline
|
||||
|
@ -242,11 +242,19 @@
|
|||
(define-syntax defstruct
|
||||
(syntax-rules ()
|
||||
[(_ name fields #:immutable #:inspector #f desc ...)
|
||||
(*defstruct (quote-syntax name) 'name 'fields #t #t (lambda () (list desc ...)))]
|
||||
(**defstruct name fields #t #t desc ...)]
|
||||
[(_ name fields #:immutable desc ...)
|
||||
(*defstruct (quote-syntax name) 'name 'fields #t #f (lambda () (list desc ...)))]
|
||||
(**defstruct name fields #t #f desc ...)]
|
||||
[(_ name fields #:inspector #f desc ...)
|
||||
(**defstruct name fields #f #t desc ...)]
|
||||
[(_ name fields desc ...)
|
||||
(*defstruct (quote-syntax name) 'name 'fields #f #f (lambda () (list desc ...)))]))
|
||||
(**defstruct name fields #f #f desc ...)]))
|
||||
(define-syntax **defstruct
|
||||
(syntax-rules ()
|
||||
[(_ name ([field field-contract] ...) immutable? transparent? desc ...)
|
||||
(*defstruct (quote-syntax name) 'name
|
||||
'([field field-contract] ...) (list (lambda () (schemeblock0 field-contract)) ...)
|
||||
#t #t (lambda () (list desc ...)))]))
|
||||
(define-syntax (defform*/subs stx)
|
||||
(syntax-case stx ()
|
||||
[(_ #:literals (lit ...) [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...)
|
||||
|
@ -351,6 +359,10 @@
|
|||
(syntax-rules ()
|
||||
[(_ id arg contract desc ...)
|
||||
(defproc* ([(id) contract] [(id [arg contract]) void?]) desc ...)]))
|
||||
(define-syntax defboolparam
|
||||
(syntax-rules ()
|
||||
[(_ id arg desc ...)
|
||||
(defproc* ([(id) boolean?] [(id [arg any/c]) void?]) desc ...)]))
|
||||
(define-syntax schemegrammar
|
||||
(syntax-rules ()
|
||||
[(_ #:literals (lit ...) id clause ...) (*schemegrammar '(lit ...)
|
||||
|
@ -640,8 +652,9 @@
|
|||
(map symbol->string (car wrappers)))))))
|
||||
(cdr wrappers))))
|
||||
|
||||
(define (*defstruct stx-id name fields immutable? transparent? content-thunk)
|
||||
(define (*defstruct stx-id name fields field-contracts immutable? transparent? content-thunk)
|
||||
(define spacer (hspace 1))
|
||||
(define to-flow (lambda (e) (make-flow (list (make-paragraph (list e))))))
|
||||
(make-splice
|
||||
(cons
|
||||
(make-table
|
||||
|
@ -649,48 +662,144 @@
|
|||
(cons
|
||||
(list (make-flow
|
||||
(list
|
||||
(make-paragraph
|
||||
(list
|
||||
(to-element
|
||||
`(,(schemeparenfont "struct")
|
||||
,(make-target-element*
|
||||
stx-id
|
||||
(to-element name)
|
||||
(let ([name (if (pair? name)
|
||||
(car name)
|
||||
name)])
|
||||
(list* (list name)
|
||||
(list name '?)
|
||||
(list 'make- name)
|
||||
(append
|
||||
(map (lambda (f)
|
||||
(list name '- (car f)))
|
||||
fields)
|
||||
(if immutable?
|
||||
null
|
||||
(map (lambda (f)
|
||||
(list 'set- name '- (car f) '!))
|
||||
fields))))))
|
||||
,(map car fields)
|
||||
,@(if immutable? '(#:immutable) null)
|
||||
,@(if transparent? '(#:inspector #f) null))))))))
|
||||
(map (lambda (v)
|
||||
(let* ([the-name
|
||||
(make-target-element*
|
||||
stx-id
|
||||
(to-element (if (pair? name)
|
||||
(map (lambda (x)
|
||||
(make-just-context x stx-id))
|
||||
name)
|
||||
stx-id))
|
||||
(let ([name (if (pair? name)
|
||||
(car name)
|
||||
name)])
|
||||
(list* (list name)
|
||||
(list name '?)
|
||||
(list 'make- name)
|
||||
(append
|
||||
(map (lambda (f)
|
||||
(list name '- (car f)))
|
||||
fields)
|
||||
(if immutable?
|
||||
null
|
||||
(map (lambda (f)
|
||||
(list 'set- name '- (car f) '!))
|
||||
fields))))))]
|
||||
[short-width (apply +
|
||||
(length fields)
|
||||
8
|
||||
(map (lambda (s)
|
||||
(string-length (symbol->string s)))
|
||||
(append (if (pair? name)
|
||||
name
|
||||
(list name))
|
||||
(map car fields))))])
|
||||
(if (and (short-width . < . max-proto-width)
|
||||
(not immutable?)
|
||||
(not transparent?))
|
||||
(make-paragraph
|
||||
(list
|
||||
(to-element
|
||||
`(,(schemeparenfont "struct")
|
||||
,the-name
|
||||
,(map car fields)))))
|
||||
(make-table
|
||||
#f
|
||||
(append
|
||||
(list
|
||||
(list (to-flow (schemeparenfont "(struct"))
|
||||
(to-flow spacer)
|
||||
(to-flow the-name)
|
||||
(if (or (null? fields)
|
||||
(short-width . < . max-proto-width))
|
||||
(to-flow spacer)
|
||||
(to-flow (make-element #f
|
||||
(list spacer
|
||||
(schemeparenfont "(")))))
|
||||
(to-flow (if (or (null? fields)
|
||||
(short-width . < . max-proto-width))
|
||||
(to-element (map car fields))
|
||||
(to-element (caar fields))))))
|
||||
(if (short-width . < . max-proto-width)
|
||||
null
|
||||
(let loop ([fields fields])
|
||||
(if (null? fields)
|
||||
null
|
||||
(cons (let ([fld (car fields)])
|
||||
(list (to-flow spacer)
|
||||
(to-flow spacer)
|
||||
(to-flow spacer)
|
||||
(to-flow spacer)
|
||||
(to-flow
|
||||
(let ([e (to-element (car fld))])
|
||||
(if (null? (cdr fields))
|
||||
(make-element
|
||||
#f
|
||||
(list e
|
||||
(schemeparenfont
|
||||
(if (and (not immutable?)
|
||||
(not transparent?))
|
||||
"))"
|
||||
")"))))
|
||||
e)))))
|
||||
(loop (cdr fields))))))
|
||||
(cond
|
||||
[(and immutable? transparent?)
|
||||
(list
|
||||
(list (to-flow spacer)
|
||||
(to-flow spacer)
|
||||
(to-flow (to-element '#:immutable))
|
||||
'cont
|
||||
'cont)
|
||||
(list (to-flow spacer)
|
||||
(to-flow spacer)
|
||||
(to-flow (make-element
|
||||
#f
|
||||
(list (to-element '#:inspector)
|
||||
spacer
|
||||
(to-element #f)
|
||||
(schemeparenfont ")"))))
|
||||
'cont
|
||||
'cont))]
|
||||
[immutable?
|
||||
(list
|
||||
(list (to-flow spacer)
|
||||
(to-flow spacer)
|
||||
(to-flow (make-element
|
||||
#f
|
||||
(list (to-element '#:immutable)
|
||||
(schemeparenfont ")"))))
|
||||
'cont
|
||||
'cont))]
|
||||
[transparent?
|
||||
(list
|
||||
(list (to-flow spacer)
|
||||
(to-flow spacer)
|
||||
(to-flow (make-element
|
||||
#f
|
||||
(list (to-element '#:inspector)
|
||||
spacer
|
||||
(to-element #f)
|
||||
(schemeparenfont ")"))))
|
||||
'cont
|
||||
'cont))]
|
||||
[else null]))))))))
|
||||
(map (lambda (v field-contract)
|
||||
(cond
|
||||
[(pair? v)
|
||||
(list
|
||||
(make-flow
|
||||
(list
|
||||
(make-paragraph (append
|
||||
(list
|
||||
(hspace 2)
|
||||
(to-element (car v)))
|
||||
(list
|
||||
spacer
|
||||
":"
|
||||
spacer
|
||||
(to-element (cadr v))))))))]
|
||||
(make-table-if-necessary
|
||||
#f
|
||||
(list
|
||||
(list (to-flow (hspace 2))
|
||||
(to-flow (to-element (car v)))
|
||||
(to-flow spacer)
|
||||
(to-flow ":")
|
||||
(to-flow spacer)
|
||||
(make-flow (list (field-contract))))))))]
|
||||
[else null]))
|
||||
fields)))
|
||||
fields field-contracts)))
|
||||
(content-thunk))))
|
||||
|
||||
(define (*defthing stx-id name result-contract content-thunk)
|
||||
|
|
|
@ -53,7 +53,7 @@ side-effects based on a @scheme[_test-expr], use @scheme[when] or
|
|||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "guide:and+or"]{Combining Tests: @scheme[and] and @scheme[or]}
|
||||
|
||||
@refalso["mz:and+or"]{@scheme[and] and @scheme[or]}
|
||||
@refalso["mz:if"]{@scheme[and] and @scheme[or]}
|
||||
|
||||
Scheme's @scheme[and] and @scheme[or] are syntactic forms, rather than
|
||||
functions. Unlike a function, the @scheme[and] and @scheme[or] forms
|
||||
|
@ -99,7 +99,7 @@ The @scheme[cond] form chains a series of tests to select a result
|
|||
expression. To a first approximation, the syntax of @scheme[cond] is
|
||||
as follows:
|
||||
|
||||
@refalso["mz:cond"]{@scheme[cond]}
|
||||
@refalso["mz:if"]{@scheme[cond]}
|
||||
|
||||
@specform[(cond [test-expr expr ...+]
|
||||
...)]
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
(italic (link "../quick/index.html" "An Introduction to PLT Scheme with Pictures")))
|
||||
|
||||
(define MzScheme
|
||||
(italic (link "../reference/index.html" "PLT Scheme Reference Manual")))
|
||||
(italic (link "../reference/index.html" "PLT Scheme Reference")))
|
||||
|
||||
(define HtDP
|
||||
(italic (link "http://www.htdp.org" "How to Design Programs")))
|
||||
|
|
|
@ -12,7 +12,7 @@ general information about continuation marks.
|
|||
|
||||
The list of continuation marks for a key @scheme[_k] and a continuation
|
||||
@scheme[_C] that extends @cont[0] is defined as follows:
|
||||
%
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{If @scheme[_C] is an empty continuation, then the mark list is
|
||||
|
|
|
@ -951,7 +951,7 @@ procedures.
|
|||
(write-special 'hello /dev/null-out)
|
||||
(sync (write-bytes-avail-evt #"hello" /dev/null-out))
|
||||
|
||||
;; A part that accumulates bytes as characters in a list,
|
||||
;; A port that accumulates bytes as characters in a list,
|
||||
;; but not in a thread-safe way:
|
||||
(define accum-list null)
|
||||
(define accumulator/not-thread-safe
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
|
||||
@title[#:style 'toc]{Core Datatypes and Procedures}
|
||||
@title[#:style 'toc]{Core Datatypes}
|
||||
|
||||
Each of the built-in datatypes comes with a set of procedures for
|
||||
manipulating members of the datatype.
|
||||
|
@ -90,6 +90,9 @@ ephemeron key (see @secref["mz:ephemerons"]).
|
|||
|
||||
@examples[(gensym "apple")]
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
@include-section["regexps.scrbl"]
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
@section[#:tag "keywords"]{Keywords}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
|
||||
@title[#:tag "mz:define-struct"]{Structure Types: @scheme[define-struct]}
|
||||
@title[#:tag "mz:define-struct"]{Defining Structure Types: @scheme[define-struct]}
|
||||
|
||||
@guideintro["guide:define-struct"]{@scheme[define-struct]}
|
||||
|
||||
|
@ -22,8 +22,6 @@
|
|||
[field-option #:immutable
|
||||
#:auto])]{
|
||||
|
||||
@moreref["mz:structures"]{structures}
|
||||
|
||||
Creates a new @techlink{structure type}, and binds transformers and
|
||||
variables related to the new @tech{structure type}. A
|
||||
@scheme[define-struct] form with @math{n} @scheme[field]s defines
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
|
||||
@title[#:tag "mz:derived-syntax" #:style 'toc]{Derived Syntactic Forms}
|
||||
|
||||
@local-table-of-contents[]
|
||||
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:cond"]{Conditionals: @scheme[cond]}
|
||||
|
||||
@guideintro["guide:cond"]{@scheme[cond]}
|
||||
|
||||
@defform/subs[#:literals (else =>)
|
||||
(cond cond-clause ...)
|
||||
([cond-clause [test-expr then-expr ...+]
|
||||
[else then-expr ...+]
|
||||
[test-expr => proc-expr]
|
||||
[test-expr]])]{
|
||||
|
||||
A @scheme[cond-clause] that starts with @scheme[else] must be the last
|
||||
@scheme[cond-clause].
|
||||
|
||||
If no @scheme[cond-clause]s are present, the result is @|void-const|.
|
||||
|
||||
If only a @scheme[[else then-expr ...+]] is present, then the
|
||||
@scheme[then-expr]s are evaluated. The results from all but the last
|
||||
@scheme[then-expr] are ignored. The results of the last
|
||||
@scheme[then-expr], which is in tail position with respect to the
|
||||
@scheme[cond] form, provides the result for the whole @scheme[cond]
|
||||
form.
|
||||
|
||||
Otherwise, the first @scheme[test-expr] is evaluated. If it produces
|
||||
@scheme[#f], then the result is the same as a @scheme[cond] form with
|
||||
the remaining @scheme[cond-clause]s, in tail position with respect to
|
||||
the original @scheme[cond] form. Otherwise, evaluation depends on the
|
||||
form of the @scheme[cond-clause]:
|
||||
|
||||
@specsubform[[test-expr then-expr ...+]]{The @scheme[then-expr]s are
|
||||
evaluated in order, and the results from all but the last
|
||||
@scheme[then-expr] are ignored. The results of the last
|
||||
@scheme[then-expr], which is in tail position with respect to the
|
||||
@scheme[cond] form, provides the result for the whole @scheme[cond]
|
||||
form.}
|
||||
|
||||
@specsubform[#:literals (=>) [test-expr => proc-expr]]{The @scheme[proc-expr] is
|
||||
evaluated, and it must produce a procedure that accepts on argument,
|
||||
otherwise the @exnraise[exn:fail:contract]. The procedure is applied
|
||||
to the result of @scheme[test-expr] in tail position with respect to
|
||||
the @scheme[cond] expression.}
|
||||
|
||||
@specsubform[[test-expr]]{The result of the @scheme[test-expr] is
|
||||
returned as the result of the @scheme[cond] form. The
|
||||
@scheme[test-expr] is not in tail position.}
|
||||
|
||||
@examples[
|
||||
(cond)
|
||||
(cond
|
||||
[else 5])
|
||||
(cond
|
||||
[(positive? -5) (error "doesn't get here")]
|
||||
[(zero? -5) (error "doesn't get here, either")]
|
||||
[(positive? 5) 'here])
|
||||
(cond
|
||||
[(member 2 '(1 2 3)) => (lambda (l) (map - l))])
|
||||
(cond
|
||||
[(member 2 '(1 2 3))])
|
||||
]}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:and+or"]{Boolean Combination: @scheme[and] and @scheme[or]}
|
||||
|
||||
@guideintro["guide:and+or"]{@scheme[and] and @scheme[or]}
|
||||
|
||||
@defform[(and expr ...)]{
|
||||
|
||||
If no @scheme[expr]s are provided, then result is @scheme[#f].
|
||||
|
||||
If a single @scheme[expr] is provided, then it is in tail position, so
|
||||
the results of the @scheme[and] expression are the results of the
|
||||
@scheme[expr].
|
||||
|
||||
Otherwise, the first @scheme[expr] is evaluated. If it produces
|
||||
@scheme[#f], the result of the @scheme[and] expression is
|
||||
@scheme[#f]. Otherwise, the result is the same as an @scheme[and]
|
||||
expression with the remaining @scheme[expr]s in tail position with
|
||||
respect to the original @scheme[and] form.
|
||||
|
||||
@examples[
|
||||
(and)
|
||||
(and 1)
|
||||
(and (values 1 2))
|
||||
(and #f (error "doesn't get here"))
|
||||
(and #t 5)
|
||||
]}
|
||||
|
||||
@defform[(or expr ...)]{
|
||||
|
||||
If no @scheme[expr]s are provided, then result is @scheme[#t].
|
||||
|
||||
If a single @scheme[expr] is provided, then it is in tail position, so
|
||||
the results of the @scheme[and] expression are the results of the
|
||||
@scheme[expr].
|
||||
|
||||
Otherwise, the first @scheme[expr] is evaluated. If it produces a
|
||||
value other than @scheme[#f], that result is the result of the
|
||||
@scheme[or] expression. Otherwise, the result is the same as an
|
||||
@scheme[or] expression with the remaining @scheme[expr]s in tail
|
||||
position with respect to the original @scheme[or] form.
|
||||
|
||||
@examples[
|
||||
(or)
|
||||
(or 1)
|
||||
(or (values 1 2))
|
||||
(or 5 (error "doesn't get here"))
|
||||
(or #f 5)
|
||||
]}
|
||||
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:when+unless"]{Guarded Evaluation: @scheme[when] and @scheme[unless]}
|
||||
|
||||
@guideintro["guide:when+unless"]{@scheme[when] and @scheme[unless]}
|
||||
|
||||
@defform[(when test-expr expr ...)]{
|
||||
|
||||
Evaluates the @scheme[text-expr]. If the result is any value other
|
||||
than @scheme[#f], the @scheme[expr]s are evaluated, and the results
|
||||
are ignored. No @scheme[expr] is in tail position with respect to the
|
||||
@scheme[when] form.
|
||||
|
||||
@examples[
|
||||
(when (positive? -5)
|
||||
(display "hi"))
|
||||
(when (positive? 5)
|
||||
(display "hi")
|
||||
(display " there"))
|
||||
]}
|
||||
|
||||
@defform[(unless test-expr expr ...)]{
|
||||
|
||||
Equivalent to @scheme[(when (not test-expr) expr ...)].
|
||||
|
||||
@examples[
|
||||
(unless (positive? 5)
|
||||
(display "hi"))
|
||||
(unless (positive? -5)
|
||||
(display "hi")
|
||||
(display " there"))
|
||||
]}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@include-section["define-struct.scrbl"]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@include-section["for.scrbl"]
|
|
@ -281,45 +281,53 @@ position with respect to the @scheme[with-handlers*] form.}
|
|||
|
||||
@defstruct[exn ([message string?]
|
||||
[continuation-marks continuation-mark-set?])
|
||||
#:immutable]{
|
||||
#:immutable
|
||||
#:inspector #f]{
|
||||
|
||||
The base @tech{structure type} for exceptions. The @scheme[message]
|
||||
field contains an error message, and the @scheme[continuation-marks]
|
||||
field contains the value produced by @scheme[(current-continuation-marks)]
|
||||
immediately before the exception was raised.}
|
||||
|
||||
@defstruct[(exn:fail exn) ()]{
|
||||
@defstruct[(exn:fail exn) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for exceptions that represent errors, as opposed to
|
||||
@scheme[exn:break].}
|
||||
|
||||
|
||||
@defstruct[(exn:fail:contract exn:fail) ()]{
|
||||
@defstruct[(exn:fail:contract exn:fail) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for errors from the inappropriate run-time use of a function or
|
||||
syntactic form.}
|
||||
|
||||
@defstruct[(exn:fail:contract:arity exn:fail:contract) ()]{
|
||||
@defstruct[(exn:fail:contract:arity exn:fail:contract) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised when a procedure is applied to the wrong number of arguments.}
|
||||
|
||||
@defstruct[(exn:fail:contract:divide-by-zero exn:fail:contract) ()]{
|
||||
@defstruct[(exn:fail:contract:divide-by-zero exn:fail:contract) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for division by exact zero.}
|
||||
|
||||
@defstruct[(exn:fail:contract:continuation exn:fail:contract) ()]{
|
||||
@defstruct[(exn:fail:contract:continuation exn:fail:contract) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised when a continuation is applied where the jump would cross a
|
||||
continuation barrier.}
|
||||
|
||||
@defstruct[(exn:fail:contract:variable exn:fail:contract) ([id symbol?])
|
||||
#:immutable]{
|
||||
#:immutable
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for a reference to a not-yet-defined @tech{top-level variable}
|
||||
or @tech{module-level variable}.}
|
||||
|
||||
@defstruct[(exn:fail:syntax exn:fail) ([exprs (listof syntax?)])
|
||||
#:immutable]{
|
||||
#:immutable
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for a syntax error that is not a @scheme[read] error. The
|
||||
@scheme[exprs] indicate the relevant source expressions,
|
||||
|
@ -327,61 +335,103 @@ least-specific to most-specific.}
|
|||
|
||||
|
||||
@defstruct[(exn:fail:read exn:fail) ([srclocs (listof srcloc?)])
|
||||
#:immutable]{
|
||||
#:immutable
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for a @scheme[read] error. The @scheme[srclocs] indicate the
|
||||
relevant source expressions.}
|
||||
|
||||
@defstruct[(exn:fail:read:eof exn:fail:read) ()]{
|
||||
@defstruct[(exn:fail:read:eof exn:fail:read) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for a @scheme[read] error, specifically when the error is due
|
||||
to an unexpected end-of-file.}
|
||||
|
||||
@defstruct[(exn:fail:read:non-char exn:fail:read) ()]{
|
||||
@defstruct[(exn:fail:read:non-char exn:fail:read) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for a @scheme[read] error, specifically when the error is due
|
||||
to an unexpected non-character (i.e., ``special'') element in the
|
||||
input stream.}
|
||||
|
||||
@defstruct[(exn:fail:filesystem exn:fail) ()]{
|
||||
@defstruct[(exn:fail:filesystem exn:fail) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for an error related to the filesystem (such as a file not
|
||||
found).}
|
||||
|
||||
@defstruct[(exn:fail:filesystem:exists exn:fail:filesystem) ()]{
|
||||
@defstruct[(exn:fail:filesystem:exists exn:fail:filesystem) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for an error when attempting to create a file that exists
|
||||
already.}
|
||||
|
||||
@defstruct[(exn:fail:filesystem:version exn:fail:filesystem) ()]{
|
||||
@defstruct[(exn:fail:filesystem:version exn:fail:filesystem) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for a version-mismatch error when loading an extension.}
|
||||
|
||||
|
||||
@defstruct[(exn:fail:network exn:fail) ()]{
|
||||
@defstruct[(exn:fail:network exn:fail) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for TCP and UDP errors.}
|
||||
|
||||
|
||||
@defstruct[(exn:fail:out-of-memory exn:fail) ()]{
|
||||
@defstruct[(exn:fail:out-of-memory exn:fail) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for an error due to insufficient memory, in cases where sufficient
|
||||
memory is at least available for raising the exception.}
|
||||
|
||||
@defstruct[(exn:fail:unsupported exn:fail) ()]{
|
||||
@defstruct[(exn:fail:unsupported exn:fail) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for an error due to an unsupported feature on the current
|
||||
platform or configuration.}
|
||||
|
||||
@defstruct[(exn:fail:user exn:fail) ()]{
|
||||
@defstruct[(exn:fail:user exn:fail) ()
|
||||
#:inspector #f]{
|
||||
|
||||
Raised for errors that are intended to be seen by end-users. In
|
||||
particular, the default error printer does not show the program
|
||||
context when printing the error message.}
|
||||
|
||||
@defstruct[(exn:break exn) ([continuation continuation?])
|
||||
#:immutable]{
|
||||
#:immutable
|
||||
#:inspector #f]{
|
||||
|
||||
Raised asynchronously (when enabled) in response to a break request.
|
||||
The @scheme[continuation] field can be used by a handler to resume the
|
||||
interrupted computation.}
|
||||
|
||||
|
||||
|
||||
@defstruct[srcloc ([source any/c]
|
||||
[line (or/c positive-exact-integer? false/c)]
|
||||
[column (or/c nonnegative-exact-integer? false/c)]
|
||||
[position (or/c positive-exact-integer? false/c)]
|
||||
[span (or/c nonnegative-exact-integer? false/c)])
|
||||
#:immutable
|
||||
#:inspector #f]{
|
||||
|
||||
The fields of an @scheme[srcloc] instance are as follows:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@scheme[source] --- An arbitrary value identifying the source,
|
||||
often a path (see @secref["mz:pathutils"]).}
|
||||
|
||||
@item{@scheme[line] --- The line number (counts from 1) or
|
||||
@scheme[#f] (unknown).}
|
||||
|
||||
@item{@scheme[column] --- The column number (counts from 0) or
|
||||
@scheme[#f] (unknown).}
|
||||
|
||||
@item{@scheme[position] --- The starting position (counts from 1) or
|
||||
@scheme[#f] (unknown).}
|
||||
|
||||
@item{@scheme[span] --- The number of covered positions (counts from
|
||||
0) or @scheme[#f] (unknown).}
|
||||
|
||||
}}
|
||||
|
|
|
@ -7,3 +7,8 @@
|
|||
@local-table-of-contents[]
|
||||
|
||||
@include-section["ports.scrbl"]
|
||||
@include-section["string-input.scrbl"]
|
||||
@include-section["string-output.scrbl"]
|
||||
@include-section["read.scrbl"]
|
||||
@include-section["write.scrbl"]
|
||||
@include-section["reader.scrbl"]
|
||||
|
|
|
@ -634,14 +634,14 @@ escape-continuation aborts can cross continuation barriers.
|
|||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:thread-model"]{Threads}
|
||||
|
||||
Scheme supports multiple, pre-emptive threads of evaluation. In terms
|
||||
of the evaluation model, this means that each step in evaluation
|
||||
actually consists of multiple concurrent expressions, rather than a
|
||||
single expression. The expressions all share the same objects and
|
||||
top-level variables, so that they can communicate through shared
|
||||
state. Most evaluation steps involve a single step in a single
|
||||
expression, but certain synchronization primitives require multiple
|
||||
threads to progress together in one step.
|
||||
Scheme supports multiple, pre-emptive @deftech{threads} of
|
||||
evaluation. In terms of the evaluation model, this means that each
|
||||
step in evaluation actually consists of multiple concurrent
|
||||
expressions, rather than a single expression. The expressions all
|
||||
share the same objects and top-level variables, so that they can
|
||||
communicate through shared state. Most evaluation steps involve a
|
||||
single step in a single expression, but certain synchronization
|
||||
primitives require multiple threads to progress together in one step.
|
||||
|
||||
In addition to the state that is shared among all threads, each thread
|
||||
has its own private state that is accessed through @deftech{thread
|
||||
|
|
|
@ -37,9 +37,6 @@ the port becomes unknown, and line and column tacking is disabled.
|
|||
Return-linefeed combinations are treated as a single character
|
||||
position only when line and column counting is enabled.
|
||||
|
||||
Certain kinds of exceptions (see @secref["mz:exns"]) encapsulate
|
||||
source-location information using a @scheme[srcloc] structure.
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
|
||||
@defproc[(port-count-lines! [port port?]) void?]{
|
||||
|
@ -64,32 +61,3 @@ read from or written to the port, but if line/character counting is
|
|||
enabled for @scheme[port], the column and position results can
|
||||
decrease after reading or writing a byte that ends a UTF-8 encoding
|
||||
sequence.}
|
||||
|
||||
@defstruct[srcloc ([source any/c]
|
||||
[line (or/c positive-exact-integer? false/c)]
|
||||
[column (or/c nonnegative-exact-integer? false/c)]
|
||||
[position (or/c positive-exact-integer? false/c)]
|
||||
[span (or/c nonnegative-exact-integer? false/c)])
|
||||
#:immutable
|
||||
#:inspector #f]{
|
||||
|
||||
The fields of an @scheme[srcloc] instance are as follows:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@scheme[source] --- An arbitrary value identifying the source,
|
||||
often a path (see @secref["mz:pathutils"]).}
|
||||
|
||||
@item{@scheme[line] --- The line number (counts from 1) or
|
||||
@scheme[#f] (unknown).}
|
||||
|
||||
@item{@scheme[column] --- The column number (counts from 0) or
|
||||
@scheme[#f] (unknown).}
|
||||
|
||||
@item{@scheme[position] --- The starting position (counts from 1) or
|
||||
@scheme[#f] (unknown).}
|
||||
|
||||
@item{@scheme[span] --- The number of covered positions (counts from
|
||||
0) or @scheme[#f] (unknown).}
|
||||
|
||||
}}
|
||||
|
|
|
@ -53,5 +53,5 @@ terminal, @scheme[#f] otherwise.}
|
|||
@defthing[eof eof-object?]{A value (distinct from all other values)
|
||||
that represents an end-of-file.}
|
||||
|
||||
@defproc[(eof-object [a any/c]) boolean?]{Returns @scheme[#t] is
|
||||
@defproc[(eof-object? [a any/c]) boolean?]{Returns @scheme[#t] is
|
||||
@scheme[v] is @scheme[eof], @scheme[#f] otherwise.}
|
||||
|
|
|
@ -1,722 +1,198 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
@require[(lib "bnf.ss" "scribble")]
|
||||
@require["reader-example.ss"]
|
||||
@begin[
|
||||
(define (ilitchar s)
|
||||
(litchar s))
|
||||
(define (nunterm s)
|
||||
(nonterm s (subscript "n")))
|
||||
(define (sub n) (subscript n))
|
||||
(define (nonalpha)
|
||||
@elem{; the next character must not be @schemelink[char-alphabetic?]{alphabetic}.})
|
||||
]
|
||||
@define[(graph-tag) @kleenerange[1 8]{@nonterm{digit@sub{10}}}]
|
||||
@define[(graph-defn) @elem{@litchar{#}@graph-tag[]@litchar{=}}]
|
||||
@define[(graph-ref) @elem{@litchar{#}@graph-tag[]@litchar{#}}]
|
||||
|
||||
@title[#:tag "mz:reader"]{Reading}
|
||||
|
||||
Scheme's reader is a recursive-descent parser that can be configured
|
||||
through a @seclink["mz:readtables"]{readtable} and various other
|
||||
@tech{parameters}. This section describes the reader's parsing when
|
||||
using the default readtable.
|
||||
|
||||
Reading from a stream produces one @defterm{datum}. If the result
|
||||
datum is a compound value, then reading the datum typically requires
|
||||
the reader to call itself recursively to read the component data.
|
||||
|
||||
The reader can be invoked in either of two modes: @scheme[read] mode,
|
||||
or @scheme[read-syntax] mode. In @scheme[read-syntax] mode, the result
|
||||
is always a @techlink{syntax object} that includes
|
||||
source-location and (initially empty) lexical information wrapped
|
||||
around the sort of datum that @scheme[read] mode would produce. In the
|
||||
case of pairs, vectors, and boxes, morever, the content is also
|
||||
wrapped recursively as a syntax object. Unless specified otherwise,
|
||||
this section describes the reader's behavior in @scheme[read] mode,
|
||||
and @scheme[read-syntax] mode does the same modulo wrapping the final
|
||||
result.
|
||||
|
||||
Reading is defined in terms of Unicode characters; see
|
||||
@secref["mz:char-input"] for information on how a byte stream is converted
|
||||
to a character stream.
|
||||
|
||||
@section[#:tag "mz:default-readtable-dispatch"]{Delimiters and Dispatch}
|
||||
|
||||
Along with @schemelink[char-whitespace?]{whitespace}, the following
|
||||
characters are @defterm{delimiters}:
|
||||
|
||||
@t{
|
||||
@hspace[2] @ilitchar{(} @ilitchar{)} @ilitchar{[} @ilitchar{]}
|
||||
@ilitchar["["] @ilitchar["]"]
|
||||
@ilitchar{"} @ilitchar{,} @ilitchar{'} @ilitchar{`}
|
||||
@ilitchar{;}
|
||||
}
|
||||
|
||||
A delimited sequence that starts with any other character is typically
|
||||
parsed as either a symbol or number, but a few non-delimiter
|
||||
characters play special roles:
|
||||
|
||||
@itemize{
|
||||
@title{Reading}
|
||||
|
||||
@defproc[(read [in input-port? (current-input-port)]) any]{
|
||||
|
||||
Reads and returns a single @tech{datum} from @scheme[in]. If
|
||||
@scheme[in] has a handler associated to it via
|
||||
@scheme[port-read-handler], then the handler is called. Otherwise, the
|
||||
default reader is used, as parameterized by the
|
||||
@scheme[current-readtable] parameter, as well as many other
|
||||
parameters.
|
||||
|
||||
See @secref["mz:reader"] for information on the default reader.}
|
||||
|
||||
@defproc[(read-syntax [source-name any/c (object-name in)]
|
||||
[in input-port? (current-input-port)])
|
||||
(or/c syntax? eof-object?)]{
|
||||
|
||||
Like @scheme[read], but produces a @tech{syntax object} with
|
||||
source-location information. The @scheme[source-name] is used as the
|
||||
source field of the syntax object; it can be an arbitrary value, but
|
||||
it should generally be a path for the source file.
|
||||
|
||||
See @secref["mz:reader"] for information on the default reader in
|
||||
@scheme[read-syntax] mode.}
|
||||
|
||||
@defproc[(read/recursive [in input-port? (current-input-port)]
|
||||
[start (or/c character? false/c) #f]
|
||||
[readtable readtable? (current-readtable)]
|
||||
[graph? any/c #f])
|
||||
any]{
|
||||
|
||||
Similar to calling @scheme[read], but normally used during the dynamic
|
||||
extent of @scheme[read] within a reader-extension procedure (see
|
||||
@secref["mz:reader-procs"]). The main effect of using
|
||||
@scheme[read/recursive] instead of @scheme[read] is that
|
||||
graph-structure annotations (see @secref["mz:sexpressions"]) in the
|
||||
nested read are considered part of the overall read, at least when the
|
||||
@scheme[graph?] argument is true; since the result is wrapped in a
|
||||
placeholder, however, it is not directly inspectable.
|
||||
|
||||
If @scheme[start] is provided and not @scheme[#f], it is effectively
|
||||
prefixed to the beginning of @scheme[in]'s stream for the read. (To
|
||||
prefix multiple characters, use @scheme[input-port-append].)
|
||||
|
||||
The @scheme[readtable] argument is used for top-level parsing to
|
||||
satisfy the read request; recursive parsing within the read (e.g., to
|
||||
read the elements of a list) instead uses the current readtable as
|
||||
determined by the @scheme[current-readtable] parameter. A reader
|
||||
macro might call @scheme[read/recursive] with a character and
|
||||
readtable to effectively invoke the readtable's behavior for the
|
||||
character. If @scheme[readtable] is @scheme[#f], the default
|
||||
readtable is used for top-level parsing.
|
||||
|
||||
When @scheme[graph?] is @scheme[#f], graph structure annotations in
|
||||
the read datum are local to the datum.
|
||||
|
||||
When called within the dynamic extent of @scheme[read], the
|
||||
@scheme[read/recursive] procedure produces either an opaque
|
||||
placeholder value, a special-comment value, or an end-of-file. The
|
||||
result is a special-comment value (see @secref["mz:special-comments"])
|
||||
when the input stream's first non-whitespace content parses as a
|
||||
comment. The result is end-of-file when @scheme[read/recursive]
|
||||
encounters an end-of-file. Otherwise, the result is a placeholder that
|
||||
protects graph references that are not yet resolved. When this
|
||||
placeholder is returned within an S-expression that is produced by any
|
||||
reader-extension procedure (see @secref["mz:reader-procs"]) for the
|
||||
same outermost @scheme[read], it will be replaced with the actual read
|
||||
value before the outermost @scheme[read] returns.
|
||||
|
||||
See @secref["mz:readtables"] for an extended example that uses
|
||||
@scheme[read/recursive].}
|
||||
|
||||
@defproc[(read-syntax/recursive [source-name any/c (object-name in)]
|
||||
[in input-port? (current-input-port)]
|
||||
[start (or/c character? false/c) #f]
|
||||
[readtable readtable? (current-readtable)]
|
||||
[graph? any/c #f])
|
||||
any]{
|
||||
|
||||
Analogous to calling @scheme[read/recursive], but the resulting value
|
||||
encapsulates S-expression structure with source-location
|
||||
information. As with @scheme[read/recursive], when
|
||||
@scheme[read-syntax/recursive] is used within the dynamic extent of
|
||||
@scheme[read-syntax], the result of from
|
||||
@scheme[read-syntax/recursive] is either a special-comment value,
|
||||
end-of-file, or opaque graph-structure placeholder (not a syntax
|
||||
object). The placeholder can be embedded in an S-expression or syntax
|
||||
object returned by a reader macro, etc., and it will be replaced with
|
||||
the actual syntax object before the outermost @scheme[read-syntax]
|
||||
returns.
|
||||
|
||||
Using @scheme[read/recursive] within the dynamic extent of
|
||||
@scheme[read-syntax] does not allow graph structure for reading to be
|
||||
included in the outer @scheme[read-syntax] parsing, and neither does
|
||||
using @scheme[read-syntax/recursive] within the dynamic extent of
|
||||
@scheme[read]. In those cases, @scheme[read/recursive] and
|
||||
@scheme[read-syntax/recursive] produce results like @scheme[read] and
|
||||
@scheme[read-syntax], except that a special-comment value is returned
|
||||
when the input stream starts with a comment (after whitespace).
|
||||
|
||||
See @secref["mz:readtables"] for an extended example that uses
|
||||
@scheme[read-syntax/recursive].}
|
||||
|
||||
|
||||
@defboolparam[read-case-sensitive on?]{
|
||||
|
||||
A parameter that controls parsing and printing of symbols. When this
|
||||
parameter's value is @scheme[#f], the reader case-folds symbols (e.g.,
|
||||
producing @scheme['hi] when the input is any one of \litchar{hi},
|
||||
\litchar{Hi}, \litchar{HI}, or \litchar{hI}). The parameter also
|
||||
affects the way that @scheme[write] prints symbols containing
|
||||
uppercase characters; if the parameter's value is @scheme[#f], then
|
||||
symbols are printed with uppercase characters quoted by a
|
||||
@litchar["\\"] or @litchar["|"]. The parameter's value is overridden by
|
||||
quoting @litchar["\\"] or @litchar["|"] vertical-bar quotes and the
|
||||
@litchar{#cs} and @litchar{#ci} prefixes; see
|
||||
@secref["mz:parse-symbol"] for more information. While a module is
|
||||
loaded, the parameter is set to @scheme[#t] (see
|
||||
@secref["mz:modloadhandler"]).}
|
||||
|
||||
@defboolparam[read-square-bracket-as-paren on?]{
|
||||
|
||||
A parameter that controls whether @litchar["["] and @litchar["]"]
|
||||
are treated as parentheses. See @secref["mz:parse-pair"] for more
|
||||
information.}
|
||||
|
||||
@defboolparam[read-curly-brace-as-paren on?]{
|
||||
|
||||
A parameter that controls whether @litchar["{"] and @litchar["}"]
|
||||
are treated as parentheses. See @secref["mz:parse-pair"] for more
|
||||
information.}
|
||||
|
||||
@defboolparam[read-accept-box on?]{
|
||||
|
||||
A parameter that controls parsing @litchar{#&} input. See
|
||||
@secref["mz:parse-box"] for more information.}
|
||||
|
||||
@item{@litchar{#} has a special meaning as an initial character in a
|
||||
delimited sequence; its meaning depends on the characters that
|
||||
follow; see below.}
|
||||
@defboolparam[read-accept-compiled on?]{
|
||||
|
||||
@item{@as-index{@litchar["|"]} starts a subsequence of characters to
|
||||
be included verbatim in the delimited sequence (i.e,. they are
|
||||
never treated as delimiters, and they are not case-folded when
|
||||
case-insensitivity is enabled); the subsequence is terminated
|
||||
by another @litchar["|"], and neither the initial nor
|
||||
terminating @litchar["|"] is part of the subsequence.}
|
||||
|
||||
@item{@as-index{@litchar["\\"]} outside of a @litchar["|"] pair causes
|
||||
the folowing character to be included verbatim in a delimited
|
||||
sequence.}
|
||||
|
||||
}
|
||||
|
||||
More precisely, after skipping whitespace, the reader dispatches based
|
||||
on the next character or characters in the input stream as follows:
|
||||
|
||||
@dispatch-table[
|
||||
|
||||
@dispatch[@litchar{(}]{starts a pair or list; see @secref["mz:parse-pair"]}
|
||||
@dispatch[@litchar{[}]{starts a pair or list; see @secref["mz:parse-pair"]}
|
||||
@dispatch[@litchar["{"]]{starts a pair or list; see @secref["mz:parse-pair"]}
|
||||
|
||||
@dispatch[@litchar{)}]{matches @litchar{(} or raises @Exn{exn:fail:read}}
|
||||
@dispatch[@litchar{]}]{matches @litchar{[} or raises @Exn{exn:fail:read}}
|
||||
@dispatch[@litchar["}"]]{matches @litchar["{"] or raises @Exn{exn:fail:read}}
|
||||
|
||||
@dispatch[@litchar{"}]{starts a string; see @secref["mz:parse-string"]}
|
||||
@dispatch[@litchar{,}]{starts a quote; see @secref["mz:parse-quote"]}
|
||||
@dispatch[@litchar{`}]{starts a quasiquote; see @secref["mz:parse-quote"]}
|
||||
@dispatch[@litchar{,}]{starts an unquote or splicing unquote; see @secref["mz:parse-quote"]}
|
||||
|
||||
@dispatch[@litchar{;}]{starts a line comment; see @secref["mz:parse-comment"]}
|
||||
|
||||
@dispatch[@cilitchar{#t}]{true; see @secref["mz:parse-boolean"]}
|
||||
@dispatch[@cilitchar{#f}]{false; see @secref["mz:parse-boolean"]}
|
||||
|
||||
@dispatch[@litchar{#(}]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
@dispatch[@litchar{#[}]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
@dispatch[@litchar["#{"]]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
|
||||
@dispatch[@litchar["#\\"]]{starts a character; see @secref["mz:parse-character"]}
|
||||
|
||||
@dispatch[@litchar{#"}]{starts a byte string; see @secref["mz:parse-string"]}
|
||||
@dispatch[@litchar{#%}]{starts a symbol; see @secref["mz:parse-symbol"]}
|
||||
@dispatch[@litchar{#:}]{starts a keyword; see @secref["mz:parse-keyword"]}
|
||||
@dispatch[@litchar{#&}]{starts a box; see @secref["mz:parse-box"]}
|
||||
|
||||
@dispatch[@litchar["#|"]]{starts a block comment; see @secref["mz:parse-comment"]}
|
||||
@dispatch[@litchar["#;"]]{starts an S-expression comment; see @secref["mz:parse-comment"]}
|
||||
@dispatch[@litchar{#,}]{starts a syntax quote; see @secref["mz:parse-quote"]}
|
||||
@dispatch[@litchar["#! "]]{starts a line comment; see @secref["mz:parse-comment"]}
|
||||
@dispatch[@litchar["#!/"]]{starts a line comment; see @secref["mz:parse-comment"]}
|
||||
@dispatch[@litchar{#`}]{starts a syntax quasiquote; see @secref["mz:parse-quote"]}
|
||||
@dispatch[@litchar{#,}]{starts an syntax unquote or splicing unquote; see @secref["mz:parse-quote"]}
|
||||
@dispatch[@litchar["#~"]]{starts compiled code; see @secref["compilation"]}
|
||||
|
||||
@dispatch[@cilitchar{#i}]{starts a number; see @secref["mz:parse-number"]}
|
||||
@dispatch[@cilitchar{#e}]{starts a number; see @secref["mz:parse-number"]}
|
||||
@dispatch[@cilitchar{#x}]{starts a number; see @secref["mz:parse-number"]}
|
||||
@dispatch[@cilitchar{#o}]{starts a number; see @secref["mz:parse-number"]}
|
||||
@dispatch[@cilitchar{#d}]{starts a number; see @secref["mz:parse-number"]}
|
||||
@dispatch[@cilitchar{#b}]{starts a number; see @secref["mz:parse-number"]}
|
||||
|
||||
@dispatch[@cilitchar["#<<"]]{starts a string; see @secref["mz:parse-string"]}
|
||||
|
||||
@dispatch[@litchar{#rx}]{starts a regular expression; see @secref["mz:parse-regexp"]}
|
||||
@dispatch[@litchar{#px}]{starts a regular expression; see @secref["mz:parse-regexp"]}
|
||||
|
||||
@dispatch[@cilitchar{#ci}]{switches case sensitivity; see @secref["mz:parse-symbol"]}
|
||||
@dispatch[@cilitchar{#cs}]{switches case sensitivity; see @secref["mz:parse-symbol"]}
|
||||
|
||||
@dispatch[@cilitchar["#sx"]]{starts a Scheme expression; see @secref["mz:parse-honu"]}
|
||||
|
||||
@dispatch[@litchar["#hx"]]{starts a Honu expression; see @secref["mz:parse-honu"]}
|
||||
@dispatch[@litchar["#honu"]]{starts a Honu module; see @secref["mz:parse-honu"]}
|
||||
|
||||
@dispatch[@litchar["#hash"]]{starts a hash table; see @secref["mz:parse-hashtable"]}
|
||||
|
||||
@dispatch[@litchar["#reader"]]{starts a reader extension use; see @secref["mz:parse-reader"]}
|
||||
|
||||
@dispatch[@elem{@litchar{#}@kleeneplus{@nonterm{digit@sub{10}}}@litchar{(}}]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
@dispatch[@elem{@litchar{#}@kleeneplus{@nonterm{digit@sub{10}}}@litchar{[}}]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
@dispatch[@elem{@litchar{#}@kleeneplus{@nonterm{digit@sub{10}}}@litchar["{"]}]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
@dispatch[@graph-defn[]]{binds a graph tag; see @secref["mz:parse-graph"]}
|
||||
@dispatch[@graph-ref[]]{uses a graph tag; see @secref["mz:parse-graph"]}
|
||||
|
||||
@dispatch[@italic{otherwise}]{starts a symbol; see @secref["mz:parse-symbol"]}
|
||||
|
||||
]
|
||||
|
||||
|
||||
@section[#:tag "mz:parse-symbol"]{Reading Symbols}
|
||||
|
||||
@guideintro["guide:symbols"]{the syntax of symbols}
|
||||
|
||||
A sequence that does not start with a delimiter or @litchar{#} is
|
||||
parsed as either a symbol or a number (see @secref["mz:parse-number"]),
|
||||
except that @litchar{.} by itself is never parsed as a symbol or
|
||||
character. A @as-index{@litchar{#%}} also starts a symbol. A successful
|
||||
number parse takes precedence over a symbol parse.
|
||||
|
||||
When the @scheme[read-case-sensitive] @tech{parameter} is set to @scheme[#f],
|
||||
characters in the sequence that are not quoted by @litchar["|"] or
|
||||
@litchar["\\"] are first case-normalized. If the reader encounters
|
||||
@as-index{@litchar{#ci}}, @litchar{#CI}, @litchar{#Ci}, or @litchar{#cI},
|
||||
then it recursively reads the following datum in
|
||||
case-insensitive mode. If the reader encounters @as-index{@litchar{#cs}},
|
||||
@litchar{#CS}, @litchar{#Cs}, or @litchar{#cS}, then recursively reads
|
||||
the following datum in case-sensitive mode.
|
||||
|
||||
@reader-examples[#:symbols? #f
|
||||
"Apple"
|
||||
"Ap#ple"
|
||||
"Ap ple"
|
||||
"Ap| |ple"
|
||||
"Ap\\ ple"
|
||||
"#ci Apple"
|
||||
"#ci |A|pple"
|
||||
"#ci \\Apple"
|
||||
"#ci#cs Apple"
|
||||
"#%Apple"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-number"]{Reading Numbers}
|
||||
|
||||
@guideintro["guide:numbers"]{the syntax of numbers}
|
||||
|
||||
@index['("numbers" "parsing")]{A} sequence that does not start with a
|
||||
delimiter is parsed as a number when it matches the following grammar
|
||||
case-insenstively for @nonterm{number@sub{10}} (decimal), where
|
||||
@metavar{n} is a meta-meta-variable in the grammar.
|
||||
|
||||
A number is optionally prefixed by an exactness specifier,
|
||||
@as-index{@litchar{#e}} (exact) or @as-index{@litchar{#i}} (inexact),
|
||||
which specifies its parsing as an exact or inexact number; see
|
||||
@secref["mz:numbers"] for information on number exactness. As the
|
||||
non-terminal names suggest, a number that has no exactness specifier
|
||||
and matches only @nunterm{inexact-number} is normally parsed as an
|
||||
inexact number, otherwise it is parsed as an excat number. If the
|
||||
@scheme[read-decimal-as-inexact] @tech{parameter} is set to @scheme[#f], then
|
||||
all numbers without an exactness specifier are instead parsed as
|
||||
exact.
|
||||
|
||||
If the reader encounters @as-index{@litchar{#b}} (binary),
|
||||
@as-index{@litchar{#o}} (octal), @as-index{@litchar{#d}} (decimal), or
|
||||
@as-index{@litchar{#x}} (hexadecimal), it must be followed by a
|
||||
sequence that is terminated by a delimiter or end-of-file, and that
|
||||
matches the @nonterm{general-number@sub{2}},
|
||||
@nonterm{general-number@sub{8}}, @nonterm{general-number@sub{10}}, or
|
||||
@nonterm{general-number@sub{16}} grammar, respectively.
|
||||
|
||||
An @nunterm{exponent-mark} in an inexact number serves both to specify
|
||||
an exponent and specify a numerical precision. If single-precision
|
||||
IEEE floating point is supported (see @secref["mz:numbers"]), the marks
|
||||
@litchar{f} and @litchar{s} specifies single-precision. Otherwise, or
|
||||
with any other mark, double-precision IEEE floating point is used.
|
||||
|
||||
@BNF[(list @nunterm{number} @BNF-alt[@nunterm{exact}
|
||||
@nunterm{inexact}])
|
||||
(list @nunterm{exact} @BNF-alt[@nunterm{exact-integer}
|
||||
@nunterm{exact-rational}]
|
||||
@nunterm{exact-complex})
|
||||
(list @nunterm{exact-integer} @BNF-seq[@optional{@nonterm{sign}} @nunterm{digits}])
|
||||
(list @nunterm{digits} @kleeneplus{@nunterm{digit}})
|
||||
(list @nunterm{exact-rational} @BNF-seq[@nunterm{exact-integer} @litchar{/} @nunterm{unsigned-integer}])
|
||||
(list @nunterm{exact-complex} @BNF-seq[@nunterm{exact-rational} @nonterm{sign} @nunterm{exact-rational} @litchar{i}])
|
||||
(list @nunterm{inexact} @BNF-alt[@nunterm{inexact-real}
|
||||
@nunterm{inexact-complex}])
|
||||
(list @nunterm{inexact-real} @BNF-seq[@optional{@nonterm{sign}} @nunterm{inexact-normal}]
|
||||
@BNF-seq[@nonterm{sign} @nunterm{inexact-special}])
|
||||
(list @nunterm{inexact-unsigned} @BNF-alt[@nunterm{inexact-normal}
|
||||
@nunterm{inexact-special}])
|
||||
(list @nunterm{inexact-normal} @BNF-seq[@nunterm{inexact-simple} @optional{@nunterm{exp-mark}
|
||||
@optional[@nonterm{sign}] @nunterm{digits#}}])
|
||||
(list @nunterm{inexact-simple} @BNF-seq[@nunterm{digits#} @optional{@litchar{.}} @kleenestar{@litchar{#}}]
|
||||
@BNF-seq[@optional{@nunterm{exact-integer}} @litchar{.} @nunterm{digits#}]
|
||||
@BNF-seq[@nunterm{digits#} @litchar{/} @nunterm{digits#}])
|
||||
(list @nunterm{inexact-special} @BNF-alt[@litchar{inf.0} @litchar{nan.0}])
|
||||
(list @nunterm{digits#} @BNF-seq[@kleeneplus{@nunterm{digit}} @kleenestar{@litchar{#}}])
|
||||
(list @nunterm{inexact-complex} @BNF-seq[@optional{@nunterm{inexact-real}} @nonterm{sign} @nunterm{inexact-unsigned} @litchar{i}]
|
||||
@BNF-seq[@nunterm{inexact-real} @litchar["@"] @nunterm{inexact-real}])
|
||||
|
||||
|
||||
(list @nonterm{sign} @BNF-alt[@litchar{+}
|
||||
@litchar{-}])
|
||||
(list @nonterm{digit@sub{16}} @BNF-alt[@nonterm{digit@sub{10}} @litchar{a} @litchar{b} @litchar{c} @litchar{d}
|
||||
@litchar{e} @litchar{f}])
|
||||
(list @nonterm{digit@sub{10}} @BNF-alt[@nonterm{digit@sub{8}} @litchar{8} @litchar{9}])
|
||||
(list @nonterm{digit@sub{8}} @BNF-alt[@nonterm{digit@sub{2}} @litchar{2} @litchar{3}
|
||||
@litchar{4} @litchar{5} @litchar{6} @litchar{7}])
|
||||
(list @nonterm{digit@sub{2}} @BNF-alt[@litchar{0} @litchar{1}])
|
||||
(list @nonterm{exp-mark@sub{16}} @BNF-alt[@litchar{s} @litchar{d} @litchar{l}])
|
||||
(list @nonterm{exp-mark@sub{10}} @BNF-alt[@nonterm{exp-mark@sub{16}} @litchar{e} @litchar{f}])
|
||||
(list @nonterm{exp-mark@sub{8}} @nonterm{exp-mark@sub{10}})
|
||||
(list @nonterm{exp-mark@sub{2}} @nonterm{exp-mark@sub{10}})
|
||||
(list @nunterm{general-number} @BNF-seq[@optional{@nonterm{exactness}} @nunterm{number}])
|
||||
(list @nonterm{exactness} @BNF-alt[@litchar{#e} @litchar{#i}])
|
||||
]
|
||||
|
||||
@reader-examples[
|
||||
"-1"
|
||||
"1/2"
|
||||
"1.0"
|
||||
"1+2i"
|
||||
"1/2+3/4i"
|
||||
"1.0+3.0e7i"
|
||||
"2e5"
|
||||
"#i5"
|
||||
"#e2e5"
|
||||
"#x2e5"
|
||||
"#b101"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-boolean"]{Reading Booleans}
|
||||
|
||||
A @as-index{@litchar{#t}} or @as-index{@litchar{#T}} is the complete
|
||||
input syntax for the boolean constant true, and
|
||||
@as-index{@litchar{#f}} or @as-index{@litchar{#F}} is the complete
|
||||
input syntax for the boolean constant false.
|
||||
|
||||
@section[#:tag "mz:parse-pair"]{Reading Pairs and Lists}
|
||||
|
||||
When the reader encounters a @as-index{@litchar{(}},
|
||||
@as-index{@litchar["["]}, or @as-index{@litchar["{"]}, it starts
|
||||
parsing a pair or list; see @secref["mz:pairs"] for information on pairs
|
||||
and lists.
|
||||
|
||||
To parse the pair or list, the reader recursively reads data
|
||||
until a matching @as-index{@litchar{)}}, @as-index{@litchar{]}}, or
|
||||
@as-index{@litchar["}"]} (respectively) is found, and it specially handles
|
||||
a delimited @litchar{.}. Pairs @litchar{()}, @litchar{[]}, and
|
||||
@litchar["{}"] are treated the same way, so the remainder of this
|
||||
section simply uses ``parentheses'' to mean any of these pair.
|
||||
|
||||
If the reader finds no delimited @as-index{@litchar{.}} among the elements
|
||||
between parentheses, then it produces a list containing the results of
|
||||
the recursive reads.
|
||||
|
||||
If the reader finds two data between the matching parentheses
|
||||
that are separated by a delimited @litchar{.}, then it creates a
|
||||
pair. More generally, if it finds two or more data where the
|
||||
last is preceeded by a delimited @litchar{.}, then it constructs
|
||||
nested pairs: the next-to-last element is paired with the last, then
|
||||
the third-to-last is paired with that pair, and so on.
|
||||
|
||||
If the reader finds three or more data between the matching
|
||||
parentheses, and if a pair of delimited @litchar{.}s surrounds any
|
||||
oter than the first and last elements, the result is a list
|
||||
countaining the element surrounded by @litchar{.}s as the first
|
||||
element, followed by the others in ther read order. This convention
|
||||
supports a kind of @index["infix"]{infix} notation at the reader
|
||||
level.
|
||||
|
||||
In @scheme[read-syntax] mode, the recursive reads for the pair/list
|
||||
elements are themselves in @scheme[read-syntax] mode, so that the
|
||||
result is list or pair of syntax objects that it itself wrapped as a
|
||||
syntax object. If the reader constructs nested pairs because the input
|
||||
included a single delimited @litchar{.}, then only the innermost pair
|
||||
and outtermost pair are wrapped as syntax objects. Whether wrapping a
|
||||
pair or list, if the pair or list was formed with @litchar{[} and
|
||||
@litchar{]}, then a @scheme['paren-shape] property is attached to the
|
||||
result with the value @scheme[#\[];if the list or pair was formed with
|
||||
@litchar["{"] and @litchar["}"], then a @scheme['paren-shape] property
|
||||
is attached to the result with the value @scheme[#\{].
|
||||
|
||||
If a delimited @litchar{.} appears in any other configuration, then
|
||||
the @exnraise[exn:fail:read]. Similarly, if the reader encounters a
|
||||
@litchar{)}, @litchar["]"], or @litchar["}"] that does not end a list
|
||||
being parsed, then the @exnraise[exn:fail:read].
|
||||
|
||||
@reader-examples[
|
||||
"()"
|
||||
"(1 2 3)"
|
||||
"{1 2 3}"
|
||||
"[1 2 3]"
|
||||
"(1 (2) 3)"
|
||||
"(1 . 3)"
|
||||
"(1 . (3))"
|
||||
"(1 . 2 . 3)"
|
||||
]
|
||||
|
||||
If the @scheme[read-square-bracket-as-paren] @tech{parameter} is set to
|
||||
@scheme[#f], then when then reader encounters @litchar{[} and
|
||||
@litchar{]}, the @exnraise{exn:fail:read}. Similarly, If the
|
||||
@scheme[read-curly-brace-as-paren] @tech{parameter} is set to @scheme[#f],
|
||||
then when then reader encounters @litchar["{"] and @litchar["}"], the
|
||||
@exnraise{exn:fail:read}.
|
||||
|
||||
@section[#:tag "mz:parse-string"]{Reading Strings}
|
||||
|
||||
@guideintro["guide:strings"]{the syntax of strings}
|
||||
|
||||
@index['("strings" "parsing")]{When} the reader encouters
|
||||
@as-index{@litchar{"}}, it begins parsing characters to form a string. The
|
||||
string continues until it is terminated by another @litchar{"} (that
|
||||
is not escaped by @litchar["\\"]).
|
||||
|
||||
Within a string sequence, the following escape sequences are
|
||||
recognized:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@as-index{@litchar["\\a"]}: alarm (ASCII 7)}
|
||||
@item{@as-index{@litchar["\\b"]}: backspace (ASCII 8)}
|
||||
@item{@as-index{@litchar["\\t"]}: tab (ASCII 9)}
|
||||
@item{@as-index{@litchar["\\n"]}: linefeed (ASCII 10)}
|
||||
@item{@as-index{@litchar["\\v"]}: vertical tab (ASCII 11)}
|
||||
@item{@as-index{@litchar["\\f"]}: formfeed (ASCII 12)}
|
||||
@item{@as-index{@litchar["\\r"]}: return (ASCII 13)}
|
||||
@item{@as-index{@litchar["\\e"]}: escape (ASCII 27)}
|
||||
|
||||
@item{@as-index{@litchar["\\\""]}: double-quotes (without terminating the string)}
|
||||
@item{@as-index{@litchar["\\'"]}: quote (i.e., the backslash has no effect)}
|
||||
@item{@as-index{@litchar["\\\\"]}: backslash (i.e., the second is not an escaping backslash)}
|
||||
|
||||
@item{@as-index{@litchar["\\"]@kleenerange[1 3]{@nonterm{digit@sub{8}}}}:
|
||||
Unicode for the octal number specified by @kleenerange[1
|
||||
3]{digit@sub{8}} (i.e., 1 to 3 @nonterm{digit@sub{8}}s) where
|
||||
each @nonterm{digit@sub{8}} is @litchar{0}, @litchar{1},
|
||||
@litchar{2}, @litchar{3}, @litchar{4}, @litchar{5},
|
||||
@litchar{6}, or @litchar{7}. A longer form takes precedence
|
||||
over a shorter form, and the resulting octal number must be
|
||||
between 0 and 255 decimal, otherwise the
|
||||
@exnraise[exn:fail:read].}
|
||||
|
||||
@item{@as-index{@litchar["\\x"]@kleenerange[1
|
||||
2]{@nonterm{digit@sub{16}}}}: Unicode for the hexadecimal
|
||||
number specified by @kleenerange[1 2]{@nonterm{digit@sub{16}}},
|
||||
where each @nonterm{digit@sub{16}} is @litchar{0}, @litchar{1},
|
||||
@litchar{2}, @litchar{3}, @litchar{4}, @litchar{5},
|
||||
@litchar{6}, @litchar{7}, @litchar{8}, @litchar{9},
|
||||
@litchar{a}, @litchar{b}, @litchar{c}, @litchar{d},
|
||||
@litchar{e}, or @litchar{f} (case-insensitive). The longer form
|
||||
takes precedence over the shorter form.}
|
||||
|
||||
@item{@as-index{@litchar["\\u"]@kleenerange[1
|
||||
4]{@nonterm{digit@sub{16}}}}: like @litchar["\\x"], but with up
|
||||
to four hexadecimal digits (longer sequences take precedence).
|
||||
The resulting hexadecimal number must be a valid argument to
|
||||
@scheme[integer->char], otherwise the
|
||||
@exnraise[exn:fail:read].}
|
||||
|
||||
@item{@as-index{@litchar["\\U"]@kleenerange[1
|
||||
8]{@nonterm{digit@sub{16}}}}: like @litchar["\\x"], but with up
|
||||
to eight hexadecimal digits (longer sequences take precedence).
|
||||
The resulting hexadecimal number must be a valid argument to
|
||||
@scheme[integer->char], otherwise the
|
||||
@exnraise[exn:fail:read].}
|
||||
|
||||
@item{@as-index{@litchar["\\"]@nonterm{newline}}: elided, where
|
||||
@nonterm{newline} is either a linefeed, carriage return, or
|
||||
carriage return--linefeed combination. This convetion allows
|
||||
single-line strings to span multiple lines in the source.}
|
||||
|
||||
}
|
||||
|
||||
If the reader encounteres any other use of a backslash in a string
|
||||
constant, the @exnraise[exn:fail:read].
|
||||
|
||||
@guideintro["guide:bytestrings"]{the syntax of byte strings}
|
||||
|
||||
@index['("byte strings" "parsing")]{A} string constant preceded by
|
||||
@litchar{#} is parsed as a byte-string. (That is, @as-index{@litchar{#"}} starts
|
||||
a byte-string literal.) See @secref["mz:bytestrings"] for
|
||||
information on byte strings. Byte string constants support the same
|
||||
escape sequences as character strings, except @litchar["\\u"] and
|
||||
@litchar["\\U"].
|
||||
|
||||
When the reader encounters @as-index{@litchar{#<<}}, it starts parsing a
|
||||
@pidefterm{here string}. The characters following @litchar{#<<} until
|
||||
a newline character define a terminator for the string. The content of
|
||||
the string includes all characters between the @litchar{#<<} line and
|
||||
a line whose only content is the specified terminator. More precisely,
|
||||
the content of the string starts after a newline following
|
||||
@litchar{#<<}, and it ends before a newline that is followed by the
|
||||
terminator, where the terminator is itself followed by either a
|
||||
newline or end-of-file. No escape sequences are recognized between the
|
||||
starting and terminating lines; all characters are included in the
|
||||
string (and terminator) literally. A return character is not treated
|
||||
as a line separator in this context. If no characters appear between
|
||||
@litchar{#<<} and a newline or end-of-file, or if an end-of-file is
|
||||
encountered before a terminating line, the @exnraise[exn:fail:read].
|
||||
|
||||
@reader-examples[
|
||||
"\"Apple\""
|
||||
"\"\\x41pple\""
|
||||
"\"\\\"Apple\\\"\""
|
||||
"\"\\\\\""
|
||||
"#\"Apple\""
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-quote"]{Reading Quotes}
|
||||
|
||||
When the reader enounters @as-index{@litchar{'}}, then it recursively
|
||||
reads one datum, and it forms a new list containing the symbol
|
||||
@scheme['quote] and the following datum. This convention is mainly
|
||||
useful for reading Scheme code, where @scheme['s] can be used as a
|
||||
shorthand for @scheme[(code:quote s)].
|
||||
|
||||
Several other sequences are recognized and transformed in a similar
|
||||
way. Longer prefixes take precedence over short ones:
|
||||
|
||||
@read-quote-table[(list @litchar{'} @scheme[quote])
|
||||
(list @as-index{@litchar{`}} @scheme[quasiquote])
|
||||
(list @as-index{@litchar{,}} @scheme[unquote])
|
||||
(list @as-index{@litchar[",@"]} @scheme[unquote-splicing])
|
||||
(list @as-index{@litchar{#'}} @scheme[syntax])
|
||||
(list @as-index{@litchar{#`}} @scheme[quasisyntax])
|
||||
(list @as-index{@litchar{#,}} @scheme[unsyntax])
|
||||
(list @as-index{@litchar["#,@"]} @scheme[unsyntax-splicing])]
|
||||
|
||||
@reader-examples[
|
||||
"'apple"
|
||||
"`(1 ,2)"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-comment"]{Reading Comments}
|
||||
|
||||
A @as-index{@litchar{;}} starts a line comment. When the reader
|
||||
encounters @litchar{;}, then it skips past all characters until the
|
||||
next linefeed or carriage return.
|
||||
|
||||
A @litchar["#|"] starts a nestable block comment. When the reader
|
||||
encounters @litchar["#|"], then it skips past all characters until a
|
||||
closing @litchar["|#"]. Pairs of matching @litchar["#|"] and
|
||||
@litchar["|#"] can be nested.
|
||||
|
||||
A @litchar{#;} starts an S-expression comment. Then the reader
|
||||
encounters @litchar{#;}, it recursively reads one datum, and then
|
||||
discards the datum (continuing on to the next datum for the read
|
||||
result).
|
||||
|
||||
A @litchar{#! } (which is @litchar{#!} followed by a space) or
|
||||
@litchar{#!/} starts a line comment that can be continued to the next
|
||||
line by ending a line with @litchar["\\"]. This form of comment
|
||||
normally appears at the beginning of a Unix script file.
|
||||
|
||||
@reader-examples[
|
||||
"; comment"
|
||||
"#| a |# 1"
|
||||
"#| #| a |# 1 |# 2"
|
||||
"#;1 2"
|
||||
"#!/bin/sh"
|
||||
"#! /bin/sh"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-vector"]{Reading Vectors}
|
||||
|
||||
When the reader encounters a @litchar{#(}, @litchar{#[}, or
|
||||
@litchar["#{"], it starts parsing a vector; see @secref["vectors"] for
|
||||
information on vectors.
|
||||
|
||||
The elements of the vector are recursively read until a matching
|
||||
@litchar{)}, @litchar{]}, or @litchar["}"] is found, just as for
|
||||
lists (see @secref["mz:parse-pair"]). A delimited @litchar{.} is not
|
||||
allowed among the vector elements.
|
||||
|
||||
An optional vector length can be specified between the @litchar{#} and
|
||||
@litchar["("], @litchar["["], or @litchar["{"]. The size is specified
|
||||
using a sequence of decimal digits, and the number of elements
|
||||
provided for the vector must be no more than the specified size. If
|
||||
fewer elements are provided, the last provided element is used for the
|
||||
remaining vector slots; if no elements are provided, then @scheme[0]
|
||||
is used for all slots.
|
||||
|
||||
In @scheme[read-syntax] mode, each recursive read for the vector
|
||||
elements is also in @scheme[read-syntax] mode, so that the wrapped
|
||||
vector's elements are also wraped as syntax objects.
|
||||
|
||||
@reader-examples[
|
||||
"#(1 apple 3)"
|
||||
"#3(\"apple\" \"banana\")"
|
||||
"#3()"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-hashtable"]{Reading Hash Tables}
|
||||
|
||||
A @litchar{#hash} starts an immutable hash-table constant with key
|
||||
matching based on @scheme[equal?]. The characters after @litchar{hash}
|
||||
must parse as a list of pairs (see @secref["mz:parse-pair"]) with a
|
||||
specific use of delimited @litchar{.}: it must appear between the
|
||||
elements of each pair in the list, and nowhere in the sequence of list
|
||||
elements. The first element of each pair is used as the key for a
|
||||
table entry, and the second element of each pair is the associated
|
||||
value.
|
||||
|
||||
A @litchar{#hasheq} starts a hash table like @litchar{#hash}, except
|
||||
that it constructs a hash table based on @scheme[eq?] instead of
|
||||
@scheme[equal?].
|
||||
|
||||
In either case, the table is constructed by adding each mapping to the
|
||||
hash table from left to right, so later mappings can hide earlier
|
||||
mappings if the keys are equivalent.
|
||||
|
||||
@reader-examples[
|
||||
#:example-note @elem{, where @scheme[make-...] stands for @scheme[make-immutable-hash-table]}
|
||||
"#hash()"
|
||||
"#hasheq()"
|
||||
"#hash((\"a\" . 5))"
|
||||
"#hasheq((a . 5) (b . 7))"
|
||||
"#hasheq((a . 5) (a . 7))"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-box"]{Reading Boxes}
|
||||
|
||||
When the reader encounters a @litchar{#&}, it starts parsing a box;
|
||||
see @secref["boxes"] for information on boxes. The content of the box
|
||||
is determined by recursively reading the next datum.
|
||||
|
||||
In @scheme[read-syntax] mode, the recursive read for the box content
|
||||
is also in @scheme[read-syntax] mode, so that the wrapped box's
|
||||
content is also wraped as a syntax object.
|
||||
|
||||
@reader-examples[
|
||||
"#&17"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-character"]{Reading Characters}
|
||||
|
||||
@guideintro["guide:characters"]{the syntax of characters}
|
||||
|
||||
A @litchar["#\\"] starts a character constant, which has one of the
|
||||
following forms:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{ @litchar["#\\nul"] or @litchar["#\\null"]: NUL (ASCII 0)@nonalpha[]}
|
||||
@item{ @litchar["#\\backspace"]: backspace (ASCII 8)@nonalpha[]}
|
||||
@item{ @litchar["#\\tab"]: tab (ASCII 9)@nonalpha[]}
|
||||
@item{ @litchar["#\\newline"] or @litchar["#\\linefeed"]: linefeed (ASCII 10)@nonalpha[]}
|
||||
@item{ @litchar["#\\vtab"]: vertical tab (ASCII 11)@nonalpha[]}
|
||||
@item{ @litchar["#\\page"]: page break (ASCII 12)@nonalpha[]}
|
||||
@item{ @litchar["#\\return"]: carriage return (ASCII 13)@nonalpha[]}
|
||||
@item{ @litchar["#\\space"]: space (ASCII 32)@nonalpha[]}
|
||||
@item{ @litchar["#\\rubout"]: delete (ASCII 127)@nonalpha[]}
|
||||
|
||||
@item{@litchar["#\\"]@kleenerange[1 3]{@nonterm{digit@sub{8}}}:
|
||||
Unicode for the octal number specified by @kleenerange[1
|
||||
3]{@nonterm{digit@sub{8}}}, as in string escapes (see
|
||||
@secref["mz:parse-string"]).}
|
||||
|
||||
@item{@litchar["#\\x"]@kleenerange[1 2]{@nonterm{digit@sub{16}}}:
|
||||
Unicode for the hexadecimal number specified by @kleenerange[1
|
||||
2]{@nonterm{digit@sub{16}}}, as in string escapes (see
|
||||
@secref["mz:parse-string"]).}
|
||||
|
||||
@item{@litchar["#\\u"]@kleenerange[1 4]{@nonterm{digit@sub{16}}}:
|
||||
like @litchar["#\\x"], but with up to four hexadecimal digits.}
|
||||
|
||||
@item{@litchar["#\\U"]@kleenerange[1 6]{@nonterm{digit@sub{16}}}:
|
||||
like @litchar["#\\x"], but with up to six hexadecimal digits.}
|
||||
|
||||
@item{@litchar["#\\"]@nonterm{c}: the character @nonterm{c}, as long
|
||||
as @litchar["#\\"]@nonterm{c} and the characters following it
|
||||
do not match any of the previous cases, and as long as the
|
||||
character after @nonterm{c} is not
|
||||
@schemelink[char-alphabetic?]{alphabetic}.}
|
||||
|
||||
}
|
||||
|
||||
@reader-examples[
|
||||
"#\\newline"
|
||||
"#\\n"
|
||||
"#\\u3BB"
|
||||
"#\\\u3BB"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-keyword"]{Reading Keywords}
|
||||
|
||||
A @litchar{#:} starts a keyword. The parsing of a keyword after the
|
||||
@litchar{#:} is the same as for a symbol, including case-folding in
|
||||
case-insensitive mode, except that the part after @litchar{#:} is
|
||||
never parsed as a number.
|
||||
|
||||
@reader-examples[
|
||||
"#:Apple"
|
||||
"#:1"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-regexp"]{Reading Regular Expressions}
|
||||
|
||||
A @litchar{#rx} or @litchar{#px} starts a regular expression. The
|
||||
characters immediately after @litchar{#rx} or @litchar{#px} must parse
|
||||
as a string or byte string (see @secref["mz:parse-string"]). A
|
||||
@litchar{#rx} prefix starts a regular expression as would be
|
||||
constructed by @scheme[regexp], @litchar{#px} as
|
||||
constructed by @scheme[pregexp], @litchar{#rx#} as
|
||||
constructed by @scheme[byte-regexp], and @litchar{#px#} as
|
||||
constructed by @scheme[byte-pregexp].
|
||||
|
||||
@reader-examples[
|
||||
"#rx\".*\""
|
||||
"#px\"[\\\\s]*\""
|
||||
"#rx#\".*\""
|
||||
"#px#\"[\\\\s]*\""
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-graph"]{Reading Graph Structure}
|
||||
|
||||
A @graph-defn[] tags the following datum for reference via
|
||||
@graph-ref[], which allows the reader to produce a datum that
|
||||
have graph structure.
|
||||
|
||||
For a specific @graph-tag in a single read result, each @graph-ref[]
|
||||
reference is replaced by the datum read for the corresponding
|
||||
@graph-defn[]; the definition @graph-defn[] also produces just the
|
||||
datum after it. A @graph-defn[] definition can appear at most
|
||||
once, and a @graph-defn[] definition must appear before a @graph-ref[]
|
||||
reference appears.
|
||||
|
||||
Although a comment parsed via @litchar{#;} discards the datum
|
||||
afterward, @graph-defn[] definitions in the discarded datum
|
||||
still can be referenced by other parts of the reader input, as long as
|
||||
both the comment and the reference are grouped together by some other
|
||||
form (i.e., some recursive read); a top-level @litchar{#;} comment
|
||||
neither defines nor uses graph tags for other top-level forms.
|
||||
|
||||
@reader-examples[
|
||||
"(#1=100 #1# #1#)"
|
||||
"#0=(1 . #0#)"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-reader"]{Reading via an External Reader}
|
||||
|
||||
When the reader encounters @litchar{#reader}, then it loads an
|
||||
external reader procedure and applies it to the current input stream.
|
||||
|
||||
The reader recursively reads the next datum after @litchar{#reader},
|
||||
and passes it to the procedure that is the value of the
|
||||
@scheme[current-reader-guard] @tech{parameter}; the result is used as a
|
||||
module path. The module path is passed to @scheme[dynamic-require]
|
||||
with either @scheme['read] or @scheme['read-syntax] (depending on
|
||||
whether the reader is in @scheme[read] or @scheme[read-syntax]
|
||||
mode).
|
||||
|
||||
The resulting procedure should accept the same arguments as
|
||||
@scheme[read] or @scheme[read-syntax] in the case thar all optional
|
||||
arguments are provided. The procedure is given the port whose stream
|
||||
contained @litchar{#reader}, and it should produce a datum result. If
|
||||
the result is a syntax object in @scheme[read] mode, then it is
|
||||
converted to a datum using @scheme[syntax-object->datum]; if the
|
||||
result is not a syntax object in @scheme[read-syntax] mode, then it is
|
||||
converted to one using @scheme[datum->syntax-object]. See also
|
||||
@secref["special-comments"] and @secref["recursive-reads"] for
|
||||
information on special-comment results and recursive reads.
|
||||
|
||||
If the @scheme[read-accept-reader] @tech{parameter} is set to @scheme[#f],
|
||||
then if the reader encounters @litchar{#reader}, the
|
||||
@exnraise[exn:fail:read].
|
||||
|
||||
@section[#:tag "mz:readtables"]{Readtables}
|
||||
|
||||
The dispatch table in @secref["mz:default-readtable-dispatch"]
|
||||
corresponds to the default @idefterm{readtable}.
|
||||
|
||||
@section[#:tag "mz:parse-honu"]{Honu Parsing}
|
||||
A parameter that controls parsing @litchar{#~} compiled input. See
|
||||
@secref["mz:parsing"] for more information.}
|
||||
|
||||
@defboolparam[read-accept-bar-quote on?]{
|
||||
|
||||
A parameter that controls parsing and printing of @litchar["|"] in
|
||||
symbols. See @secref["mz:parse-symbol"] and @secref["mz:printing"] for
|
||||
more information.}
|
||||
|
||||
@defboolparam[read-accept-graph on?]{
|
||||
|
||||
A parameter value that controls parsing input with sharing. See
|
||||
@secref["mz:parse-graph"] for more information.}
|
||||
|
||||
@defboolparam[read-decimal-as-inexact on?]{
|
||||
|
||||
A parameter that controls parsing input numbers with a decimal point
|
||||
or exponent (but no explicit exactness tag). See
|
||||
@secref["mz:parse-number"] for more information.}
|
||||
|
||||
@defboolparam[read-accept-dot on?]{
|
||||
|
||||
A parameter that controls parsing input with a dot, which is normally
|
||||
used for literal cons cells. See @secref["mz:parse-pair"] for more
|
||||
information.}
|
||||
|
||||
@defboolparam[read-accept-infix-dot on?]{
|
||||
|
||||
A parameter that controls parsing input with two dots to trigger infix
|
||||
conversion. See @secref["mz:parse-pair"] for more information.}
|
||||
|
||||
@defboolparam[read-accept-quasiquote on?]{
|
||||
|
||||
A parameter that controls parsing input with @litchar{`} or
|
||||
@litchar{,} which is normally used for @scheme[quasiquote],
|
||||
@scheme[unquote], and @scheme[unquote-splicing] abbreviations. See
|
||||
@secref["mz:parse-quote"] for more information.}
|
||||
|
||||
@defboolparam[read-accept-reader on?]{
|
||||
|
||||
A parameter that controls whether @litchar{#reader} is allowed for
|
||||
selecting a parser. See @secref["mz:parse-reader"] for more
|
||||
information.}
|
||||
|
||||
@defparam[current-reader-guard proc (any/c . -> . any)]{
|
||||
|
||||
A parameter whose value converts or rejects (by raising an exception)
|
||||
a module-path datum following @litchar{#reader}. See
|
||||
@secref["mz:parse-reader"] for more information.}
|
||||
|
||||
|
||||
@defparam[current-readtable readtable (or/c readtable? false/c)]{
|
||||
|
||||
A parameter whose value determines a readtable that
|
||||
adjusts the parsing of S-expression input, where @scheme[#f] implies the
|
||||
default behavior. See @secref["mz:readtables"] for more information.}
|
735
collects/scribblings/reference/reader.scrbl
Normal file
735
collects/scribblings/reference/reader.scrbl
Normal file
|
@ -0,0 +1,735 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
@require[(lib "bnf.ss" "scribble")]
|
||||
@require["reader-example.ss"]
|
||||
@begin[
|
||||
(define (ilitchar s)
|
||||
(litchar s))
|
||||
(define (nunterm s)
|
||||
(nonterm s (subscript "n")))
|
||||
(define (sub n) (subscript n))
|
||||
(define (nonalpha)
|
||||
@elem{; the next character must not be @schemelink[char-alphabetic?]{alphabetic}.})
|
||||
]
|
||||
@define[(graph-tag) @kleenerange[1 8]{@nonterm{digit@sub{10}}}]
|
||||
@define[(graph-defn) @elem{@litchar{#}@graph-tag[]@litchar{=}}]
|
||||
@define[(graph-ref) @elem{@litchar{#}@graph-tag[]@litchar{#}}]
|
||||
|
||||
@title[#:tag "mz:reader"]{The Reader}
|
||||
|
||||
Scheme's reader is a recursive-descent parser that can be configured
|
||||
through a @seclink["mz:readtables"]{readtable} and various other
|
||||
@tech{parameters}. This section describes the reader's parsing when
|
||||
using the default readtable.
|
||||
|
||||
Reading from a stream produces one @deftech{datum}. If the result
|
||||
datum is a compound value, then reading the datum typically requires
|
||||
the reader to call itself recursively to read the component data.
|
||||
|
||||
The reader can be invoked in either of two modes: @scheme[read] mode,
|
||||
or @scheme[read-syntax] mode. In @scheme[read-syntax] mode, the result
|
||||
is always a @techlink{syntax object} that includes
|
||||
source-location and (initially empty) lexical information wrapped
|
||||
around the sort of datum that @scheme[read] mode would produce. In the
|
||||
case of pairs, vectors, and boxes, morever, the content is also
|
||||
wrapped recursively as a syntax object. Unless specified otherwise,
|
||||
this section describes the reader's behavior in @scheme[read] mode,
|
||||
and @scheme[read-syntax] mode does the same modulo wrapping the final
|
||||
result.
|
||||
|
||||
Reading is defined in terms of Unicode characters; see
|
||||
@secref["mz:ports"] for information on how a byte stream is converted
|
||||
to a character stream.
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:default-readtable-dispatch"]{Delimiters and Dispatch}
|
||||
|
||||
Along with @schemelink[char-whitespace?]{whitespace}, the following
|
||||
characters are @defterm{delimiters}:
|
||||
|
||||
@t{
|
||||
@hspace[2] @ilitchar{(} @ilitchar{)} @ilitchar{[} @ilitchar{]}
|
||||
@ilitchar["["] @ilitchar["]"]
|
||||
@ilitchar{"} @ilitchar{,} @ilitchar{'} @ilitchar{`}
|
||||
@ilitchar{;}
|
||||
}
|
||||
|
||||
A delimited sequence that starts with any other character is typically
|
||||
parsed as either a symbol or number, but a few non-delimiter
|
||||
characters play special roles:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@litchar{#} has a special meaning as an initial character in a
|
||||
delimited sequence; its meaning depends on the characters that
|
||||
follow; see below.}
|
||||
|
||||
@item{@as-index{@litchar["|"]} starts a subsequence of characters to
|
||||
be included verbatim in the delimited sequence (i.e,. they are
|
||||
never treated as delimiters, and they are not case-folded when
|
||||
case-insensitivity is enabled); the subsequence is terminated
|
||||
by another @litchar["|"], and neither the initial nor
|
||||
terminating @litchar["|"] is part of the subsequence.}
|
||||
|
||||
@item{@as-index{@litchar["\\"]} outside of a @litchar["|"] pair causes
|
||||
the folowing character to be included verbatim in a delimited
|
||||
sequence.}
|
||||
|
||||
}
|
||||
|
||||
More precisely, after skipping whitespace, the reader dispatches based
|
||||
on the next character or characters in the input stream as follows:
|
||||
|
||||
@dispatch-table[
|
||||
|
||||
@dispatch[@litchar{(}]{starts a pair or list; see @secref["mz:parse-pair"]}
|
||||
@dispatch[@litchar{[}]{starts a pair or list; see @secref["mz:parse-pair"]}
|
||||
@dispatch[@litchar["{"]]{starts a pair or list; see @secref["mz:parse-pair"]}
|
||||
|
||||
@dispatch[@litchar{)}]{matches @litchar{(} or raises @Exn{exn:fail:read}}
|
||||
@dispatch[@litchar{]}]{matches @litchar{[} or raises @Exn{exn:fail:read}}
|
||||
@dispatch[@litchar["}"]]{matches @litchar["{"] or raises @Exn{exn:fail:read}}
|
||||
|
||||
@dispatch[@litchar{"}]{starts a string; see @secref["mz:parse-string"]}
|
||||
@dispatch[@litchar{,}]{starts a quote; see @secref["mz:parse-quote"]}
|
||||
@dispatch[@litchar{`}]{starts a quasiquote; see @secref["mz:parse-quote"]}
|
||||
@dispatch[@litchar{,}]{starts an unquote or splicing unquote; see @secref["mz:parse-quote"]}
|
||||
|
||||
@dispatch[@litchar{;}]{starts a line comment; see @secref["mz:parse-comment"]}
|
||||
|
||||
@dispatch[@cilitchar{#t}]{true; see @secref["mz:parse-boolean"]}
|
||||
@dispatch[@cilitchar{#f}]{false; see @secref["mz:parse-boolean"]}
|
||||
|
||||
@dispatch[@litchar{#(}]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
@dispatch[@litchar{#[}]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
@dispatch[@litchar["#{"]]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
|
||||
@dispatch[@litchar["#\\"]]{starts a character; see @secref["mz:parse-character"]}
|
||||
|
||||
@dispatch[@litchar{#"}]{starts a byte string; see @secref["mz:parse-string"]}
|
||||
@dispatch[@litchar{#%}]{starts a symbol; see @secref["mz:parse-symbol"]}
|
||||
@dispatch[@litchar{#:}]{starts a keyword; see @secref["mz:parse-keyword"]}
|
||||
@dispatch[@litchar{#&}]{starts a box; see @secref["mz:parse-box"]}
|
||||
|
||||
@dispatch[@litchar["#|"]]{starts a block comment; see @secref["mz:parse-comment"]}
|
||||
@dispatch[@litchar["#;"]]{starts an S-expression comment; see @secref["mz:parse-comment"]}
|
||||
@dispatch[@litchar{#,}]{starts a syntax quote; see @secref["mz:parse-quote"]}
|
||||
@dispatch[@litchar["#! "]]{starts a line comment; see @secref["mz:parse-comment"]}
|
||||
@dispatch[@litchar["#!/"]]{starts a line comment; see @secref["mz:parse-comment"]}
|
||||
@dispatch[@litchar{#`}]{starts a syntax quasiquote; see @secref["mz:parse-quote"]}
|
||||
@dispatch[@litchar{#,}]{starts an syntax unquote or splicing unquote; see @secref["mz:parse-quote"]}
|
||||
@dispatch[@litchar["#~"]]{starts compiled code; see @secref["compilation"]}
|
||||
|
||||
@dispatch[@cilitchar{#i}]{starts a number; see @secref["mz:parse-number"]}
|
||||
@dispatch[@cilitchar{#e}]{starts a number; see @secref["mz:parse-number"]}
|
||||
@dispatch[@cilitchar{#x}]{starts a number; see @secref["mz:parse-number"]}
|
||||
@dispatch[@cilitchar{#o}]{starts a number; see @secref["mz:parse-number"]}
|
||||
@dispatch[@cilitchar{#d}]{starts a number; see @secref["mz:parse-number"]}
|
||||
@dispatch[@cilitchar{#b}]{starts a number; see @secref["mz:parse-number"]}
|
||||
|
||||
@dispatch[@cilitchar["#<<"]]{starts a string; see @secref["mz:parse-string"]}
|
||||
|
||||
@dispatch[@litchar{#rx}]{starts a regular expression; see @secref["mz:parse-regexp"]}
|
||||
@dispatch[@litchar{#px}]{starts a regular expression; see @secref["mz:parse-regexp"]}
|
||||
|
||||
@dispatch[@cilitchar{#ci}]{switches case sensitivity; see @secref["mz:parse-symbol"]}
|
||||
@dispatch[@cilitchar{#cs}]{switches case sensitivity; see @secref["mz:parse-symbol"]}
|
||||
|
||||
@dispatch[@cilitchar["#sx"]]{starts a Scheme expression; see @secref["mz:parse-honu"]}
|
||||
|
||||
@dispatch[@litchar["#hx"]]{starts a Honu expression; see @secref["mz:parse-honu"]}
|
||||
@dispatch[@litchar["#honu"]]{starts a Honu module; see @secref["mz:parse-honu"]}
|
||||
|
||||
@dispatch[@litchar["#hash"]]{starts a hash table; see @secref["mz:parse-hashtable"]}
|
||||
|
||||
@dispatch[@litchar["#reader"]]{starts a reader extension use; see @secref["mz:parse-reader"]}
|
||||
|
||||
@dispatch[@elem{@litchar{#}@kleeneplus{@nonterm{digit@sub{10}}}@litchar{(}}]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
@dispatch[@elem{@litchar{#}@kleeneplus{@nonterm{digit@sub{10}}}@litchar{[}}]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
@dispatch[@elem{@litchar{#}@kleeneplus{@nonterm{digit@sub{10}}}@litchar["{"]}]{starts a vector; see @secref["mz:parse-vector"]}
|
||||
@dispatch[@graph-defn[]]{binds a graph tag; see @secref["mz:parse-graph"]}
|
||||
@dispatch[@graph-ref[]]{uses a graph tag; see @secref["mz:parse-graph"]}
|
||||
|
||||
@dispatch[@italic{otherwise}]{starts a symbol; see @secref["mz:parse-symbol"]}
|
||||
|
||||
]
|
||||
|
||||
|
||||
@section[#:tag "mz:parse-symbol"]{Reading Symbols}
|
||||
|
||||
@guideintro["guide:symbols"]{the syntax of symbols}
|
||||
|
||||
A sequence that does not start with a delimiter or @litchar{#} is
|
||||
parsed as either a symbol or a number (see
|
||||
@secref["mz:parse-number"]), except that @litchar{.} by itself is
|
||||
never parsed as a symbol or character (unless the
|
||||
@scheme[read-accept-dot] parameter is set to @scheme[#f]). A
|
||||
@as-index{@litchar{#%}} also starts a symbol. A successful number
|
||||
parse takes precedence over a symbol parse.
|
||||
|
||||
When the @scheme[read-case-sensitive] @tech{parameter} is set to @scheme[#f],
|
||||
characters in the sequence that are not quoted by @litchar["|"] or
|
||||
@litchar["\\"] are first case-normalized. If the reader encounters
|
||||
@as-index{@litchar{#ci}}, @litchar{#CI}, @litchar{#Ci}, or @litchar{#cI},
|
||||
then it recursively reads the following datum in
|
||||
case-insensitive mode. If the reader encounters @as-index{@litchar{#cs}},
|
||||
@litchar{#CS}, @litchar{#Cs}, or @litchar{#cS}, then recursively reads
|
||||
the following datum in case-sensitive mode.
|
||||
|
||||
@reader-examples[#:symbols? #f
|
||||
"Apple"
|
||||
"Ap#ple"
|
||||
"Ap ple"
|
||||
"Ap| |ple"
|
||||
"Ap\\ ple"
|
||||
"#ci Apple"
|
||||
"#ci |A|pple"
|
||||
"#ci \\Apple"
|
||||
"#ci#cs Apple"
|
||||
"#%Apple"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-number"]{Reading Numbers}
|
||||
|
||||
@guideintro["guide:numbers"]{the syntax of numbers}
|
||||
|
||||
@index['("numbers" "parsing")]{A} sequence that does not start with a
|
||||
delimiter is parsed as a number when it matches the following grammar
|
||||
case-insenstively for @nonterm{number@sub{10}} (decimal), where
|
||||
@metavar{n} is a meta-meta-variable in the grammar.
|
||||
|
||||
A number is optionally prefixed by an exactness specifier,
|
||||
@as-index{@litchar{#e}} (exact) or @as-index{@litchar{#i}} (inexact),
|
||||
which specifies its parsing as an exact or inexact number; see
|
||||
@secref["mz:numbers"] for information on number exactness. As the
|
||||
non-terminal names suggest, a number that has no exactness specifier
|
||||
and matches only @nunterm{inexact-number} is normally parsed as an
|
||||
inexact number, otherwise it is parsed as an excat number. If the
|
||||
@scheme[read-decimal-as-inexact] @tech{parameter} is set to @scheme[#f], then
|
||||
all numbers without an exactness specifier are instead parsed as
|
||||
exact.
|
||||
|
||||
If the reader encounters @as-index{@litchar{#b}} (binary),
|
||||
@as-index{@litchar{#o}} (octal), @as-index{@litchar{#d}} (decimal), or
|
||||
@as-index{@litchar{#x}} (hexadecimal), it must be followed by a
|
||||
sequence that is terminated by a delimiter or end-of-file, and that
|
||||
matches the @nonterm{general-number@sub{2}},
|
||||
@nonterm{general-number@sub{8}}, @nonterm{general-number@sub{10}}, or
|
||||
@nonterm{general-number@sub{16}} grammar, respectively.
|
||||
|
||||
An @nunterm{exponent-mark} in an inexact number serves both to specify
|
||||
an exponent and specify a numerical precision. If single-precision
|
||||
IEEE floating point is supported (see @secref["mz:numbers"]), the marks
|
||||
@litchar{f} and @litchar{s} specifies single-precision. Otherwise, or
|
||||
with any other mark, double-precision IEEE floating point is used.
|
||||
|
||||
@BNF[(list @nunterm{number} @BNF-alt[@nunterm{exact}
|
||||
@nunterm{inexact}])
|
||||
(list @nunterm{exact} @BNF-alt[@nunterm{exact-integer}
|
||||
@nunterm{exact-rational}]
|
||||
@nunterm{exact-complex})
|
||||
(list @nunterm{exact-integer} @BNF-seq[@optional{@nonterm{sign}} @nunterm{digits}])
|
||||
(list @nunterm{digits} @kleeneplus{@nunterm{digit}})
|
||||
(list @nunterm{exact-rational} @BNF-seq[@nunterm{exact-integer} @litchar{/} @nunterm{unsigned-integer}])
|
||||
(list @nunterm{exact-complex} @BNF-seq[@nunterm{exact-rational} @nonterm{sign} @nunterm{exact-rational} @litchar{i}])
|
||||
(list @nunterm{inexact} @BNF-alt[@nunterm{inexact-real}
|
||||
@nunterm{inexact-complex}])
|
||||
(list @nunterm{inexact-real} @BNF-seq[@optional{@nonterm{sign}} @nunterm{inexact-normal}]
|
||||
@BNF-seq[@nonterm{sign} @nunterm{inexact-special}])
|
||||
(list @nunterm{inexact-unsigned} @BNF-alt[@nunterm{inexact-normal}
|
||||
@nunterm{inexact-special}])
|
||||
(list @nunterm{inexact-normal} @BNF-seq[@nunterm{inexact-simple} @optional{@nunterm{exp-mark}
|
||||
@optional[@nonterm{sign}] @nunterm{digits#}}])
|
||||
(list @nunterm{inexact-simple} @BNF-seq[@nunterm{digits#} @optional{@litchar{.}} @kleenestar{@litchar{#}}]
|
||||
@BNF-seq[@optional{@nunterm{exact-integer}} @litchar{.} @nunterm{digits#}]
|
||||
@BNF-seq[@nunterm{digits#} @litchar{/} @nunterm{digits#}])
|
||||
(list @nunterm{inexact-special} @BNF-alt[@litchar{inf.0} @litchar{nan.0}])
|
||||
(list @nunterm{digits#} @BNF-seq[@kleeneplus{@nunterm{digit}} @kleenestar{@litchar{#}}])
|
||||
(list @nunterm{inexact-complex} @BNF-seq[@optional{@nunterm{inexact-real}} @nonterm{sign} @nunterm{inexact-unsigned} @litchar{i}]
|
||||
@BNF-seq[@nunterm{inexact-real} @litchar["@"] @nunterm{inexact-real}])
|
||||
|
||||
|
||||
(list @nonterm{sign} @BNF-alt[@litchar{+}
|
||||
@litchar{-}])
|
||||
(list @nonterm{digit@sub{16}} @BNF-alt[@nonterm{digit@sub{10}} @litchar{a} @litchar{b} @litchar{c} @litchar{d}
|
||||
@litchar{e} @litchar{f}])
|
||||
(list @nonterm{digit@sub{10}} @BNF-alt[@nonterm{digit@sub{8}} @litchar{8} @litchar{9}])
|
||||
(list @nonterm{digit@sub{8}} @BNF-alt[@nonterm{digit@sub{2}} @litchar{2} @litchar{3}
|
||||
@litchar{4} @litchar{5} @litchar{6} @litchar{7}])
|
||||
(list @nonterm{digit@sub{2}} @BNF-alt[@litchar{0} @litchar{1}])
|
||||
(list @nonterm{exp-mark@sub{16}} @BNF-alt[@litchar{s} @litchar{d} @litchar{l}])
|
||||
(list @nonterm{exp-mark@sub{10}} @BNF-alt[@nonterm{exp-mark@sub{16}} @litchar{e} @litchar{f}])
|
||||
(list @nonterm{exp-mark@sub{8}} @nonterm{exp-mark@sub{10}})
|
||||
(list @nonterm{exp-mark@sub{2}} @nonterm{exp-mark@sub{10}})
|
||||
(list @nunterm{general-number} @BNF-seq[@optional{@nonterm{exactness}} @nunterm{number}])
|
||||
(list @nonterm{exactness} @BNF-alt[@litchar{#e} @litchar{#i}])
|
||||
]
|
||||
|
||||
@reader-examples[
|
||||
"-1"
|
||||
"1/2"
|
||||
"1.0"
|
||||
"1+2i"
|
||||
"1/2+3/4i"
|
||||
"1.0+3.0e7i"
|
||||
"2e5"
|
||||
"#i5"
|
||||
"#e2e5"
|
||||
"#x2e5"
|
||||
"#b101"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-boolean"]{Reading Booleans}
|
||||
|
||||
A @as-index{@litchar{#t}} or @as-index{@litchar{#T}} is the complete
|
||||
input syntax for the boolean constant true, and
|
||||
@as-index{@litchar{#f}} or @as-index{@litchar{#F}} is the complete
|
||||
input syntax for the boolean constant false.
|
||||
|
||||
@section[#:tag "mz:parse-pair"]{Reading Pairs and Lists}
|
||||
|
||||
When the reader encounters a @as-index{@litchar{(}},
|
||||
@as-index{@litchar["["]}, or @as-index{@litchar["{"]}, it starts
|
||||
parsing a pair or list; see @secref["mz:pairs"] for information on pairs
|
||||
and lists.
|
||||
|
||||
To parse the pair or list, the reader recursively reads data
|
||||
until a matching @as-index{@litchar{)}}, @as-index{@litchar{]}}, or
|
||||
@as-index{@litchar["}"]} (respectively) is found, and it specially handles
|
||||
a delimited @litchar{.}. Pairs @litchar{()}, @litchar{[]}, and
|
||||
@litchar["{}"] are treated the same way, so the remainder of this
|
||||
section simply uses ``parentheses'' to mean any of these pair.
|
||||
|
||||
If the reader finds no delimited @as-index{@litchar{.}} among the elements
|
||||
between parentheses, then it produces a list containing the results of
|
||||
the recursive reads.
|
||||
|
||||
If the reader finds two data between the matching parentheses
|
||||
that are separated by a delimited @litchar{.}, then it creates a
|
||||
pair. More generally, if it finds two or more data where the
|
||||
last is preceeded by a delimited @litchar{.}, then it constructs
|
||||
nested pairs: the next-to-last element is paired with the last, then
|
||||
the third-to-last is paired with that pair, and so on.
|
||||
|
||||
If the reader finds three or more data between the matching
|
||||
parentheses, and if a pair of delimited @litchar{.}s surrounds any
|
||||
other than the first and last elements, the result is a list
|
||||
containing the element surrounded by @litchar{.}s as the first
|
||||
element, followed by the others in the read order. This convention
|
||||
supports a kind of @index["infix"]{infix} notation at the reader
|
||||
level.
|
||||
|
||||
In @scheme[read-syntax] mode, the recursive reads for the pair/list
|
||||
elements are themselves in @scheme[read-syntax] mode, so that the
|
||||
result is list or pair of syntax objects that it itself wrapped as a
|
||||
syntax object. If the reader constructs nested pairs because the input
|
||||
included a single delimited @litchar{.}, then only the innermost pair
|
||||
and outtermost pair are wrapped as syntax objects. Whether wrapping a
|
||||
pair or list, if the pair or list was formed with @litchar{[} and
|
||||
@litchar{]}, then a @scheme['paren-shape] property is attached to the
|
||||
result with the value @scheme[#\[];if the list or pair was formed with
|
||||
@litchar["{"] and @litchar["}"], then a @scheme['paren-shape] property
|
||||
is attached to the result with the value @scheme[#\{].
|
||||
|
||||
If a delimited @litchar{.} appears in any other configuration, then
|
||||
the @exnraise[exn:fail:read]. Similarly, if the reader encounters a
|
||||
@litchar{)}, @litchar["]"], or @litchar["}"] that does not end a list
|
||||
being parsed, then the @exnraise[exn:fail:read].
|
||||
|
||||
@reader-examples[
|
||||
"()"
|
||||
"(1 2 3)"
|
||||
"{1 2 3}"
|
||||
"[1 2 3]"
|
||||
"(1 (2) 3)"
|
||||
"(1 . 3)"
|
||||
"(1 . (3))"
|
||||
"(1 . 2 . 3)"
|
||||
]
|
||||
|
||||
If the @scheme[read-square-bracket-as-paren] @tech{parameter} is set to
|
||||
@scheme[#f], then when then reader encounters @litchar{[} and
|
||||
@litchar{]}, the @exnraise{exn:fail:read}. Similarly, If the
|
||||
@scheme[read-curly-brace-as-paren] @tech{parameter} is set to @scheme[#f],
|
||||
then when then reader encounters @litchar["{"] and @litchar["}"], the
|
||||
@exnraise{exn:fail:read}.
|
||||
|
||||
If the @scheme[read-accept-dot] @tech{parameter} is set to
|
||||
@scheme[#f], then a delimited @scheme{.} is not treated specially; it
|
||||
is instead parsed a s symbol. If the @scheme[read-accept-infix-dot]
|
||||
@tech{parameter} is set to @scheme[#f], then multiple delimited
|
||||
@litchar{.}s trigger a @scheme[exn:fail:read], instead of the infix
|
||||
conversion.
|
||||
|
||||
@section[#:tag "mz:parse-string"]{Reading Strings}
|
||||
|
||||
@guideintro["guide:strings"]{the syntax of strings}
|
||||
|
||||
@index['("strings" "parsing")]{When} the reader encouters
|
||||
@as-index{@litchar{"}}, it begins parsing characters to form a string. The
|
||||
string continues until it is terminated by another @litchar{"} (that
|
||||
is not escaped by @litchar["\\"]).
|
||||
|
||||
Within a string sequence, the following escape sequences are
|
||||
recognized:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@as-index{@litchar["\\a"]}: alarm (ASCII 7)}
|
||||
@item{@as-index{@litchar["\\b"]}: backspace (ASCII 8)}
|
||||
@item{@as-index{@litchar["\\t"]}: tab (ASCII 9)}
|
||||
@item{@as-index{@litchar["\\n"]}: linefeed (ASCII 10)}
|
||||
@item{@as-index{@litchar["\\v"]}: vertical tab (ASCII 11)}
|
||||
@item{@as-index{@litchar["\\f"]}: formfeed (ASCII 12)}
|
||||
@item{@as-index{@litchar["\\r"]}: return (ASCII 13)}
|
||||
@item{@as-index{@litchar["\\e"]}: escape (ASCII 27)}
|
||||
|
||||
@item{@as-index{@litchar["\\\""]}: double-quotes (without terminating the string)}
|
||||
@item{@as-index{@litchar["\\'"]}: quote (i.e., the backslash has no effect)}
|
||||
@item{@as-index{@litchar["\\\\"]}: backslash (i.e., the second is not an escaping backslash)}
|
||||
|
||||
@item{@as-index{@litchar["\\"]@kleenerange[1 3]{@nonterm{digit@sub{8}}}}:
|
||||
Unicode for the octal number specified by @kleenerange[1
|
||||
3]{digit@sub{8}} (i.e., 1 to 3 @nonterm{digit@sub{8}}s) where
|
||||
each @nonterm{digit@sub{8}} is @litchar{0}, @litchar{1},
|
||||
@litchar{2}, @litchar{3}, @litchar{4}, @litchar{5},
|
||||
@litchar{6}, or @litchar{7}. A longer form takes precedence
|
||||
over a shorter form, and the resulting octal number must be
|
||||
between 0 and 255 decimal, otherwise the
|
||||
@exnraise[exn:fail:read].}
|
||||
|
||||
@item{@as-index{@litchar["\\x"]@kleenerange[1
|
||||
2]{@nonterm{digit@sub{16}}}}: Unicode for the hexadecimal
|
||||
number specified by @kleenerange[1 2]{@nonterm{digit@sub{16}}},
|
||||
where each @nonterm{digit@sub{16}} is @litchar{0}, @litchar{1},
|
||||
@litchar{2}, @litchar{3}, @litchar{4}, @litchar{5},
|
||||
@litchar{6}, @litchar{7}, @litchar{8}, @litchar{9},
|
||||
@litchar{a}, @litchar{b}, @litchar{c}, @litchar{d},
|
||||
@litchar{e}, or @litchar{f} (case-insensitive). The longer form
|
||||
takes precedence over the shorter form.}
|
||||
|
||||
@item{@as-index{@litchar["\\u"]@kleenerange[1
|
||||
4]{@nonterm{digit@sub{16}}}}: like @litchar["\\x"], but with up
|
||||
to four hexadecimal digits (longer sequences take precedence).
|
||||
The resulting hexadecimal number must be a valid argument to
|
||||
@scheme[integer->char], otherwise the
|
||||
@exnraise[exn:fail:read].}
|
||||
|
||||
@item{@as-index{@litchar["\\U"]@kleenerange[1
|
||||
8]{@nonterm{digit@sub{16}}}}: like @litchar["\\x"], but with up
|
||||
to eight hexadecimal digits (longer sequences take precedence).
|
||||
The resulting hexadecimal number must be a valid argument to
|
||||
@scheme[integer->char], otherwise the
|
||||
@exnraise[exn:fail:read].}
|
||||
|
||||
@item{@as-index{@litchar["\\"]@nonterm{newline}}: elided, where
|
||||
@nonterm{newline} is either a linefeed, carriage return, or
|
||||
carriage return--linefeed combination. This convetion allows
|
||||
single-line strings to span multiple lines in the source.}
|
||||
|
||||
}
|
||||
|
||||
If the reader encounteres any other use of a backslash in a string
|
||||
constant, the @exnraise[exn:fail:read].
|
||||
|
||||
@guideintro["guide:bytestrings"]{the syntax of byte strings}
|
||||
|
||||
@index['("byte strings" "parsing")]{A} string constant preceded by
|
||||
@litchar{#} is parsed as a byte-string. (That is, @as-index{@litchar{#"}} starts
|
||||
a byte-string literal.) See @secref["mz:bytestrings"] for
|
||||
information on byte strings. Byte string constants support the same
|
||||
escape sequences as character strings, except @litchar["\\u"] and
|
||||
@litchar["\\U"].
|
||||
|
||||
When the reader encounters @as-index{@litchar{#<<}}, it starts parsing a
|
||||
@pidefterm{here string}. The characters following @litchar{#<<} until
|
||||
a newline character define a terminator for the string. The content of
|
||||
the string includes all characters between the @litchar{#<<} line and
|
||||
a line whose only content is the specified terminator. More precisely,
|
||||
the content of the string starts after a newline following
|
||||
@litchar{#<<}, and it ends before a newline that is followed by the
|
||||
terminator, where the terminator is itself followed by either a
|
||||
newline or end-of-file. No escape sequences are recognized between the
|
||||
starting and terminating lines; all characters are included in the
|
||||
string (and terminator) literally. A return character is not treated
|
||||
as a line separator in this context. If no characters appear between
|
||||
@litchar{#<<} and a newline or end-of-file, or if an end-of-file is
|
||||
encountered before a terminating line, the @exnraise[exn:fail:read].
|
||||
|
||||
@reader-examples[
|
||||
"\"Apple\""
|
||||
"\"\\x41pple\""
|
||||
"\"\\\"Apple\\\"\""
|
||||
"\"\\\\\""
|
||||
"#\"Apple\""
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-quote"]{Reading Quotes}
|
||||
|
||||
When the reader enounters @as-index{@litchar{'}}, then it recursively
|
||||
reads one datum, and it forms a new list containing the symbol
|
||||
@scheme['quote] and the following datum. This convention is mainly
|
||||
useful for reading Scheme code, where @scheme['s] can be used as a
|
||||
shorthand for @scheme[(code:quote s)].
|
||||
|
||||
Several other sequences are recognized and transformed in a similar
|
||||
way. Longer prefixes take precedence over short ones:
|
||||
|
||||
@read-quote-table[(list @litchar{'} @scheme[quote])
|
||||
(list @as-index{@litchar{`}} @scheme[quasiquote])
|
||||
(list @as-index{@litchar{,}} @scheme[unquote])
|
||||
(list @as-index{@litchar[",@"]} @scheme[unquote-splicing])
|
||||
(list @as-index{@litchar{#'}} @scheme[syntax])
|
||||
(list @as-index{@litchar{#`}} @scheme[quasisyntax])
|
||||
(list @as-index{@litchar{#,}} @scheme[unsyntax])
|
||||
(list @as-index{@litchar["#,@"]} @scheme[unsyntax-splicing])]
|
||||
|
||||
@reader-examples[
|
||||
"'apple"
|
||||
"`(1 ,2)"
|
||||
]
|
||||
|
||||
The @litchar{`}, @litchar{,}, and @litchar[",@"] forms are disabled when
|
||||
the @scheme[read-accept-quasiquote] @tech{parameter} is set to
|
||||
@scheme[#f], in which case the @exnraise[exn:fail:read], instead.
|
||||
|
||||
@section[#:tag "mz:parse-comment"]{Reading Comments}
|
||||
|
||||
A @as-index{@litchar{;}} starts a line comment. When the reader
|
||||
encounters @litchar{;}, then it skips past all characters until the
|
||||
next linefeed or carriage return.
|
||||
|
||||
A @litchar["#|"] starts a nestable block comment. When the reader
|
||||
encounters @litchar["#|"], then it skips past all characters until a
|
||||
closing @litchar["|#"]. Pairs of matching @litchar["#|"] and
|
||||
@litchar["|#"] can be nested.
|
||||
|
||||
A @litchar{#;} starts an S-expression comment. Then the reader
|
||||
encounters @litchar{#;}, it recursively reads one datum, and then
|
||||
discards the datum (continuing on to the next datum for the read
|
||||
result).
|
||||
|
||||
A @litchar{#! } (which is @litchar{#!} followed by a space) or
|
||||
@litchar{#!/} starts a line comment that can be continued to the next
|
||||
line by ending a line with @litchar["\\"]. This form of comment
|
||||
normally appears at the beginning of a Unix script file.
|
||||
|
||||
@reader-examples[
|
||||
"; comment"
|
||||
"#| a |# 1"
|
||||
"#| #| a |# 1 |# 2"
|
||||
"#;1 2"
|
||||
"#!/bin/sh"
|
||||
"#! /bin/sh"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-vector"]{Reading Vectors}
|
||||
|
||||
When the reader encounters a @litchar{#(}, @litchar{#[}, or
|
||||
@litchar["#{"], it starts parsing a vector; see @secref["vectors"] for
|
||||
information on vectors.
|
||||
|
||||
The elements of the vector are recursively read until a matching
|
||||
@litchar{)}, @litchar{]}, or @litchar["}"] is found, just as for
|
||||
lists (see @secref["mz:parse-pair"]). A delimited @litchar{.} is not
|
||||
allowed among the vector elements.
|
||||
|
||||
An optional vector length can be specified between the @litchar{#} and
|
||||
@litchar["("], @litchar["["], or @litchar["{"]. The size is specified
|
||||
using a sequence of decimal digits, and the number of elements
|
||||
provided for the vector must be no more than the specified size. If
|
||||
fewer elements are provided, the last provided element is used for the
|
||||
remaining vector slots; if no elements are provided, then @scheme[0]
|
||||
is used for all slots.
|
||||
|
||||
In @scheme[read-syntax] mode, each recursive read for the vector
|
||||
elements is also in @scheme[read-syntax] mode, so that the wrapped
|
||||
vector's elements are also wraped as syntax objects.
|
||||
|
||||
@reader-examples[
|
||||
"#(1 apple 3)"
|
||||
"#3(\"apple\" \"banana\")"
|
||||
"#3()"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-hashtable"]{Reading Hash Tables}
|
||||
|
||||
A @litchar{#hash} starts an immutable hash-table constant with key
|
||||
matching based on @scheme[equal?]. The characters after @litchar{hash}
|
||||
must parse as a list of pairs (see @secref["mz:parse-pair"]) with a
|
||||
specific use of delimited @litchar{.}: it must appear between the
|
||||
elements of each pair in the list, and nowhere in the sequence of list
|
||||
elements. The first element of each pair is used as the key for a
|
||||
table entry, and the second element of each pair is the associated
|
||||
value.
|
||||
|
||||
A @litchar{#hasheq} starts a hash table like @litchar{#hash}, except
|
||||
that it constructs a hash table based on @scheme[eq?] instead of
|
||||
@scheme[equal?].
|
||||
|
||||
In either case, the table is constructed by adding each mapping to the
|
||||
hash table from left to right, so later mappings can hide earlier
|
||||
mappings if the keys are equivalent.
|
||||
|
||||
@reader-examples[
|
||||
#:example-note @elem{, where @scheme[make-...] stands for @scheme[make-immutable-hash-table]}
|
||||
"#hash()"
|
||||
"#hasheq()"
|
||||
"#hash((\"a\" . 5))"
|
||||
"#hasheq((a . 5) (b . 7))"
|
||||
"#hasheq((a . 5) (a . 7))"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-box"]{Reading Boxes}
|
||||
|
||||
When the reader encounters a @litchar{#&}, it starts parsing a box;
|
||||
see @secref["boxes"] for information on boxes. The content of the box
|
||||
is determined by recursively reading the next datum.
|
||||
|
||||
In @scheme[read-syntax] mode, the recursive read for the box content
|
||||
is also in @scheme[read-syntax] mode, so that the wrapped box's
|
||||
content is also wraped as a syntax object.
|
||||
|
||||
@reader-examples[
|
||||
"#&17"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-character"]{Reading Characters}
|
||||
|
||||
@guideintro["guide:characters"]{the syntax of characters}
|
||||
|
||||
A @litchar["#\\"] starts a character constant, which has one of the
|
||||
following forms:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{ @litchar["#\\nul"] or @litchar["#\\null"]: NUL (ASCII 0)@nonalpha[]}
|
||||
@item{ @litchar["#\\backspace"]: backspace (ASCII 8)@nonalpha[]}
|
||||
@item{ @litchar["#\\tab"]: tab (ASCII 9)@nonalpha[]}
|
||||
@item{ @litchar["#\\newline"] or @litchar["#\\linefeed"]: linefeed (ASCII 10)@nonalpha[]}
|
||||
@item{ @litchar["#\\vtab"]: vertical tab (ASCII 11)@nonalpha[]}
|
||||
@item{ @litchar["#\\page"]: page break (ASCII 12)@nonalpha[]}
|
||||
@item{ @litchar["#\\return"]: carriage return (ASCII 13)@nonalpha[]}
|
||||
@item{ @litchar["#\\space"]: space (ASCII 32)@nonalpha[]}
|
||||
@item{ @litchar["#\\rubout"]: delete (ASCII 127)@nonalpha[]}
|
||||
|
||||
@item{@litchar["#\\"]@kleenerange[1 3]{@nonterm{digit@sub{8}}}:
|
||||
Unicode for the octal number specified by @kleenerange[1
|
||||
3]{@nonterm{digit@sub{8}}}, as in string escapes (see
|
||||
@secref["mz:parse-string"]).}
|
||||
|
||||
@item{@litchar["#\\x"]@kleenerange[1 2]{@nonterm{digit@sub{16}}}:
|
||||
Unicode for the hexadecimal number specified by @kleenerange[1
|
||||
2]{@nonterm{digit@sub{16}}}, as in string escapes (see
|
||||
@secref["mz:parse-string"]).}
|
||||
|
||||
@item{@litchar["#\\u"]@kleenerange[1 4]{@nonterm{digit@sub{16}}}:
|
||||
like @litchar["#\\x"], but with up to four hexadecimal digits.}
|
||||
|
||||
@item{@litchar["#\\U"]@kleenerange[1 6]{@nonterm{digit@sub{16}}}:
|
||||
like @litchar["#\\x"], but with up to six hexadecimal digits.}
|
||||
|
||||
@item{@litchar["#\\"]@nonterm{c}: the character @nonterm{c}, as long
|
||||
as @litchar["#\\"]@nonterm{c} and the characters following it
|
||||
do not match any of the previous cases, and as long as the
|
||||
character after @nonterm{c} is not
|
||||
@schemelink[char-alphabetic?]{alphabetic}.}
|
||||
|
||||
}
|
||||
|
||||
@reader-examples[
|
||||
"#\\newline"
|
||||
"#\\n"
|
||||
"#\\u3BB"
|
||||
"#\\\u3BB"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-keyword"]{Reading Keywords}
|
||||
|
||||
A @litchar{#:} starts a keyword. The parsing of a keyword after the
|
||||
@litchar{#:} is the same as for a symbol, including case-folding in
|
||||
case-insensitive mode, except that the part after @litchar{#:} is
|
||||
never parsed as a number.
|
||||
|
||||
@reader-examples[
|
||||
"#:Apple"
|
||||
"#:1"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-regexp"]{Reading Regular Expressions}
|
||||
|
||||
A @litchar{#rx} or @litchar{#px} starts a regular expression. The
|
||||
characters immediately after @litchar{#rx} or @litchar{#px} must parse
|
||||
as a string or byte string (see @secref["mz:parse-string"]). A
|
||||
@litchar{#rx} prefix starts a regular expression as would be
|
||||
constructed by @scheme[regexp], @litchar{#px} as
|
||||
constructed by @scheme[pregexp], @litchar{#rx#} as
|
||||
constructed by @scheme[byte-regexp], and @litchar{#px#} as
|
||||
constructed by @scheme[byte-pregexp].
|
||||
|
||||
@reader-examples[
|
||||
"#rx\".*\""
|
||||
"#px\"[\\\\s]*\""
|
||||
"#rx#\".*\""
|
||||
"#px#\"[\\\\s]*\""
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-graph"]{Reading Graph Structure}
|
||||
|
||||
A @graph-defn[] tags the following datum for reference via
|
||||
@graph-ref[], which allows the reader to produce a datum that
|
||||
have graph structure.
|
||||
|
||||
For a specific @graph-tag in a single read result, each @graph-ref[]
|
||||
reference is replaced by the datum read for the corresponding
|
||||
@graph-defn[]; the definition @graph-defn[] also produces just the
|
||||
datum after it. A @graph-defn[] definition can appear at most
|
||||
once, and a @graph-defn[] definition must appear before a @graph-ref[]
|
||||
reference appears.
|
||||
|
||||
Although a comment parsed via @litchar{#;} discards the datum
|
||||
afterward, @graph-defn[] definitions in the discarded datum
|
||||
still can be referenced by other parts of the reader input, as long as
|
||||
both the comment and the reference are grouped together by some other
|
||||
form (i.e., some recursive read); a top-level @litchar{#;} comment
|
||||
neither defines nor uses graph tags for other top-level forms.
|
||||
|
||||
@reader-examples[
|
||||
"(#1=100 #1# #1#)"
|
||||
"#0=(1 . #0#)"
|
||||
]
|
||||
|
||||
@section[#:tag "mz:parse-reader"]{Reading via an External Reader}
|
||||
|
||||
When the reader encounters @litchar{#reader}, then it loads an
|
||||
external reader procedure and applies it to the current input stream.
|
||||
|
||||
The reader recursively reads the next datum after @litchar{#reader},
|
||||
and passes it to the procedure that is the value of the
|
||||
@scheme[current-reader-guard] @tech{parameter}; the result is used as a
|
||||
module path. The module path is passed to @scheme[dynamic-require]
|
||||
with either @scheme['read] or @scheme['read-syntax] (depending on
|
||||
whether the reader is in @scheme[read] or @scheme[read-syntax]
|
||||
mode).
|
||||
|
||||
The resulting procedure should accept the same arguments as
|
||||
@scheme[read] or @scheme[read-syntax] in the case thar all optional
|
||||
arguments are provided. The procedure is given the port whose stream
|
||||
contained @litchar{#reader}, and it should produce a datum result. If
|
||||
the result is a syntax object in @scheme[read] mode, then it is
|
||||
converted to a datum using @scheme[syntax-object->datum]; if the
|
||||
result is not a syntax object in @scheme[read-syntax] mode, then it is
|
||||
converted to one using @scheme[datum->syntax-object]. See also
|
||||
@secref["special-comments"] and @secref["recursive-reads"] for
|
||||
information on special-comment results and recursive reads.
|
||||
|
||||
If the @scheme[read-accept-reader] @tech{parameter} is set to
|
||||
@scheme[#f], then if the reader encounters @litchar{#reader}, the
|
||||
@exnraise[exn:fail:read].
|
||||
|
||||
@section[#:tag "mz:readtables"]{Readtables}
|
||||
|
||||
The dispatch table in @secref["mz:default-readtable-dispatch"]
|
||||
corresponds to the default @idefterm{readtable}.
|
||||
|
||||
@section[#:tag "mz:parse-honu"]{Honu Parsing}
|
|
@ -1,7 +1,7 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
|
||||
@title{PLT Scheme Reference Manual}
|
||||
@title{PLT Scheme Reference}
|
||||
|
||||
This manual defines the core PLT Scheme language and describes its
|
||||
most prominent libraries. The companion manual
|
||||
|
@ -16,24 +16,23 @@ language.
|
|||
|
||||
@include-section["model.scrbl"]
|
||||
@include-section["syntax-model.scrbl"]
|
||||
@include-section["read.scrbl"]
|
||||
@include-section["syntax.scrbl"]
|
||||
@include-section["derived.scrbl"]
|
||||
@include-section["data.scrbl"]
|
||||
@include-section["struct.scrbl"]
|
||||
@include-section["io.scrbl"]
|
||||
@include-section["regexps.scrbl"]
|
||||
@include-section["control.scrbl"]
|
||||
@include-section["concurrency.scrbl"]
|
||||
@include-section["custodians.scrbl"]
|
||||
@include-section["security.scrbl"]
|
||||
@include-section["io.scrbl"]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
|
||||
@section{Platform-Specific Path Conventions}
|
||||
@section{Operating System}
|
||||
|
||||
@subsection[#:tag "mz:unix-path"]{Unix and Mac OS X Paths}
|
||||
@subsection{Platform-Specific Path Conventions}
|
||||
|
||||
@subsection[#:tag "mz:windows-path"]{Windows Paths}
|
||||
@subsubsection[#:tag "mz:unix-path"]{Unix and Mac OS X Paths}
|
||||
|
||||
@subsubsection[#:tag "mz:windows-path"]{Windows Paths}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
|
||||
|
|
14
collects/scribblings/reference/security.scrbl
Normal file
14
collects/scribblings/reference/security.scrbl
Normal file
|
@ -0,0 +1,14 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require[(lib "bnf.ss" "scribble")]
|
||||
@require["mz.ss"]
|
||||
|
||||
@title[#:style 'toc]{Security}
|
||||
|
||||
MzScheme offers several mechanisms for managing security, each of
|
||||
which relies on @tech{thread}- and @tech{continuation}-specific
|
||||
@tech{parameters} (see @secref["mz:parameters"]).
|
||||
|
||||
@local-table-of-contents[]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@include-section["custodians.scrbl"]
|
377
collects/scribblings/reference/string-input.scrbl
Normal file
377
collects/scribblings/reference/string-input.scrbl
Normal file
|
@ -0,0 +1,377 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require[(lib "bnf.ss" "scribble")]
|
||||
@require["mz.ss"]
|
||||
|
||||
@title{Byte and String Input}
|
||||
|
||||
@defproc[(read-char [in input-port? (current-input-port)])
|
||||
(or/c character? eof-object?)]{
|
||||
|
||||
Reads a single character from @scheme[in]---which may involve reading
|
||||
several bytes to UTF-8-decode them into a character (see
|
||||
@secref["mz:ports"]); a minimal number of bytes are read/peeked to
|
||||
perform the decoding. If no bytes are available before an end-of-file,
|
||||
then @scheme[eof] is returned.}
|
||||
|
||||
|
||||
@defproc[(read-byte [in input-port? (current-input-port)])
|
||||
(or/c byte? eof-object?)]{
|
||||
|
||||
Reads a single byte from @scheme[in]. If no bytes are available before
|
||||
an end-of-file, then @scheme[eof] is returned.}
|
||||
|
||||
|
||||
@defproc[(read-line [in input-port? (current-input-port)]
|
||||
[mode (one-of 'linefeed 'return 'return-linefeed 'any 'any-one) 'linefeed])
|
||||
(or/c string? eof-object?)]{
|
||||
|
||||
Returns a string containing the next line of bytes from @scheme[in].
|
||||
|
||||
Characters are read from @scheme[in] until a line separator or an
|
||||
end-of-file is read. The line separator is not included in the result
|
||||
string (but it is removed from the port's stream). If no characters
|
||||
are read before an end-of-file is encountered, @scheme[eof] is
|
||||
returned.
|
||||
|
||||
The @scheme[mode] argument determines the line separator(s). It
|
||||
must be one of the following symbols:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@scheme['linefeed] breaks lines on linefeed characters.}
|
||||
|
||||
@item{@scheme['return] breaks lines on return characters.}
|
||||
|
||||
@item{@scheme['return-linefeed] breaks lines on
|
||||
return-linefeed combinations. If a return character is not followed
|
||||
by a linefeed character, it is included in the result string;
|
||||
similarly, a linefeed that is not preceded by a return is included
|
||||
in the result string.}
|
||||
|
||||
@item{@scheme['any] breaks lines on any of a return
|
||||
character, linefeed character, or return-linefeed combination. If a
|
||||
return character is followed by a linefeed character, the two are
|
||||
treated as a combination.}
|
||||
|
||||
@item{@scheme['any-one] breaks lines on either a return or
|
||||
linefeed character, without recognizing return-linefeed
|
||||
combinations.}
|
||||
|
||||
}
|
||||
|
||||
Return and linefeed characters are detected after the conversions that
|
||||
are automatically performed when reading a file in text mode. For
|
||||
example, reading a file in text mode under Windows automatically
|
||||
changes return-linefeed combinations to a linefeed. Thus, when a file
|
||||
is opened in text mode, @scheme['linefeed] is usually the appropriate
|
||||
@scheme[read-line] mode.}
|
||||
|
||||
@defproc[(read-bytes-line [in input-port? (current-input-port)]
|
||||
[mode (one-of 'linefeed 'return 'return-linefeed 'any 'any-one) 'linefeed])
|
||||
(or/c bytes? eof-object?)]{
|
||||
Like @scheme[read-line], but reads bytes and produces a byte string.}
|
||||
|
||||
@defproc[(read-string [amt nonnegative-exact-integer?]
|
||||
[in input-port? (current-input-port)])
|
||||
(or/c string? eof-object)]{
|
||||
|
||||
Returns a string containing the next @scheme[amt] characters from
|
||||
@scheme[in].
|
||||
|
||||
If @scheme[amt] is @scheme[0], then the empty string is
|
||||
returned. Otherwise, if fewer than @scheme[amt] characters are
|
||||
available before an end-of-file is encountered, then the returned
|
||||
string will contain only those characters before the end-of-file; that
|
||||
is, the returned string's length will be less than @scheme[amt]. (A
|
||||
temporary string of size @scheme[amt] is allocated while reading the
|
||||
input, even if the size of the result is less than @scheme[amt]
|
||||
characters.) If no characters are available before an end-of-file,
|
||||
then @scheme[eof] is returned.
|
||||
|
||||
If an error occurs during reading, some characters may be lost; that
|
||||
is, if @scheme[read-string] successfully reads some characters before
|
||||
encountering an error, the characters are dropped.}
|
||||
|
||||
@defproc[(read-bytes [amt nonnegative-exact-integer?]
|
||||
[in input-port? (current-input-port)])
|
||||
(or/c bytes? eof-object)]{
|
||||
Like @scheme[read-string], but reads bytes and produces a byte string.}
|
||||
|
||||
@defproc[(read-string! [str (and/c string? (not/c immutable?))]
|
||||
[in input-port? (current-input-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (string-length str)])
|
||||
(or/c positive-exact-integer? eof-object?)]{
|
||||
|
||||
Reads characters from @scheme[in] like @scheme[read-string], but puts
|
||||
them into @scheme[str] starting from index @scheme[start-pos]
|
||||
(inclusive) up to @scheme[end-pos] (exclusive). Like
|
||||
@scheme[substring], the @exnraise[exn:fail:contract] if
|
||||
@scheme[start-pos] or @scheme[end-pos] is out-of-range for
|
||||
@scheme[str].
|
||||
|
||||
If the difference between @scheme[start-pos] and @scheme[end-pos] is
|
||||
@scheme[0], then @scheme[0] is returned and @scheme[str] is not
|
||||
modified. If no bytes are available before an end-of-file, then
|
||||
@scheme[eof] is returned. Otherwise, the return value is the number of
|
||||
characters read. If @math{m} characters are read and
|
||||
@math{m<@scheme[end-pos]-@scheme[start-pos]}, then @scheme[str] is
|
||||
not modified at indices @math{@scheme[start-pos]+m} though
|
||||
@scheme[end-pos].}
|
||||
|
||||
@defproc[(read-bytes! [bstr bytes?]
|
||||
[in input-port? (current-input-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(or/c positive-exact-integer? eof-object?)]{
|
||||
Like @scheme[read-string!], but reads bytes, puts them into a byte
|
||||
string, and returns the number of bytes read.}
|
||||
|
||||
@defproc[(read-bytes-avail! [bstr bytes?]
|
||||
[in input-port? (current-input-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(or/c positive-exact-integer? eof-object? procedure?)]{
|
||||
|
||||
Like @scheme[read-bytes!], but it returns without blocking after
|
||||
reading immediately-available bytes, and it may return a procedure for
|
||||
a ``special'' result. The @scheme[read-bytes-avail!] procedure blocks
|
||||
only if no bytes (or specials) are yet available. Also unlike
|
||||
@scheme[read-bytes!], @scheme[read-bytes-avail!] never drops bytes; if
|
||||
@scheme[read-bytes-avail!] successfully reads some bytes and then
|
||||
encounters an error, it suppresses the error (treating it roughly like
|
||||
an end-of-file) and returns the read bytes. (The error will be
|
||||
triggered by future reads.) If an error is encountered before any
|
||||
bytes have been read, an exception is raised.
|
||||
|
||||
When @scheme[in] produces a special value, as described in
|
||||
@secref["mz:customport"], the result is a procedure of four
|
||||
arguments. The four arguments correspond to the location of the
|
||||
special value within the port, as described in
|
||||
@secref["mz:customport"]. If the procedure is called more than once
|
||||
with valid arguments, the @exnraise[exn:fail:contract]. If
|
||||
@scheme[read-bytes-avail] returns a special-producing procedure, then
|
||||
it does not place characters in @scheme[bstr]. Similarly,
|
||||
@scheme[read-bytes-avail] places only as many bytes into @scheme[bstr]
|
||||
as are available before a special value in the port's stream.}
|
||||
|
||||
@defproc[(read-bytes-avail!* [bstr bytes?]
|
||||
[in input-port? (current-input-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(or/c nonnegative-exact-integer? eof-object? procedure?)]{
|
||||
|
||||
Like @scheme[read-bytes-avail!], but returns @scheme[0] immediately if
|
||||
no bytes (or specials) are available for reading and the end-of-file
|
||||
is not reached.}
|
||||
|
||||
@defproc[(read-bytes-avail!/enable-break [bstr bytes?]
|
||||
[in input-port? (current-input-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(or/c positive-exact-integer? eof-object? procedure?)]{
|
||||
|
||||
Like @scheme[read-bytes-avail!], but breaks are enabled during the
|
||||
read (see also @secref["mz:breakhandler"]). If breaking is disabled
|
||||
when @scheme[read-bytes-avail!/enable-break] is called, and if the
|
||||
@scheme[exn:break] exception is raised as a result of the call, then
|
||||
no bytes will have been read from @scheme[in].}
|
||||
|
||||
|
||||
@defproc[(peek-string [amt nonnegative-exact-integer?]
|
||||
[skip-bytes-amt nonnegative-exact-integer?]
|
||||
[in input-port? (current-input-port)])
|
||||
(or/c string? eof-object)]{
|
||||
|
||||
Similar to @scheme[read-string], except that the returned characters
|
||||
are preserved in the port for future reads. (More precisely, undecoded
|
||||
bytes are left for future reads.) The @scheme[skip-bytes-amt] argument
|
||||
indicates a number of bytes (@italic{not} characters) in the input
|
||||
stream to skip before collecting characters to return; thus, in total,
|
||||
the next @scheme[skip-bytes-amt] bytes plus @scheme[amt] characters
|
||||
are inspected.
|
||||
|
||||
For most kinds of ports, inspecting @scheme[skip-bytes-amt] bytes and
|
||||
@scheme[amt] characters requires at least
|
||||
@math{@scheme[skip-bytes-amt]+@scheme[amt]} bytes of memory overhead
|
||||
associated with the port, at least until the bytes/characters are
|
||||
read. No such overhead is required when peeking into a string port
|
||||
(see @secref["mz:stringport"]), a pipe port (see
|
||||
@secref["mz:pipeports"]), or a custom port with a specific peek
|
||||
procedure (depending on how the peek procedure is implemented; see
|
||||
@secref["mz:customport"]).
|
||||
|
||||
If a port produces @scheme[eof] mid-stream, peek skips beyond the
|
||||
@scheme[eof] always produce @scheme[eof] until the @scheme[eof] is
|
||||
read.}
|
||||
|
||||
@defproc[(peek-bytes [amt nonnegative-exact-integer?]
|
||||
[skip-bytes-amt nonnegative-exact-integer?]
|
||||
[in input-port? (current-input-port)])
|
||||
(or/c bytes? eof-object)]{
|
||||
Like @scheme[peek-string], but peeks bytes and produces a byte string.}
|
||||
|
||||
@defproc[(peek-string! [str (and/c string? (not/c immutable?))]
|
||||
[skip-bytes-amt nonnegative-exact-integer?]
|
||||
[in input-port? (current-input-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (string-length str)])
|
||||
(or/c positive-exact-integer? eof-object?)]{
|
||||
Like @scheme[read-string!], but for peeking, and with a
|
||||
@scheme[skip-bytes-amt] argument like @scheme[peek-string].}
|
||||
|
||||
@defproc[(peek-bytes! [bstr (and/c bytes? (not/c immutable?))]
|
||||
[skip-bytes-amt nonnegative-exact-integer?]
|
||||
[in input-port? (current-input-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(or/c positive-exact-integer? eof-object?)]{
|
||||
Like @scheme[peek-string!], but peeks bytes, puts them into a byte
|
||||
string, and returns the number of bytes read.}
|
||||
|
||||
@defproc[(peek-bytes-avail! [bstr (and/c bytes? (not/c immutable?))]
|
||||
[skip-bytes-amt nonnegative-exact-integer?]
|
||||
[progress (or/c evt? false/c) #f]
|
||||
[in input-port? (current-input-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(or/c nonnegative-exact-integer? eof-object? procedure?)]{
|
||||
|
||||
Like @scheme[read-bytes-avail!], but for peeking, and with two extra
|
||||
arguments. The @scheme[skip-bytes-amt] argument is as in
|
||||
@scheme[peek-bytes]. The @scheme[progress] argument must be either
|
||||
@scheme[#f] or an event produced by
|
||||
@scheme[port-progress-evt] for @scheme[in].
|
||||
|
||||
To peek, @scheme[peek-bytes-avail!] blocks until finding an
|
||||
end-of-file, at least one byte (or special) past the skipped bytes, or
|
||||
until a non-@scheme[#f] @scheme[progress] becomes ready. Furthermore,
|
||||
if @scheme[progress] is ready before bytes are peeked, no bytes are
|
||||
peeked or skipped, and @scheme[progress] may cut short the skipping
|
||||
process if it becomes available during the peek attempt.
|
||||
|
||||
The result of @scheme[peek-bytes-avail!] is @scheme[0] only in the
|
||||
case that @scheme[progress] becomes ready before bytes are peeked.}
|
||||
|
||||
@defproc[(peek-bytes-avail!* [bstr (and/c bytes? (not/c immutable?))]
|
||||
[skip-bytes-amt nonnegative-exact-integer?]
|
||||
[progress (or/c evt? false/c) #f]
|
||||
[in input-port? (current-input-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(or/c nonnegative-exact-integer? eof-object? procedure?)]{
|
||||
|
||||
Like @scheme[read-bytes-avail!*], but for peeking, and with
|
||||
@scheme[skip-bytes-amt] and @scheme[progress] arguments like
|
||||
@scheme[peek-bytes-avail!]. Since this procedure never blocks, it may
|
||||
return before even @scheme[skip-amt] bytes are available from the
|
||||
port.}
|
||||
|
||||
@defproc[(peek-bytes-avail!/enable-break [bstr (and/c bytes? (not/c immutable?))]
|
||||
[skip-bytes-amt nonnegative-exact-integer?]
|
||||
[progress (or/c evt? false/c) #f]
|
||||
[in input-port? (current-input-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(or/c nonnegative-exact-integer? eof-object? procedure?)]{
|
||||
Like @scheme[read-bytes-avail!/enable-break], but for peeking, and
|
||||
with @scheme[skip-bytes-amt] and @scheme[progress] arguments like
|
||||
@scheme[peek-bytes-avail!].}
|
||||
|
||||
|
||||
@defproc[(read-char-or-special [in input-port? (current-input-port)])
|
||||
(or/c character? eof-object? any/c)]{
|
||||
|
||||
Like @scheme[read-char], but that if the input port returns a non-byte
|
||||
value (through a value-generating procedure in a custom port; see
|
||||
@secref["mz:customport"] and @secref["mz:special-comments"] for
|
||||
details), the non-byte value is returned.}
|
||||
|
||||
@defproc[(read-byte-or-special [in input-port? (current-input-port)])
|
||||
(or/c byte? eof-object? any/c)]{
|
||||
|
||||
Like @scheme[read-char-or-special], but reads and returns a byte
|
||||
instead of a character.}
|
||||
|
||||
@defproc[(peek-char [in input-port? (current-input-port)]
|
||||
[skip-bytes-amt nonnegative-exact-integer? 0])
|
||||
(or/c character? eof-object?)]{
|
||||
|
||||
Like @scheme[read-char], but peeks instead of reading, and skipping
|
||||
@scheme[skip-bytes-amt] bytes (not characters) at the start of the
|
||||
port.}
|
||||
|
||||
@defproc[(peek-byte [in input-port? (current-input-port)]
|
||||
[skip-bytes-amt nonnegative-exact-integer? 0])
|
||||
(or/c byte? eof-object?)]{
|
||||
|
||||
Like @scheme[peek-char], but reads and returns a byte instead of a
|
||||
character.}
|
||||
|
||||
@defproc[(peek-char-or-special [in input-port? (current-input-port)]
|
||||
[skip-bytes-amt nonnegative-exact-integer? 0])
|
||||
(or/c character? eof-object? any/c)]{
|
||||
|
||||
Like @scheme[peek-char], but if the input port returns a non-byte
|
||||
value after @scheme[skip-bytes-amt] byte positions, it is returned.}
|
||||
|
||||
@defproc[(peek-byte-or-special [in input-port? (current-input-port)]
|
||||
[skip-bytes-amt nonnegative-exact-integer? 0]
|
||||
[progress (or/c evt? false/c) #f])
|
||||
(or/c character? eof-object? any/c)]{
|
||||
|
||||
Like @scheme[peek-char-or-special], but reads and returns a byte
|
||||
instead of a character, and it supports a @scheme[progress] argument
|
||||
like @scheme[peek-bytes-avail!].}
|
||||
|
||||
@defproc[(port-progress-evt [in input-port? (current-input-port)])
|
||||
evt?]{
|
||||
|
||||
Returns an event that becomes ready after any subsequent read from
|
||||
@scheme[in], or after @scheme[in] is closed. After the event becomes
|
||||
ready, it remains ready. If progress events are unavailable for
|
||||
@scheme[in] (as reported by @scheme[port-provides-progress-evts?]) the
|
||||
@exnraise[exn:fail:contract].}
|
||||
|
||||
@defproc[(port-provides-progress-evts? [in input-port?]) boolean]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[port-progress-evt] can return an event
|
||||
for @scheme[in]. All built-in kinds of ports support progress events,
|
||||
but ports created with @scheme[make-input-port] (see
|
||||
@secref["mz:customport"]) may not.}
|
||||
|
||||
@defproc[(port-commit-peeked [amt nonnegative-exact-integer?]
|
||||
[progress evt?]
|
||||
[evt evt?]
|
||||
[in input-port? (current-input-port)])
|
||||
boolean?]{
|
||||
|
||||
Attempts to commit as read the first @scheme[amt] previously peeked
|
||||
bytes, non-byte specials, and @scheme[eof]s from @scheme[in], or the
|
||||
first @scheme[eof] or special value peeked from
|
||||
@scheme[in]. (Only mid-stream @scheme[eof]s can be
|
||||
committed. A @scheme[eof] when the port is exhausted does not
|
||||
correspond to data in the stream.)
|
||||
|
||||
The read commits only if @scheme[progress] does not become ready first
|
||||
(i.e., if no other process reads from @scheme[in] first), and only if
|
||||
@scheme[evt] is chosen by a @scheme[sync] within
|
||||
@scheme[port-commit-peeked] (in which case the event result is
|
||||
ignored); the @scheme[evt] must be either a channel-put event,
|
||||
channel, semaphore, semaphore-peek event, always event, or never
|
||||
event. Suspending the thread that calls @scheme[port-commit-peeked]
|
||||
may or may not prevent the commit from proceeding.
|
||||
|
||||
The result from @scheme[port-commit-peeked] is @scheme[#t] if data is
|
||||
committed, and @scheme[#f] otherwise.
|
||||
|
||||
If no data has been peeked from @scheme[in] and @scheme[progress] is
|
||||
not ready, then @exnraise[exn:fail:contract]. If fewer than
|
||||
@scheme[amt] items have been peeked at the current start of
|
||||
@scheme[in]'s stream, then only the peeked items are committed as
|
||||
read. If @scheme[in]'s stream currently starts at an @scheme[eof] or
|
||||
a non-byte special value, then only the @scheme[eof] or special value
|
||||
is committed as read.
|
||||
|
||||
If @scheme[progress] is not a result of @scheme[port-progress-evt]
|
||||
applied to @scheme[in], then @exnraise[exn:fail:contract].}
|
150
collects/scribblings/reference/string-output.scrbl
Normal file
150
collects/scribblings/reference/string-output.scrbl
Normal file
|
@ -0,0 +1,150 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require[(lib "bnf.ss" "scribble")]
|
||||
@require["mz.ss"]
|
||||
|
||||
@title{Byte and String Output}
|
||||
|
||||
@defproc[(write-char [char character?][out output-port? (current-output-port)])
|
||||
void?]{
|
||||
|
||||
Writes a single character to @scheme[out]; more precisely, the bytes
|
||||
that are the UTF-8 encoding of @scheme[char] are written to
|
||||
@scheme[out].}
|
||||
|
||||
@defproc[(write-byte [byte any/c][out output-port? (current-output-port)])
|
||||
void?]{
|
||||
|
||||
Writes a single byte to @scheme[out].}
|
||||
|
||||
@defproc[(write-string [str string?]
|
||||
[out output-port? (current-output-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (string-length str)])
|
||||
void?]{
|
||||
|
||||
Writes characters to @scheme[out] from @scheme[str] starting from
|
||||
index @scheme[start-pos] (inclusive) up to @scheme[end-pos]
|
||||
(exclusive). Like @scheme[substring], the @exnraise[exn:fail:contract]
|
||||
if @scheme[start-pos] or @scheme[end-pos] is out-of-range for
|
||||
@scheme[str].
|
||||
|
||||
The result is the number of characters written to @scheme[out], which
|
||||
is always @scheme[(- end-pos start-pos)].}
|
||||
|
||||
@defproc[(write-bytes [bstr bytes?]
|
||||
[out output-port? (current-output-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
void?]{
|
||||
|
||||
Like @scheme[write-string], but writes bytes instead of characters.}
|
||||
|
||||
@defproc[(write-bytes-avail [bstr bytes?]
|
||||
[out output-port? (current-output-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
nonnegative-exact-integer?]{
|
||||
|
||||
Like @scheme[write-bytes], but returns without blocking after writing
|
||||
as many bytes as it can immediately flush. It blocks only if no bytes
|
||||
can be flushed immediately. The result is the number of bytes written
|
||||
and flushed to @scheme[out]; if @scheme[start-pos] is the same as
|
||||
@scheme[end-pos], then the result can be @scheme[0] (indicating a
|
||||
successful flush of any buffered data), otherwise the result is at
|
||||
least @scheme[1] but possibly less than @scheme[(- end-pos
|
||||
start-pos)].
|
||||
|
||||
The @scheme[write-bytes-avail] procedure never drops bytes; if
|
||||
@scheme[write-bytes-avail] successfully writes some bytes and then
|
||||
encounters an error, it suppresses the error and returns the number of
|
||||
written bytes. (The error will be triggered by future writes.) If an
|
||||
error is encountered before any bytes have been written, an exception
|
||||
is raised.}
|
||||
|
||||
@defproc[(write-bytes-avail* [bstr bytes?]
|
||||
[out output-port? (current-output-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(or/c nonnegative-exact-integer? false/c)]{
|
||||
|
||||
Like @scheme[write-bytes-avail], but never blocks, returns @scheme[#f]
|
||||
if the port contains buffered data that cannot be written immediately,
|
||||
and returns @scheme[0] if the port's internal buffer (if any) is
|
||||
flushed but no additional bytes can be written immediately.}
|
||||
|
||||
@defproc[(write-bytes-avail/enable-break [bstr bytes?]
|
||||
[out output-port? (current-output-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
nonnegative-exact-integer?]{
|
||||
|
||||
Like @scheme[write-bytes-avail], except that breaks are enabled during
|
||||
the write. The procedure provides a guarantee about the interaction of
|
||||
writing and breaks: if breaking is disabled when
|
||||
@scheme[write-bytes-avail/enable-break] is called, and if the
|
||||
@scheme[exn:break] exception is raised as a result of the call, then
|
||||
no bytes will have been written to @scheme[out]. See also
|
||||
@secref["mz:breakhandler"].}
|
||||
|
||||
@defproc[(write-special [v any/c][out output-port? (current-output-port)]) boolean?]{
|
||||
|
||||
Writes @scheme[v] directly to @scheme[out] if the port supports
|
||||
special writes, or raises @scheme[exn:fail:contract] if the port does
|
||||
not support special write. The result is always @scheme[#t],
|
||||
indicating that the write succeeded.}
|
||||
|
||||
@defproc[(write-special-avail* [v any/c][out output-port? (current-output-port)]) boolean?]{
|
||||
|
||||
Like @scheme[write-special], but without blocking. If @scheme[v]
|
||||
cannot be written immediately, the result is @scheme[#f] without
|
||||
writing @scheme[v], otherwise the result is @scheme[#t] and @scheme[v]
|
||||
is written.}
|
||||
|
||||
@defproc[(write-bytes-avail-evt [bstr bytes?]
|
||||
[out output-port? (current-output-port)]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
evt?]{
|
||||
|
||||
Similar to @scheme[write-bytes-avail], but instead of writing bytes
|
||||
immediately, it returns a synchronizable event (see
|
||||
@secref["mz:sync"]). The @scheme[out] must support atomic writes, as
|
||||
indicated by @scheme[port-writes-atomic?].
|
||||
|
||||
Synchronizing on the object starts a write from @scheme[bstr], and the
|
||||
event becomes ready when bytes are written (unbuffered) to the
|
||||
port. If @scheme[start-pos] and @scheme[end-pos] are the same, then
|
||||
the synchronization result is @scheme[0] when the port's internal
|
||||
buffer (if any) is flushed, otherwise the result is a positive exact
|
||||
integer. If the event is not selected in a synchronization, then no
|
||||
bytes will have been written to @scheme[out].}
|
||||
|
||||
@defproc[(write-special-evt [v any/c][out output-port? (current-output-port)]) evt?]{
|
||||
|
||||
Similar to @scheme[write-special], but instead of writing the special
|
||||
value immediately, it returns a synchronizable event (see
|
||||
@secref["mz:sync"]). The @scheme[out] must support atomic writes, as
|
||||
indicated by @scheme[port-writes-atomic?].
|
||||
|
||||
Synchronizing on the object starts a write of the special value, and
|
||||
the event becomes ready when the value is written (unbuffered) to the
|
||||
port. If the event is not selected in a synchronization, then no value
|
||||
will have been written to @scheme[out].}
|
||||
|
||||
@defproc[(port-writes-atomic? [out output-port?]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[write-bytes-avail/enable-break] can
|
||||
provide an exclusive-or guarantee (break or write, but not both) for
|
||||
@scheme[out], and if the port can be used with procedures like
|
||||
@scheme[write-bytes-avail-evt]. Scheme's file-stream ports, pipes,
|
||||
string ports, and TCP ports all support atomic writes; ports created
|
||||
with @scheme[make-output-port] (see @secref["mz:customport"]) may
|
||||
support atomic writes.}
|
||||
|
||||
@defproc[(port-writes-special? [out output-port?]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if procedures like @scheme[write-special] can
|
||||
write arbitrary values to the port. Scheme's file-stream ports,
|
||||
pipes, string ports, and TCP ports all reject special values, but
|
||||
ports created with @scheme[make-output-port] (see
|
||||
@secref["mz:customport"]) may support them.}
|
|
@ -15,8 +15,6 @@ accessed and changed with type-specific @tech{accessor} and
|
|||
@tech{predicate} procedure that answers @scheme[#t] for instances of
|
||||
the structure type and @scheme[#f] for any other value.
|
||||
|
||||
@refalso["mz:define-struct"]{structure types via @scheme[define-struct]}
|
||||
|
||||
A structure type's fields are essentially unnamed, though names are
|
||||
supported for error-reporting purposes. The constructor procedure
|
||||
takes one value for each field of the structure type, except that some
|
||||
|
@ -56,6 +54,9 @@ results of applying @scheme[struct->vector] to the structs are
|
|||
@scheme[equal?]. (Consequently, @scheme[equal?] testing for structures
|
||||
depends on the current inspector.)
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@include-section["define-struct.scrbl"]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:creatingmorestructs"]{Creating Structure Types}
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
|
||||
@define[cvt (schemefont "CVT")]
|
||||
|
||||
@title[#:tag "mz:syntax" #:style 'toc]{Core Syntactic Forms}
|
||||
@title[#:tag "mz:syntax" #:style 'toc]{Syntactic Forms}
|
||||
|
||||
This section describes core syntax forms that apear in a fully
|
||||
expanded expression, plus a few closely-related non-core forms.
|
||||
This section describes the core syntax forms that apear in a fully
|
||||
expanded expression, plus a many closely-related non-core forms.
|
||||
|
||||
@local-table-of-contents[]
|
||||
|
||||
|
@ -465,7 +465,7 @@ and in the @scheme[body]s.
|
|||
]}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:if"]{Conditionals: @scheme[if]}
|
||||
@section[#:tag "mz:if"]{Conditionals: @scheme[if], @scheme[cond], @scheme[and], and @scheme[or]}
|
||||
|
||||
@guideintro["guide:conditionals"]{conditionals}
|
||||
|
||||
|
@ -483,6 +483,112 @@ position with respect to the @scheme[if] form.
|
|||
(if (positive? 5) 1 (error "doesn't get here"))
|
||||
]}
|
||||
|
||||
@defform/subs[#:literals (else =>)
|
||||
(cond cond-clause ...)
|
||||
([cond-clause [test-expr then-expr ...+]
|
||||
[else then-expr ...+]
|
||||
[test-expr => proc-expr]
|
||||
[test-expr]])]{
|
||||
|
||||
@guideintro["guide:cond"]{@scheme[cond]}
|
||||
|
||||
A @scheme[cond-clause] that starts with @scheme[else] must be the last
|
||||
@scheme[cond-clause].
|
||||
|
||||
If no @scheme[cond-clause]s are present, the result is @|void-const|.
|
||||
|
||||
If only a @scheme[[else then-expr ...+]] is present, then the
|
||||
@scheme[then-expr]s are evaluated. The results from all but the last
|
||||
@scheme[then-expr] are ignored. The results of the last
|
||||
@scheme[then-expr], which is in tail position with respect to the
|
||||
@scheme[cond] form, provides the result for the whole @scheme[cond]
|
||||
form.
|
||||
|
||||
Otherwise, the first @scheme[test-expr] is evaluated. If it produces
|
||||
@scheme[#f], then the result is the same as a @scheme[cond] form with
|
||||
the remaining @scheme[cond-clause]s, in tail position with respect to
|
||||
the original @scheme[cond] form. Otherwise, evaluation depends on the
|
||||
form of the @scheme[cond-clause]:
|
||||
|
||||
@specsubform[[test-expr then-expr ...+]]{The @scheme[then-expr]s are
|
||||
evaluated in order, and the results from all but the last
|
||||
@scheme[then-expr] are ignored. The results of the last
|
||||
@scheme[then-expr], which is in tail position with respect to the
|
||||
@scheme[cond] form, provides the result for the whole @scheme[cond]
|
||||
form.}
|
||||
|
||||
@specsubform[#:literals (=>) [test-expr => proc-expr]]{The @scheme[proc-expr] is
|
||||
evaluated, and it must produce a procedure that accepts on argument,
|
||||
otherwise the @exnraise[exn:fail:contract]. The procedure is applied
|
||||
to the result of @scheme[test-expr] in tail position with respect to
|
||||
the @scheme[cond] expression.}
|
||||
|
||||
@specsubform[[test-expr]]{The result of the @scheme[test-expr] is
|
||||
returned as the result of the @scheme[cond] form. The
|
||||
@scheme[test-expr] is not in tail position.}
|
||||
|
||||
@examples[
|
||||
(cond)
|
||||
(cond
|
||||
[else 5])
|
||||
(cond
|
||||
[(positive? -5) (error "doesn't get here")]
|
||||
[(zero? -5) (error "doesn't get here, either")]
|
||||
[(positive? 5) 'here])
|
||||
(cond
|
||||
[(member 2 '(1 2 3)) => (lambda (l) (map - l))])
|
||||
(cond
|
||||
[(member 2 '(1 2 3))])
|
||||
]}
|
||||
|
||||
@defform[(and expr ...)]{
|
||||
|
||||
@guideintro["guide:and+or"]{@scheme[and]}
|
||||
|
||||
If no @scheme[expr]s are provided, then result is @scheme[#f].
|
||||
|
||||
If a single @scheme[expr] is provided, then it is in tail position, so
|
||||
the results of the @scheme[and] expression are the results of the
|
||||
@scheme[expr].
|
||||
|
||||
Otherwise, the first @scheme[expr] is evaluated. If it produces
|
||||
@scheme[#f], the result of the @scheme[and] expression is
|
||||
@scheme[#f]. Otherwise, the result is the same as an @scheme[and]
|
||||
expression with the remaining @scheme[expr]s in tail position with
|
||||
respect to the original @scheme[and] form.
|
||||
|
||||
@examples[
|
||||
(and)
|
||||
(and 1)
|
||||
(and (values 1 2))
|
||||
(and #f (error "doesn't get here"))
|
||||
(and #t 5)
|
||||
]}
|
||||
|
||||
@defform[(or expr ...)]{
|
||||
|
||||
@guideintro["guide:and+or"]{@scheme[or]}
|
||||
|
||||
If no @scheme[expr]s are provided, then result is @scheme[#t].
|
||||
|
||||
If a single @scheme[expr] is provided, then it is in tail position, so
|
||||
the results of the @scheme[and] expression are the results of the
|
||||
@scheme[expr].
|
||||
|
||||
Otherwise, the first @scheme[expr] is evaluated. If it produces a
|
||||
value other than @scheme[#f], that result is the result of the
|
||||
@scheme[or] expression. Otherwise, the result is the same as an
|
||||
@scheme[or] expression with the remaining @scheme[expr]s in tail
|
||||
position with respect to the original @scheme[or] form.
|
||||
|
||||
@examples[
|
||||
(or)
|
||||
(or 1)
|
||||
(or (values 1 2))
|
||||
(or 5 (error "doesn't get here"))
|
||||
(or #f 5)
|
||||
]}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:define"]{Definitions: @scheme[define] and @scheme[define-values]}
|
||||
|
||||
|
@ -600,6 +706,38 @@ in tail position only if no @scheme[body]s are present.
|
|||
(printf "hi\n"))
|
||||
]}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:when+unless"]{Guarded Evaluation: @scheme[when] and @scheme[unless]}
|
||||
|
||||
@guideintro["guide:when+unless"]{@scheme[when] and @scheme[unless]}
|
||||
|
||||
@defform[(when test-expr expr ...)]{
|
||||
|
||||
Evaluates the @scheme[text-expr]. If the result is any value other
|
||||
than @scheme[#f], the @scheme[expr]s are evaluated, and the results
|
||||
are ignored. No @scheme[expr] is in tail position with respect to the
|
||||
@scheme[when] form.
|
||||
|
||||
@examples[
|
||||
(when (positive? -5)
|
||||
(display "hi"))
|
||||
(when (positive? 5)
|
||||
(display "hi")
|
||||
(display " there"))
|
||||
]}
|
||||
|
||||
@defform[(unless test-expr expr ...)]{
|
||||
|
||||
Equivalent to @scheme[(when (not test-expr) expr ...)].
|
||||
|
||||
@examples[
|
||||
(unless (positive? 5)
|
||||
(display "hi"))
|
||||
(unless (positive? -5)
|
||||
(display "hi")
|
||||
(display " there"))
|
||||
]}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:set!"]{Assignment: @scheme[set!] and @scheme[set!-values]}
|
||||
|
||||
|
@ -638,6 +776,8 @@ corresponding value from @scheme[expr] in the same way as for
|
|||
(list a b))
|
||||
]}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@include-section["for.scrbl"]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:wcm"]{Continuation Marks: @scheme[with-continuation-mark]}
|
||||
|
|
129
collects/scribblings/reference/write.scrbl
Normal file
129
collects/scribblings/reference/write.scrbl
Normal file
|
@ -0,0 +1,129 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require[(lib "bnf.ss" "scribble")]
|
||||
@require["mz.ss"]
|
||||
|
||||
@define[(FmtMark . s) (apply litchar "~" s)]
|
||||
|
||||
@title{Writing}
|
||||
|
||||
@defproc[(write [datum any/c][out output-port? (current-output-port)])
|
||||
void?]{
|
||||
|
||||
Writes @scheme[datum] to @scheme[out], normally in such a way that
|
||||
instances of core datatypes can be read back in. If @scheme[out] has a
|
||||
handler associated to it via @scheme[port-write-handler], then the
|
||||
handler is called. Otherwise, the default printer is used (in
|
||||
@scheme[write] mode), as configured by various parameters.
|
||||
|
||||
See @secref["mz:printer"] for more information about the default
|
||||
printer.}
|
||||
|
||||
@defproc[(display [datum any/c][out output-port? (current-output-port)])
|
||||
void?]{
|
||||
|
||||
Displays @scheme[datum] to @scheme[out], similar to @scheme[write],
|
||||
but usually in such a way that byte- and character-based datatypes are
|
||||
written as raw bytes or characters. If @scheme[out] has a handler
|
||||
associated to it via @scheme[port-display-handler], then the handler
|
||||
is called. Otherwise, the default printer is used (in @scheme[display]
|
||||
mode), as configured by various parameters.
|
||||
|
||||
See @secref["mz:printer"] for more information about the default
|
||||
printer.}
|
||||
|
||||
@defproc[(print [datum any/c][out output-port? (current-output-port)])
|
||||
void?]{
|
||||
|
||||
Writes @scheme[datum] to @scheme[out], normally the same way as
|
||||
@scheme[write]. If @scheme[out] has a handler associated to it via
|
||||
@scheme[port-print-handler], then the handler is called. Otherwise,
|
||||
the handler specified by @scheme[global-port-print-handler] is called;
|
||||
the default handler uses the default printer in @scheme[write] mode.
|
||||
|
||||
The rationale for providing @scheme[print] is that @scheme[display]
|
||||
and @scheme[write] both have relatively standard output conventions,
|
||||
and this standardization restricts the ways that an environment can
|
||||
change the behavior of these procedures. No output conventions should
|
||||
be assumed for @scheme[print], so that environments are free to modify
|
||||
the actual output generated by @scheme[print] in any way.}
|
||||
|
||||
|
||||
@defproc[(fprintf [out output-port?][form string?][v any/c] ...) void?]{
|
||||
|
||||
Prints formatted output to @scheme[out], where @scheme[form] is a string
|
||||
that is printed directly, except for special formatting
|
||||
escapes:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@FmtMark{n} or @FmtMark{%} prints a newline}
|
||||
|
||||
@item{@FmtMark{a} or @FmtMark{A} @scheme[display]s the next argument
|
||||
among the @scheme[v]s}
|
||||
|
||||
@item{@FmtMark{s} or @FmtMark{S} @scheme[write]s the next argument
|
||||
among the @scheme[v]s}
|
||||
|
||||
@item{@FmtMark{v} or @FmtMark{V} @scheme[print]s the next argument
|
||||
among the @scheme[v]s}
|
||||
|
||||
@item{@FmtMark{e} or @FmtMark{E} outputs the next argument among the
|
||||
@scheme[v]s using the current error value conversion handler (see
|
||||
@scheme[error-value->string-handler]) and current error printing
|
||||
width} @item{@FmtMark{c} or @FmtMark{C} @scheme[write-char]s the
|
||||
next argument in @scheme[v]s; if the next argument is not a
|
||||
character, the @exnraise[exn:fail:contract]}
|
||||
|
||||
@item{@FmtMark{b} or @FmtMark{B} prints the next argument among the
|
||||
@scheme[v]s in binary; if the next argument is not an exact number, the
|
||||
@exnraise[exn:fail:contract]}
|
||||
|
||||
@item{@FmtMark{o} or @FmtMark{O} prints the next argument among the
|
||||
@scheme[v]s in octal; if the next argument is not an exact number, the
|
||||
@exnraise[exn:fail:contract]}
|
||||
|
||||
@item{@FmtMark{x} or @FmtMark{X} prints the next argument among the
|
||||
@scheme[v]s in hexadecimal; if the next argument is not an exact
|
||||
number, the @exnraise[exn:fail:contract]}
|
||||
|
||||
@item{@FmtMark{~} prints a tilde.}
|
||||
|
||||
@item{@FmtMark{}@nonterm{w}, where @nonterm{w} is a whitespace character,
|
||||
skips characters in @scheme[form] until a non-whitespace
|
||||
character is encountered or until a second end-of-line is
|
||||
encountered (whichever happens first). An end-of-line is either
|
||||
@scheme[#\return], @scheme[#\newline], or @scheme[#\return] followed
|
||||
immediately by @scheme[#\newline] (on all platforms).}
|
||||
|
||||
}
|
||||
|
||||
The @scheme[form] string must not contain any @litchar{~} that is
|
||||
not one of the above escapes, otherwise the
|
||||
@exnraise[exn:fail:contract]. When the format string requires more
|
||||
@scheme[v]s than are supplied, the
|
||||
@exnraise[exn:fail:contract]. Similarly, when more @scheme[v]s are
|
||||
supplied than are used by the format string, the
|
||||
@exnraise[exn:fail:contract].
|
||||
|
||||
@examples[
|
||||
(fprintf (current-output-port)
|
||||
"~a as a string is ~s.~n"
|
||||
'(3 4)
|
||||
"(3 4)")
|
||||
]}
|
||||
|
||||
@defproc[(printf [form string?][v any/c] ...) void?]{
|
||||
The same as @scheme[(fprintf (current-output-port) form v ...)].}
|
||||
|
||||
@defproc[(format [form string?][v any/c] ...) string?]{
|
||||
Formats to a string. The result is the same as
|
||||
|
||||
@schemeblock[
|
||||
(let ([o (open-output-string)])
|
||||
(fprintf o form v ...)
|
||||
(get-output-string o))
|
||||
]
|
||||
|
||||
@examples[
|
||||
(format "~a as a string is ~s.~n" '(3 4) "(3 4)")
|
||||
]}
|
Loading…
Reference in New Issue
Block a user