change scribble to use new-lambda and new-struct, and correlate definitions and uses via lexical binding
svn: r6714
|
@ -1,9 +1,8 @@
|
|||
|
||||
(module basic mzscheme
|
||||
(module basic (lib "new-lambda.ss" "scribblings")
|
||||
(require "decode.ss"
|
||||
"struct.ss"
|
||||
"config.ss"
|
||||
(lib "kw.ss")
|
||||
(lib "list.ss")
|
||||
(lib "class.ss"))
|
||||
|
||||
|
@ -19,23 +18,23 @@
|
|||
(content->string content)
|
||||
"_"))
|
||||
|
||||
(define/kw (title #:key [tag #f] [style #f] #:body str)
|
||||
(define (title #:tag [tag #f] #:style [style #f] . str)
|
||||
(let ([content (decode-content str)])
|
||||
(make-title-decl (or tag (gen-tag content)) style content)))
|
||||
|
||||
(define/kw (section #:key [tag #f] #:body str)
|
||||
(define (section #:tag [tag #f] . str)
|
||||
(let ([content (decode-content str)])
|
||||
(make-part-start 0 (or tag (gen-tag content)) content)))
|
||||
|
||||
(define/kw (subsection #:key [tag #f] #:body str)
|
||||
(define (subsection #:tag [tag #f] . str)
|
||||
(let ([content (decode-content str)])
|
||||
(make-part-start 1 (or tag (gen-tag content)) content)))
|
||||
|
||||
(define/kw (subsubsection #:key [tag #f] #:body str)
|
||||
(define (subsubsection #:tag [tag #f] . str)
|
||||
(let ([content (decode-content str)])
|
||||
(make-part-start 2 (or tag (gen-tag content)) content)))
|
||||
|
||||
(define/kw (subsubsub*section #:key [tag #f] #:body str)
|
||||
(define (subsubsub*section #:tag [tag #f] . str)
|
||||
(let ([content (decode-content str)])
|
||||
(make-paragraph (list (make-element 'bold content)))))
|
||||
|
||||
|
@ -50,7 +49,7 @@
|
|||
|
||||
(provide itemize item item?)
|
||||
|
||||
(define/kw (itemize #:body items)
|
||||
(define (itemize . items)
|
||||
(let ([items (filter (lambda (v) (not (whitespace? v))) items)])
|
||||
(for-each (lambda (v)
|
||||
(unless (an-item? v)
|
||||
|
@ -63,7 +62,7 @@
|
|||
(define-struct an-item (flow))
|
||||
(define (item? x) (an-item? x))
|
||||
|
||||
(define/kw (item #:body str)
|
||||
(define (item . str)
|
||||
(make-an-item (decode-flow str)))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
@ -77,28 +76,28 @@
|
|||
(define (hspace n)
|
||||
(make-element 'hspace (list (make-string n #\space))))
|
||||
|
||||
(define/kw (elem #:body str)
|
||||
(define (elem . str)
|
||||
(make-element #f (decode-content str)))
|
||||
|
||||
(define/kw (aux-elem #:body s)
|
||||
(define (aux-elem . s)
|
||||
(make-aux-element #f (decode-content s)))
|
||||
|
||||
(define/kw (italic #:body str)
|
||||
(define (italic . str)
|
||||
(make-element 'italic (decode-content str)))
|
||||
|
||||
(define/kw (bold #:body str)
|
||||
(define (bold . str)
|
||||
(make-element 'bold (decode-content str)))
|
||||
|
||||
(define/kw (tt #:body str)
|
||||
(define (tt . str)
|
||||
(make-element 'tt (decode-content str)))
|
||||
|
||||
(define/kw (span-class classname #:body str)
|
||||
(define (span-class classname . str)
|
||||
(make-element classname (decode-content str)))
|
||||
|
||||
(define/kw (subscript #:body str)
|
||||
(define (subscript . str)
|
||||
(make-element 'subscript (decode-content str)))
|
||||
|
||||
(define/kw (superscript #:body str)
|
||||
(define (superscript . str)
|
||||
(make-element 'superscript (decode-content str)))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
@ -116,20 +115,20 @@
|
|||
word-seq
|
||||
element-seq))
|
||||
|
||||
(define/kw (index* word-seq content-seq #:body s)
|
||||
(define (index* word-seq content-seq . s)
|
||||
(let ([key (gen-target)])
|
||||
(record-index word-seq
|
||||
content-seq
|
||||
key
|
||||
(decode-content s))))
|
||||
|
||||
(define/kw (index word-seq #:body s)
|
||||
(define (index word-seq . s)
|
||||
(let ([word-seq (if (string? word-seq)
|
||||
(list word-seq)
|
||||
word-seq)])
|
||||
(apply index* word-seq word-seq s)))
|
||||
|
||||
(define/kw (as-index #:body s)
|
||||
(define (as-index . s)
|
||||
(let ([key (gen-target)]
|
||||
[content (decode-content s)])
|
||||
(record-index (list (content->string content))
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
|
||||
(module doclang mzscheme
|
||||
(module doclang (lib "new-lambda.ss" "scribblings") ; <--- temporary
|
||||
(require "struct.ss"
|
||||
"decode.ss"
|
||||
(lib "kw.ss"))
|
||||
(require-for-syntax (lib "kerncase.ss" "syntax"))
|
||||
|
||||
(provide (all-from-except mzscheme #%module-begin)
|
||||
(provide (all-from-except (lib "new-lambda.ss" "scribblings") #%module-begin)
|
||||
(rename *module-begin #%module-begin))
|
||||
|
||||
;; Module wrapper ----------------------------------------
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
scribble-eval-handler)
|
||||
|
||||
(define current-int-namespace (make-parameter (make-namespace)))
|
||||
(define current-int-namespace (make-parameter (current-namespace)))
|
||||
(define scribble-eval-handler (make-parameter (lambda (c? x) (eval x))))
|
||||
|
||||
(define image-counter 0)
|
||||
|
@ -108,17 +108,11 @@
|
|||
#f)))))))
|
||||
|
||||
(define (do-eval s)
|
||||
(cond
|
||||
[(and (list? s)
|
||||
(eq? 'code:line (car s))
|
||||
(= (length s) 3)
|
||||
(list? (caddr s))
|
||||
(eq? 'code:comment (caaddr s)))
|
||||
(do-eval (cadr s))]
|
||||
[(and (list? s)
|
||||
(eq? 'eval:alts (car s))
|
||||
(= (length s) 3))
|
||||
(do-eval (caddr s))]
|
||||
(syntax-case s (code:comment eval:alts)
|
||||
[(code:line v (code:comment . rest))
|
||||
(do-eval #'v)]
|
||||
[(eval:alts p e)
|
||||
(do-eval #'e)]
|
||||
[else
|
||||
(let ([o (open-output-string)])
|
||||
(parameterize ([current-output-port o])
|
||||
|
@ -160,17 +154,19 @@
|
|||
v2)]
|
||||
[else v]))
|
||||
|
||||
(define (strip-comments s)
|
||||
(cond
|
||||
[(and (pair? s)
|
||||
(pair? (car s))
|
||||
(eq? (caar s) 'code:comment))
|
||||
(strip-comments (cdr s))]
|
||||
[(pair? s)
|
||||
(cons (strip-comments (car s))
|
||||
(strip-comments (cdr s)))]
|
||||
[(eq? s 'code:blank) (void)]
|
||||
[else s]))
|
||||
(define (strip-comments stx)
|
||||
(syntax-case stx (code:comment code:blank)
|
||||
[((code:comment . _) . rest)
|
||||
(strip-comments #'rest)]
|
||||
[(a . b)
|
||||
(datum->syntax-object stx
|
||||
(cons (strip-comments #'a)
|
||||
(strip-comments #'b))
|
||||
stx
|
||||
stx
|
||||
stx)]
|
||||
[code:blank #'(void)]
|
||||
[else stx]))
|
||||
|
||||
|
||||
(define (do-plain-eval s catching-exns?)
|
||||
|
@ -181,7 +177,7 @@
|
|||
(syntax-rules ()
|
||||
[(_ e) (#%expression
|
||||
(begin (parameterize ([current-command-line-arguments #()])
|
||||
(do-plain-eval (quote e) #f))
|
||||
(do-plain-eval (quote-syntax e) #f))
|
||||
""))]))
|
||||
|
||||
|
||||
|
@ -193,7 +189,7 @@
|
|||
(syntax-rules ()
|
||||
[(_ e) (#%expression
|
||||
(parameterize ([current-command-line-arguments #()])
|
||||
(show-val (car (do-plain-eval (quote e) #f)))))]))
|
||||
(show-val (car (do-plain-eval (quote-syntax e) #f)))))]))
|
||||
|
||||
(define (eval-example-string s)
|
||||
(eval (read (open-input-string s))))
|
||||
|
@ -239,7 +235,7 @@
|
|||
[(_ t schemeinput* e ...)
|
||||
(interleave t
|
||||
(list (schemeinput* e) ...)
|
||||
(map do-eval (list (quote e) ...)))]))
|
||||
(map do-eval (list (quote-syntax e) ...)))]))
|
||||
|
||||
(define-syntax interaction
|
||||
(syntax-rules ()
|
||||
|
|
|
@ -200,6 +200,11 @@
|
|||
[(at-right) '((align "right"))]
|
||||
[(at-left) '((align "left"))]
|
||||
[else null])
|
||||
,@(let ([a (and (list? (table-style t))
|
||||
(assoc 'style (table-style t)))])
|
||||
(if (and a (string? (cadr a)))
|
||||
`((class ,(cadr a)))
|
||||
null))
|
||||
,@(if (string? (table-style t))
|
||||
`((class ,(table-style t)))
|
||||
null))
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
|
||||
(module manual mzscheme
|
||||
(module manual (lib "new-lambda.ss" "scribblings")
|
||||
(require "decode.ss"
|
||||
"struct.ss"
|
||||
"scheme.ss"
|
||||
"config.ss"
|
||||
"basic.ss"
|
||||
(lib "string.ss")
|
||||
(lib "kw.ss")
|
||||
(lib "list.ss")
|
||||
(lib "class.ss"))
|
||||
|
||||
|
@ -46,7 +45,10 @@
|
|||
(define (to-element/id s)
|
||||
(make-element "schemesymbol" (list (to-element/no-color s))))
|
||||
|
||||
(define (keep-s-expr ctx s v) s)
|
||||
(define (keep-s-expr ctx s v)
|
||||
(if (symbol? s)
|
||||
(make-just-context s ctx)
|
||||
s))
|
||||
(define (add-sq-prop s name val)
|
||||
(if (eq? name 'paren-shape)
|
||||
(make-shaped-parens s val)
|
||||
|
@ -97,41 +99,41 @@
|
|||
link procedure
|
||||
idefterm)
|
||||
|
||||
(define/kw (onscreen #:body str)
|
||||
(define (onscreen . str)
|
||||
(make-element 'sf (decode-content str)))
|
||||
(define (menuitem menu item)
|
||||
(make-element 'sf (list menu "|" item)))
|
||||
(define/kw (defterm #:body str)
|
||||
(define (defterm . str)
|
||||
(make-element 'italic (decode-content str)))
|
||||
(define/kw (idefterm #:body str)
|
||||
(define (idefterm . str)
|
||||
(let ([c (decode-content str)])
|
||||
(make-element 'italic c)))
|
||||
(define/kw (schemefont #:body str)
|
||||
(define (schemefont . str)
|
||||
(apply tt str))
|
||||
(define/kw (schemevalfont #:body str)
|
||||
(define (schemevalfont . str)
|
||||
(make-element "schemevalue" (decode-content str)))
|
||||
(define/kw (schemeresultfont #:body str)
|
||||
(define (schemeresultfont . str)
|
||||
(make-element "schemeresult" (decode-content str)))
|
||||
(define/kw (schemeidfont #:body str)
|
||||
(define (schemeidfont . str)
|
||||
(make-element "schemesymbol" (decode-content str)))
|
||||
(define/kw (schemeparenfont #:body str)
|
||||
(define (schemeparenfont . str)
|
||||
(make-element "schemeparen" (decode-content str)))
|
||||
(define/kw (schememetafont #:body str)
|
||||
(define (schememetafont . str)
|
||||
(make-element "schememeta" (decode-content str)))
|
||||
(define/kw (schemekeywordfont #:body str)
|
||||
(define (schemekeywordfont . str)
|
||||
(make-element "schemekeyword" (decode-content str)))
|
||||
(define/kw (file #:body str)
|
||||
(define (file . str)
|
||||
(make-element 'tt (append (list "\"") (decode-content str) (list "\""))))
|
||||
(define/kw (exec #:body str)
|
||||
(define (exec . str)
|
||||
(make-element 'tt (decode-content str)))
|
||||
(define/kw (procedure #:body str)
|
||||
(define (procedure . str)
|
||||
(make-element "schemeresult" (append (list "#<procedure:") (decode-content str) (list ">"))))
|
||||
|
||||
(define/kw (link url #:body str)
|
||||
(define (link url . str)
|
||||
(make-element (make-target-url url) (decode-content str)))
|
||||
|
||||
(provide t)
|
||||
(define/kw (t #:body str)
|
||||
(define (t . str)
|
||||
(decode-paragraph str))
|
||||
|
||||
(provide schememodule)
|
||||
|
@ -151,7 +153,7 @@
|
|||
|
||||
;; ----------------------------------------
|
||||
|
||||
(provide deftech tech)
|
||||
(provide deftech tech techlink)
|
||||
|
||||
(define (*tech make-elem style s)
|
||||
(let* ([c (decode-content s)]
|
||||
|
@ -165,12 +167,15 @@
|
|||
c
|
||||
(format "tech-term:~a" s))))
|
||||
|
||||
(define/kw (deftech #:body s)
|
||||
(define (deftech . s)
|
||||
(*tech make-target-element #f (list (apply defterm s))))
|
||||
|
||||
(define/kw (tech #:body s)
|
||||
(define (tech . s)
|
||||
(*tech make-link-element "techlink" s))
|
||||
|
||||
(define (techlink . s)
|
||||
(*tech make-link-element #f s))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(provide defproc defproc* defstruct defthing defform defform* defform/subs defform*/subs defform/none
|
||||
|
@ -218,21 +223,23 @@
|
|||
(define-syntax defproc
|
||||
(syntax-rules ()
|
||||
[(_ (id arg ...) result desc ...)
|
||||
(*defproc '[(id arg ...)]
|
||||
(*defproc (list (quote-syntax id))
|
||||
'[(id arg ...)]
|
||||
(list (list (lambda () (arg-contract arg)) ...))
|
||||
(list (lambda () (schemeblock0 result)))
|
||||
(lambda () (list desc ...)))]))
|
||||
(define-syntax defproc*
|
||||
(syntax-rules ()
|
||||
[(_ [[(id arg ...) result] ...] desc ...)
|
||||
(*defproc '[(id arg ...) ...]
|
||||
(*defproc (list (quote-syntax id) ...)
|
||||
'[(id arg ...) ...]
|
||||
(list (list (lambda () (arg-contract arg)) ...) ...)
|
||||
(list (lambda () (schemeblock0 result)) ...)
|
||||
(lambda () (list desc ...)))]))
|
||||
(define-syntax defstruct
|
||||
(syntax-rules ()
|
||||
[(_ name fields desc ...)
|
||||
(*defstruct 'name 'fields (lambda () (list desc ...)))]))
|
||||
(*defstruct (quote-syntax name) 'name 'fields (lambda () (list desc ...)))]))
|
||||
(define-syntax (defform*/subs stx)
|
||||
(syntax-case stx ()
|
||||
[(_ #:literals (lit ...) [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...)
|
||||
|
@ -245,8 +252,11 @@
|
|||
'(unsyntax x)
|
||||
#'name)
|
||||
#'rest)
|
||||
#'spec)])])
|
||||
#'(*defforms #t '(lit ...)
|
||||
#'spec)])]
|
||||
[spec-id
|
||||
(syntax-case #'spec ()
|
||||
[(name . rest) #'name])])
|
||||
#'(*defforms (quote-syntax spec-id) '(lit ...)
|
||||
'(spec spec1 ...)
|
||||
(list (lambda (x) (schemeblock0 new-spec))
|
||||
(lambda (ignored) (schemeblock0 spec1)) ...)
|
||||
|
@ -260,6 +270,7 @@
|
|||
#'(fm #:literals () [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...)]))
|
||||
(define-syntax (defform* stx)
|
||||
(syntax-case stx ()
|
||||
[(_ #:literals lits [spec ...] desc ...) #'(defform*/subs #:literals lits [spec ...] () desc ...)]
|
||||
[(_ [spec ...] desc ...) #'(defform*/subs [spec ...] () desc ...)]))
|
||||
(define-syntax (defform stx)
|
||||
(syntax-case stx ()
|
||||
|
@ -312,7 +323,7 @@
|
|||
(define-syntax defthing
|
||||
(syntax-rules ()
|
||||
[(_ id result desc ...)
|
||||
(*defthing 'id 'result (lambda () (list desc ...)))]))
|
||||
(*defthing (quote-syntax id) 'id 'result (lambda () (list desc ...)))]))
|
||||
(define-syntax schemegrammar
|
||||
(syntax-rules ()
|
||||
[(_ #:literals (lit ...) id clause ...) (*schemegrammar '(lit ...)
|
||||
|
@ -342,7 +353,7 @@
|
|||
(list (make-table style content))))
|
||||
(list (make-table style content))))
|
||||
|
||||
(define (*defproc prototypes arg-contractss result-contracts content-thunk)
|
||||
(define (*defproc stx-ids prototypes arg-contractss result-contracts content-thunk)
|
||||
(let ([spacer (hspace 1)]
|
||||
[has-optional? (lambda (arg)
|
||||
(and (pair? arg)
|
||||
|
@ -378,7 +389,7 @@
|
|||
(apply
|
||||
append
|
||||
(map
|
||||
(lambda (prototype arg-contracts result-contract first?)
|
||||
(lambda (stx-id prototype arg-contracts result-contract first?)
|
||||
(append
|
||||
(list
|
||||
(list (make-flow
|
||||
|
@ -403,7 +414,7 @@
|
|||
(make-target-element
|
||||
#f
|
||||
(list (to-element (car prototype)))
|
||||
(register-scheme-definition (car prototype)))
|
||||
(register-scheme-definition stx-id))
|
||||
(to-element (car prototype))))
|
||||
(map arg->elem required)
|
||||
(if (null? optional)
|
||||
|
@ -449,25 +460,29 @@
|
|||
[else null]))
|
||||
(cdr prototype)
|
||||
arg-contracts))))
|
||||
stx-ids
|
||||
prototypes
|
||||
arg-contractss
|
||||
result-contracts
|
||||
(cons #t (map (lambda (x) #f) (cdr prototypes))))))
|
||||
(content-thunk))))))
|
||||
|
||||
(define (make-target-element* content wrappers)
|
||||
(define (make-target-element* stx-id content wrappers)
|
||||
(if (null? wrappers)
|
||||
content
|
||||
(make-target-element*
|
||||
stx-id
|
||||
(make-target-element
|
||||
#f
|
||||
(list content)
|
||||
(register-scheme-definition (string->symbol
|
||||
(apply string-append
|
||||
(map symbol->string (car wrappers))))))
|
||||
(register-scheme-definition
|
||||
(datum->syntax-object stx-id
|
||||
(string->symbol
|
||||
(apply string-append
|
||||
(map symbol->string (car wrappers)))))))
|
||||
(cdr wrappers))))
|
||||
|
||||
(define (*defstruct name fields content-thunk)
|
||||
(define (*defstruct stx-id name fields content-thunk)
|
||||
(define spacer (hspace 1))
|
||||
(make-splice
|
||||
(cons
|
||||
|
@ -481,6 +496,7 @@
|
|||
(to-element
|
||||
`(,(schemeparenfont "struct")
|
||||
,(make-target-element*
|
||||
stx-id
|
||||
(to-element name)
|
||||
(let ([name (if (pair? name)
|
||||
(car name)
|
||||
|
@ -515,7 +531,7 @@
|
|||
fields)))
|
||||
(content-thunk))))
|
||||
|
||||
(define (*defthing name result-contract content-thunk)
|
||||
(define (*defthing stx-id name result-contract content-thunk)
|
||||
(define spacer (hspace 1))
|
||||
(make-splice
|
||||
(cons
|
||||
|
@ -528,19 +544,19 @@
|
|||
(list (make-target-element
|
||||
#f
|
||||
(list (to-element name))
|
||||
(register-scheme-definition name))
|
||||
(register-scheme-definition stx-id))
|
||||
spacer ":" spacer
|
||||
(to-element result-contract))))))))
|
||||
(content-thunk))))
|
||||
|
||||
(define (meta-symbol? s) (memq s '(... ...+ ?)))
|
||||
|
||||
(define (*defforms kw? lits forms form-procs subs sub-procs content-thunk)
|
||||
(define (*defforms kw-id lits forms form-procs subs sub-procs content-thunk)
|
||||
(parameterize ([current-variable-list
|
||||
(apply
|
||||
append
|
||||
(map (lambda (form)
|
||||
(let loop ([form (cons (if kw? (cdr form) form)
|
||||
(let loop ([form (cons (if kw-id (cdr form) form)
|
||||
subs)])
|
||||
(cond
|
||||
[(symbol? form) (if (or (meta-symbol? form)
|
||||
|
@ -568,22 +584,25 @@
|
|||
(to-element
|
||||
`(,x
|
||||
. ,(cdr form)))))))
|
||||
(and kw?
|
||||
(and kw-id
|
||||
(eq? form (car forms))
|
||||
(make-target-element
|
||||
#f
|
||||
(list (to-element (car form)))
|
||||
(register-scheme-form-definition (car form)))))))))
|
||||
(list (to-element (make-just-context (car form) kw-id)))
|
||||
(register-scheme-form-definition kw-id))))))))
|
||||
forms form-procs)
|
||||
(apply
|
||||
append
|
||||
(map (lambda (sub)
|
||||
(list (list (make-flow (list (make-paragraph (list (tt 'nbsp))))))
|
||||
(list (make-flow (list (apply *schemerawgrammar
|
||||
(map (lambda (f) (f)) sub)))))))
|
||||
sub-procs))))
|
||||
(if (null? sub-procs)
|
||||
null
|
||||
(list (list (make-flow (list (make-paragraph (list (tt 'nbsp))))))
|
||||
(list (make-flow (list (let ([l (map (lambda (sub)
|
||||
(map (lambda (f) (f)) sub))
|
||||
sub-procs)])
|
||||
(*schemerawgrammars
|
||||
"specgrammar"
|
||||
(map car l)
|
||||
(map cdr l))))))))))
|
||||
(content-thunk)))))
|
||||
|
||||
|
||||
(define (*specsubform form has-kw? lits form-thunk subs sub-procs content-thunk)
|
||||
(parameterize ([current-variable-list
|
||||
(append (let loop ([form (cons (if has-kw? (cdr form) form)
|
||||
|
@ -610,41 +629,47 @@
|
|||
(if form-thunk
|
||||
(form-thunk)
|
||||
(make-paragraph (list (to-element form)))))))
|
||||
(apply
|
||||
append
|
||||
(map (lambda (sub)
|
||||
(list (list (make-flow (list (make-paragraph (list (tt 'nbsp))))))
|
||||
(list (make-flow (list (apply *schemerawgrammar
|
||||
(map (lambda (f) (f)) sub)))))))
|
||||
sub-procs))))
|
||||
(if (null? sub-procs)
|
||||
null
|
||||
(list (list (make-flow (list (make-paragraph (list (tt 'nbsp))))))
|
||||
(list (make-flow (list (let ([l (map (lambda (sub)
|
||||
(map (lambda (f) (f)) sub))
|
||||
sub-procs)])
|
||||
(*schemerawgrammars
|
||||
"specgrammar"
|
||||
(map car l)
|
||||
(map cdr l))))))))))
|
||||
(flow-paragraphs (decode-flow (content-thunk)))))))
|
||||
|
||||
(define (*schemerawgrammars nonterms clauseses)
|
||||
(define (*schemerawgrammars style nonterms clauseses)
|
||||
(make-table
|
||||
'((valignment baseline baseline baseline baseline baseline)
|
||||
(alignment right left center left left))
|
||||
`((valignment baseline baseline baseline baseline baseline)
|
||||
(alignment right left center left left)
|
||||
(style ,style))
|
||||
(let ([empty-line (make-flow (list (make-paragraph (list (tt 'nbsp)))))]
|
||||
[to-flow (lambda (i) (make-flow (list (make-paragraph (list i)))))])
|
||||
(apply append
|
||||
(map
|
||||
(lambda (nonterm clauses)
|
||||
(cons
|
||||
(list (to-flow nonterm)
|
||||
empty-line
|
||||
(to-flow "=")
|
||||
empty-line
|
||||
(make-flow (list (car clauses))))
|
||||
(map (lambda (clause)
|
||||
(list empty-line
|
||||
empty-line
|
||||
(to-flow "|")
|
||||
empty-line
|
||||
(make-flow (list clause))))
|
||||
(cdr clauses))))
|
||||
nonterms clauseses)))))
|
||||
(cdr
|
||||
(apply append
|
||||
(map
|
||||
(lambda (nonterm clauses)
|
||||
(list*
|
||||
(list empty-line empty-line empty-line empty-line empty-line)
|
||||
(list (to-flow nonterm)
|
||||
empty-line
|
||||
(to-flow "=")
|
||||
empty-line
|
||||
(make-flow (list (car clauses))))
|
||||
(map (lambda (clause)
|
||||
(list empty-line
|
||||
empty-line
|
||||
(to-flow "|")
|
||||
empty-line
|
||||
(make-flow (list clause))))
|
||||
(cdr clauses))))
|
||||
nonterms clauseses))))))
|
||||
|
||||
(define (*schemerawgrammar nonterm clause1 . clauses)
|
||||
(*schemerawgrammars (list nonterm) (list (cons clause1 clauses))))
|
||||
(define (*schemerawgrammar style nonterm clause1 . clauses)
|
||||
(*schemerawgrammars style (list nonterm) (list (cons clause1 clauses))))
|
||||
|
||||
(define (*schemegrammar lits s-expr clauseses-thunk)
|
||||
(parameterize ([current-variable-list
|
||||
|
@ -657,7 +682,7 @@
|
|||
(loop (cdr form)))]
|
||||
[else null]))])
|
||||
(let ([l (clauseses-thunk)])
|
||||
(*schemerawgrammars (map car l) (map cdr l)))))
|
||||
(*schemerawgrammars #f (map car l) (map cdr l)))))
|
||||
|
||||
(define (*var id)
|
||||
(to-element (*var-sym id)))
|
||||
|
@ -668,26 +693,26 @@
|
|||
;; ----------------------------------------
|
||||
|
||||
(provide centerline)
|
||||
(define/kw (centerline #:body s)
|
||||
(define (centerline . s)
|
||||
(make-table 'centered (list (list (make-flow (list (decode-paragraph s)))))))
|
||||
|
||||
(provide commandline)
|
||||
(define/kw (commandline #:body s)
|
||||
(define (commandline . s)
|
||||
(make-paragraph (list (hspace 2) (apply tt s))))
|
||||
|
||||
|
||||
(define (secref s)
|
||||
(make-link-element #f null `(part ,s)))
|
||||
(define/kw (seclink tag #:body s)
|
||||
(define (seclink tag . s)
|
||||
(make-link-element #f (decode-content s) `(part ,tag)))
|
||||
(define/kw (*schemelink id #:body s)
|
||||
(make-link-element #f (decode-content s) (register-scheme-definition id)))
|
||||
(define (*schemelink stx-id id . s)
|
||||
(make-link-element #f (decode-content s) (register-scheme-definition stx-id)))
|
||||
(define-syntax schemelink
|
||||
(syntax-rules ()
|
||||
[(_ id . content) (*schemelink 'id . content)]))
|
||||
[(_ id . content) (*schemelink (quote-syntax id) 'id . content)]))
|
||||
(provide secref seclink schemelink)
|
||||
|
||||
(define/kw (pidefterm #:body s)
|
||||
(define (pidefterm . s)
|
||||
(let ([c (apply defterm s)])
|
||||
(index (string-append (content->string (element-content c)) "s")
|
||||
c)))
|
||||
|
@ -707,7 +732,7 @@
|
|||
;; ----------------------------------------
|
||||
|
||||
(provide math)
|
||||
(define/kw (math #:body s)
|
||||
(define (math . s)
|
||||
(let ([c (decode-content s)])
|
||||
(make-element #f (apply append
|
||||
(map (lambda (i)
|
||||
|
@ -727,7 +752,7 @@
|
|||
|
||||
(provide cite)
|
||||
|
||||
(define/kw (cite #:key key title author location date)
|
||||
(define (cite #:key key #:title title #:author author #:location location #:date date)
|
||||
"[...]"
|
||||
#;
|
||||
(make-bibliography-element
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
(require "struct.ss"
|
||||
"basic.ss"
|
||||
(lib "class.ss")
|
||||
(lib "for.ss"))
|
||||
(lib "for.ss")
|
||||
(lib "modcollapse.ss" "syntax"))
|
||||
|
||||
(provide define-code
|
||||
to-element
|
||||
|
@ -17,7 +18,8 @@
|
|||
current-variable-list
|
||||
current-meta-list
|
||||
|
||||
(struct shaped-parens (val shape)))
|
||||
(struct shaped-parens (val shape))
|
||||
(struct just-context (val ctx)))
|
||||
|
||||
(define no-color "schemeplain")
|
||||
(define reader-color "schemeplain")
|
||||
|
@ -32,13 +34,12 @@
|
|||
|
||||
(define current-keyword-list
|
||||
;; This is temporary, until the MzScheme manual is filled in...
|
||||
(make-parameter '(require
|
||||
(make-parameter null #;'(require
|
||||
provide
|
||||
new send else => and or
|
||||
define-syntax syntax-rules define-struct
|
||||
quote quasiquote unquote unquote-splicing
|
||||
syntax quasisyntax unsyntax unsyntax-splicing
|
||||
set! set!-values)))
|
||||
quasiquote unquote unquote-splicing
|
||||
syntax quasisyntax unsyntax unsyntax-splicing)))
|
||||
(define current-variable-list
|
||||
(make-parameter null))
|
||||
(define current-meta-list
|
||||
|
@ -353,8 +354,8 @@
|
|||
(not (or it? is-var?)))
|
||||
(make-delayed-element
|
||||
(lambda (renderer sec ht)
|
||||
(let* ([vtag (register-scheme-definition (syntax-e c))]
|
||||
[stag (register-scheme-form-definition (syntax-e c))]
|
||||
(let* ([vtag (register-scheme-definition c)]
|
||||
[stag (register-scheme-form-definition c)]
|
||||
[vd (hash-table-get ht vtag #f)]
|
||||
[sd (hash-table-get ht stag #f)])
|
||||
(list
|
||||
|
@ -431,7 +432,7 @@
|
|||
(cond
|
||||
[(syntax? v)
|
||||
(let ([mk `(,#'d->s
|
||||
#f
|
||||
(quote-syntax ,v)
|
||||
,(syntax-case v (uncode)
|
||||
[(uncode e) #'e]
|
||||
[else (stx->loc-s-expr (syntax-e v))])
|
||||
|
@ -463,11 +464,22 @@
|
|||
[(_ code typeset-code) #'(define-code code typeset-code unsyntax)]))
|
||||
|
||||
|
||||
(define (register-scheme-definition sym)
|
||||
(format "definition:~s" sym))
|
||||
(define (register-scheme-definition stx)
|
||||
(unless (identifier? stx)
|
||||
(error 'register-scheme-definition "not an identifier: ~e" (syntax-object->datum stx)))
|
||||
(format "definition:~s"
|
||||
(let ([b (identifier-binding stx)])
|
||||
(cond
|
||||
[(not b) (format "top:~a" (syntax-e stx))]
|
||||
[(eq? b 'lexical) (format "lexical:~a" (syntax-e stx))]
|
||||
[else (format "module:~a:~a"
|
||||
(if (module-path-index? (car b))
|
||||
(collapse-module-path-index (car b) '(lib "ack.ss" "scribble"))
|
||||
(car b))
|
||||
(cadr b))]))))
|
||||
|
||||
(define (register-scheme-form-definition sym)
|
||||
(format "formdefinition:~s" sym))
|
||||
(define (register-scheme-form-definition stx)
|
||||
(format "form~s" (register-scheme-definition stx)))
|
||||
|
||||
(define syntax-ize-hook (make-parameter (lambda (v col) #f)))
|
||||
|
||||
|
@ -495,6 +507,7 @@
|
|||
l))))
|
||||
|
||||
(define-struct shaped-parens (val shape))
|
||||
(define-struct just-context (val ctx))
|
||||
|
||||
(define (syntax-ize v col)
|
||||
(cond
|
||||
|
@ -504,6 +517,13 @@
|
|||
(syntax-property (syntax-ize (shaped-parens-val v) col)
|
||||
'paren-shape
|
||||
(shaped-parens-shape v))]
|
||||
[(just-context? v)
|
||||
(let ([s (syntax-ize (just-context-val v) col)])
|
||||
(datum->syntax-object (just-context-ctx v)
|
||||
(syntax-e s)
|
||||
s
|
||||
s
|
||||
(just-context-ctx v)))]
|
||||
[(and (list? v)
|
||||
(pair? v)
|
||||
(memq (car v) '(quote unquote unquote-splicing)))
|
||||
|
|
|
@ -184,6 +184,10 @@
|
|||
background-color: #ddddff;
|
||||
}
|
||||
|
||||
.specgrammar {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.hspace {
|
||||
font-family: Courier; font-size: 80%;
|
||||
}
|
||||
|
|
400
collects/scribblings/guide/class.scrbl
Normal file
|
@ -0,0 +1,400 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require[(lib "manual.ss" "scribble")]
|
||||
@require[(lib "eval.ss" "scribble")]
|
||||
@require[(lib "class.ss")]
|
||||
@require["guide-utils.ss"]
|
||||
|
||||
@title[#:tag "classes"]{Classes and Objects}
|
||||
|
||||
A @scheme[class] expression denotes a first-class value,
|
||||
just like a @scheme[lambda] expression:
|
||||
|
||||
@specform[(class superclass-expr decl-or-expr ...)]
|
||||
|
||||
The @scheme[_superclass-expr] determines the superclass for the new
|
||||
class. Each @scheme[_decl-or-expr] is either a declaration related to
|
||||
methods, fields, and intialization arguments, or it is an expression
|
||||
that is evaluated each time that the class is instantiated. In other
|
||||
words, instead of a method-like constructor, a class has
|
||||
initialization expressions interleaved with field and method
|
||||
declarations.
|
||||
|
||||
By convention, class names end with @schemeidfont{%}. The built-in root class is
|
||||
@scheme[object%]. The following expression creates a class with
|
||||
public methods @scheme[get-size], @scheme[grow], and @scheme[eat]:
|
||||
|
||||
@schemeblock[
|
||||
(class object%
|
||||
(init size) (code:comment #,(t "initialization argument"))
|
||||
|
||||
(define current-size size) (code:comment #,(t "field"))
|
||||
|
||||
(super-new) (code:comment #,(t "superclass initialization"))
|
||||
|
||||
(define/public (get-size)
|
||||
current-size)
|
||||
|
||||
(define/public (grow amt)
|
||||
(set! current-size (+ amt current-size)))
|
||||
|
||||
(define/public (eat other-fish)
|
||||
(grow (send other-fish get-size))))
|
||||
]
|
||||
|
||||
@interaction-eval[
|
||||
(define fish%
|
||||
(class object%
|
||||
(init size)
|
||||
(define current-size size)
|
||||
(super-new)
|
||||
(define/public (get-size)
|
||||
current-size)
|
||||
(define/public (grow amt)
|
||||
(set! current-size (+ amt current-size)))
|
||||
(define/public (eat other-fish)
|
||||
(grow (send other-fish get-size)))))]
|
||||
|
||||
The @scheme[size] initialization argument must be supplied via a named
|
||||
argument when instantiating the class through the @scheme[new] form:
|
||||
|
||||
@schemeblock[
|
||||
(new (class object% (init size) ...) [size 10])
|
||||
]
|
||||
|
||||
Of course, we can also name the class and its instance:
|
||||
|
||||
@schemeblock[
|
||||
(define fish% (class object% (init size) ...))
|
||||
(define charlie (new fish% [size 10]))
|
||||
]
|
||||
|
||||
@interaction-eval[(define charlie (new fish% [size 10]))]
|
||||
|
||||
In the definition of @scheme[fish%], @scheme[current-size] is a
|
||||
private field that starts out with the value of the @scheme[size]
|
||||
initialization argument. Initialization arguments like @scheme[size]
|
||||
are available only during class instantiation, so they cannot be
|
||||
referenced directly from a method. The @scheme[current-size] field, in
|
||||
contrast, is available to methods.
|
||||
|
||||
The @scheme[(super-new)] expression in @scheme[fish%] invokes the
|
||||
initialization of the superclass. In this case, the superclass is
|
||||
@scheme[object%], which takes no initialization arguments and performs
|
||||
no work; @scheme[super-new] must be used, anyway, because a class must
|
||||
always invoke its superclass's initialization.
|
||||
|
||||
Initialization arguments, field declarations, and expressions such as
|
||||
@scheme[(super-new)] can appear in any order within a @scheme[class],
|
||||
and they can be interleaved with method declarations. The relative
|
||||
order of expressions in the class determines the order of evaluation
|
||||
during instantiation. For example, if a field's initial value requires
|
||||
calling a method that works only after superclass initialization, then
|
||||
the field declaration is placed after the @scheme[super-new]
|
||||
call. Ordering field and initialization declarations in this way helps
|
||||
avoid imperative assignment. The relative order of method declarations
|
||||
makes no difference for evaluation, because methods are fully defined
|
||||
before a class is instantiated.
|
||||
|
||||
@section[#:tag "guide:methods"]{Methods}
|
||||
|
||||
Each of the three @scheme[define/public] declarations in
|
||||
@scheme[fish%] introduces a new method. The declaration uses the same
|
||||
syntax as a Scheme function, but a method is not accessible as an
|
||||
independent function. A call to the @scheme[grow] method of a
|
||||
@scheme[fish%] object requires the @scheme[send] form:
|
||||
|
||||
@interaction[
|
||||
(send charlie grow 6)
|
||||
(send charlie get-size)
|
||||
]
|
||||
|
||||
Within @scheme[fish%], self methods can be called like functions,
|
||||
because the method names are in scope. For example, the @scheme[eat]
|
||||
method within @scheme[fish%] directly invokes the @scheme[grow]
|
||||
method. Within a class, attempting to use a method name in any way
|
||||
other than a method call results in a syntax error.
|
||||
|
||||
In some cases, a class must call methods that are supplied by the superclass
|
||||
but not overridden. In that case, the class can use @scheme[send]
|
||||
with @scheme[this] to access the method:
|
||||
|
||||
@def+int[
|
||||
(define hungry-fish% (class fish% (super-new)
|
||||
(define/public (eat-more fish1 fish2)
|
||||
(send this eat fish1)
|
||||
(send this eat fish2))))
|
||||
]
|
||||
|
||||
Alternately, the class can declare the existence of a method using @scheme[inherit],
|
||||
which brings the method name into scope for a direct call:
|
||||
|
||||
@def+int[
|
||||
(define hungry-fish% (class fish% (super-new)
|
||||
(inherit eat)
|
||||
(define/public (eat-more fish1 fish2)
|
||||
(eat fish1) (eat fish2))))
|
||||
]
|
||||
|
||||
With the @scheme[inherit] declaration, if @scheme[fish%] had not
|
||||
provided an @scheme[eat] method, an error would be signaled in the
|
||||
evaluation of the @scheme[class] form for @scheme[hungry-fish%]. In
|
||||
contrast, with @scheme[(send this ...)], an error would not be
|
||||
signaled until the @scheme[eat-more] method is called and the
|
||||
@scheme[send] form is evaluated. For this reason, @scheme[inherit] is
|
||||
preferred.
|
||||
|
||||
Another drawback of @scheme[send] is that it is less efficient than
|
||||
@scheme[inherit]. Invocation of a method via @scheme[send] involves
|
||||
finding a method in the target object's class at run time, making
|
||||
@scheme[send] comparable to an interface-based method call in Java. In
|
||||
contrast, @scheme[inherit]-based method invocations use an offset
|
||||
within the class's method table that is computed when the class is
|
||||
created.
|
||||
|
||||
To achieve performance similar to @scheme[inherit]-based method calls when
|
||||
invoking a method from outside the method's class, the programmer must use the
|
||||
@scheme[generic] form, which produces a class- and method-specific
|
||||
@defterm{generic method} to be invoked with @scheme[send-generic]:
|
||||
|
||||
@def+int[
|
||||
(define get-fish-size (generic fish% get-size))
|
||||
(send-generic charlie get-fish-size)
|
||||
(send-generic (new hungry-fish% [size 32]) get-fish-size)
|
||||
(send-generic (new object%) get-fish-size)
|
||||
]
|
||||
|
||||
Roughly speaking, the form translates the class and the external
|
||||
method name to a location in the class's method table. As illustrated
|
||||
by the last example, sending through a generic method checks that its
|
||||
argument is an instance of the generic's class.
|
||||
|
||||
Whether a method is called directly within a @scheme[class],
|
||||
through a generic method,
|
||||
or through @scheme[send], method overriding works in the usual way:
|
||||
|
||||
@defs+int[
|
||||
[
|
||||
(define picky-fish% (class fish% (super-new)
|
||||
(define/override (grow amt)
|
||||
;; Doesn't eat all of its food
|
||||
(super grow (* 3/4 amt)))))
|
||||
(define daisy (new picky-fish% [size 20]))
|
||||
]
|
||||
(send daisy eat charlie)
|
||||
(send daisy get-size)
|
||||
]
|
||||
|
||||
The @scheme[grow] method in @scheme[picky-fish%] is declared with
|
||||
@scheme[define/override] instead of @scheme[define/public], because
|
||||
@scheme[grow] is meant as an overriding declaration. If @scheme[grow]
|
||||
had been declared with @scheme[define/public], an error would have
|
||||
been signaled when evaluating the @scheme[class] expression, because
|
||||
@scheme[fish%] already supplies @scheme[grow].
|
||||
|
||||
Using @scheme[define/override] also allows the invocation of the
|
||||
overridden method via a @scheme[super] call. For example, the
|
||||
@scheme[grow] implementation in @scheme[picky-fish%] uses
|
||||
@scheme[super] to delegate to the superclass implementation.
|
||||
|
||||
@section[#:tag "guide:initargs"]{Initialization Arguments}
|
||||
|
||||
Since @scheme[picky-fish%] declares no initialization arguments, any
|
||||
initialization values supplied in @scheme[(new picky-fish% ...)] are
|
||||
propagated to the superclass initialization, i.e., to @scheme[fish%].
|
||||
A subclass can supply additional initialization arguments for its
|
||||
superclass in a @scheme[super-new] call, and such initialization
|
||||
arguments take precedence over arguments supplied to @scheme[new]. For
|
||||
example, the following @scheme[size-10-fish%] class always generates
|
||||
fish of size 10:
|
||||
|
||||
@def+int[
|
||||
(define size-10-fish% (class fish% (super-new [size 10])))
|
||||
(send (new size-10-fish%) get-size)
|
||||
]
|
||||
|
||||
In the case of @scheme[size-10-fish%], supplying a @scheme[size]
|
||||
initialization argument with @scheme[new] would result in an
|
||||
initialization error; because the @scheme[size] in @scheme[super-new]
|
||||
takes precedence, a @scheme[size] supplied to @scheme[new] would have
|
||||
no target declaration.
|
||||
|
||||
An initialization argument is optional if the @scheme[class] form
|
||||
declares a default value. For example, the following @scheme[default-10-fish%]
|
||||
class accepts a @scheme[size] initialization argument, but its value defaults to
|
||||
10 if no value is supplied on instantiation:
|
||||
|
||||
@def+int[
|
||||
(define default-10-fish% (class fish%
|
||||
(init [size 10])
|
||||
(super-new [size size])))
|
||||
(new default-10-fish%)
|
||||
(new default-10-fish% [size 20])
|
||||
]
|
||||
|
||||
In this example, the @scheme[super-new] call propagates its own
|
||||
@scheme[size] value as the @scheme[size] initialization argument to
|
||||
the superclass.
|
||||
|
||||
@section[#:tag "guide:intnames"]{Internal and External Names}
|
||||
|
||||
The two uses of @scheme[size] in @scheme[default-10-fish%] expose the
|
||||
double life of class-member identifiers. When @scheme[size] is the
|
||||
first identifier of a bracketed pair in @scheme[new] or
|
||||
@scheme[super-new], @scheme[size] is an @defterm{external name} that
|
||||
is symbolically matched to an initialization argument in a class. When
|
||||
@scheme[size] appears as an expression within
|
||||
@scheme[default-10-fish%], @scheme[size] is an \defterm{internal name}
|
||||
that is lexically scoped. Similarly, a call to an inherited
|
||||
@scheme[eat] method uses @scheme[eat] as an internal name, whereas a
|
||||
@scheme[send] of @scheme[eat] uses @scheme[eat] as an external name.
|
||||
|
||||
The full syntax of the @scheme[class] form allows a programmer to
|
||||
specify distinct internal and external names for a class member. Since
|
||||
internal names are local, they can be renamed to avoid shadowing or
|
||||
conflicts. Such renaming is not frequently necessary, but workarounds
|
||||
in the absence of renaming can be especially cumbersome.
|
||||
|
||||
@section{Interfaces}
|
||||
|
||||
Interfaces are useful for checking that an object or a class
|
||||
implements a set of methods with a particular (implied) behavior.
|
||||
This use of interfaces is helpful even without a static type system
|
||||
(which is the main reason that Java has interfaces).
|
||||
|
||||
An interface in PLT Scheme is created using the @scheme[interface]
|
||||
form, which merely declares the method names required to implement the
|
||||
interface. An interface can extend other interfaces, which means that
|
||||
implementations of the interface automatically implement the extended
|
||||
interfaces.
|
||||
|
||||
@specform[(interface (superinterface-expr ...) id ...)]
|
||||
|
||||
To declare that a class implements an interface, the
|
||||
@scheme[class*] form must be used instead of @scheme[class]:
|
||||
|
||||
@specform[(class* superclass-expr (interface-expr ...) decl-or-expr ...)]
|
||||
|
||||
For example, instead of forcing all fish classes to be derived from
|
||||
@scheme[fish%], we can define @scheme[fish-interface] and change the
|
||||
@scheme[fish%] class to declare that it implements
|
||||
@scheme[fish-interface]:
|
||||
|
||||
@schemeblock[
|
||||
(define fish-interface (interface () get-size grow eat))
|
||||
(define fish% (class* object% (fish-interface) ...))
|
||||
]
|
||||
|
||||
If the definition of @scheme[fish%] does not include
|
||||
@scheme[get-size], @scheme[grow], and @scheme[eat] methods, then an
|
||||
error is signaled in the evaluation of the @scheme[class*] form,
|
||||
because implementing the @scheme[fish-interface] interface requires
|
||||
those methods.
|
||||
|
||||
The @scheme[is-a?] predicate accepts either a class or interface as
|
||||
its first argument and an object as its second argument. When given a
|
||||
class, @scheme[is-a?] checks whether the object is an instance of that
|
||||
class or a derived class. When given an interface, @scheme[is-a?]
|
||||
checks whether the object's class implements the interface. In
|
||||
addition, the @scheme[implementation?] predicate checks whether a
|
||||
given class implements a given interface.
|
||||
|
||||
@section[#:tag "guide:inner"]{Final, Augment, and Inner}
|
||||
|
||||
As in Java, a method in a @scheme[class] form can be specified as
|
||||
@defterm{final}, which means that a subclass cannot override the
|
||||
method. A final method is declared using @scheme[public-final] or
|
||||
@scheme[override-final], depending on whether the declaration is for a
|
||||
new method or an overriding implementation.
|
||||
|
||||
Between the extremes of allowing arbitrary overriding and disallowing
|
||||
overriding entirely, the {class} system also supports Beta-style
|
||||
@defterm{augmentable} methods~\cite{beta}. A method
|
||||
declared with @scheme[pubment] is like @scheme[public], but the method
|
||||
cannot be overridden in subclasses; it can be augmented only. A
|
||||
@scheme[pubment] method must explicitly invoke an augmentation (if any)
|
||||
using @scheme[inner]; a subclass augments the method using
|
||||
@scheme[augment], instead of @scheme[override].
|
||||
|
||||
In general, a method can switch between augment and override modes in
|
||||
a class derivation. The @scheme[augride] method specification
|
||||
indicates an augmentation to a method where the augmentation is itself
|
||||
overrideable in subclasses (though the superclass's implementation
|
||||
cannot be overridden). Similarly, @scheme[overment] overrides a method
|
||||
and makes the overriding implementation augmentable. Our earlier
|
||||
work~\cite{Super+Inner} motivates and explains these extensions and
|
||||
their interleaving.
|
||||
|
||||
@section[#:tag "guide:extnames"]{Controlling the Scope of External Names}
|
||||
|
||||
As noted in @secref["guide:intnames"], class members have both
|
||||
internal and external names. A member definition binds an internal
|
||||
name locally, and this binding can be locally renamed. External
|
||||
names, in contrast, have global scope by default, and a member
|
||||
definition does not bind an external name. Instead, a member
|
||||
definition refers to an existing binding for an external name, where
|
||||
the member name is bound to a @defterm{member key}; a class ultimately
|
||||
maps member keys to methods, fields, and initialization arguments.
|
||||
|
||||
Recall the @scheme[hungry-fish%] @scheme[class] expression:
|
||||
|
||||
@schemeblock[
|
||||
(define hungry-fish% (class fish% ...
|
||||
(inherit eat)
|
||||
(define/public (eat-more fish1 fish2)
|
||||
(eat fish1) (eat fish2))))
|
||||
]
|
||||
|
||||
During its evaluation, the @scheme[hungry-fish%] and @scheme[fish%]
|
||||
classes refer to the same global binding of @scheme[eat]. At run
|
||||
time, calls to @scheme[eat] in @scheme[hungry-fish%] are matched with
|
||||
the @scheme[eat] method in @scheme[fish%] through the shared method
|
||||
key that is bound to @scheme[eat].
|
||||
|
||||
The default binding for an external name is global, but a
|
||||
programmer can introduce an external-name binding with the
|
||||
@scheme[define-member-name] form.
|
||||
|
||||
@specform[(define-member-name id member-key-expr)]
|
||||
|
||||
In particular, by using @scheme[(generate-member-key)] as the
|
||||
@scheme[member-key-expr], an external name can be localized for a
|
||||
particular scope, because the generated member key is inaccessible
|
||||
outside the scope. In other words, @scheme[define-member-name] gives
|
||||
an external name a kind of package-private scope, but generalized from
|
||||
packages to arbitrary binding scopes in Scheme.
|
||||
|
||||
For example, the following @scheme[fish%] and @scheme[pond%] classes cooperate
|
||||
via a @scheme[get-depth] method that is only accessible to the
|
||||
cooperating classes:
|
||||
|
||||
@schemeblock[
|
||||
(define-values (fish% pond%) (code:comment #,(t "two mutually recursive classes"))
|
||||
(let () ; create a local definition scope
|
||||
(define-member-name get-depth (generate-member-key))
|
||||
(define fish%
|
||||
(class ... (define my-depth ...)
|
||||
(define my-pond ...)
|
||||
(define/public (dive amt)
|
||||
(set! my-depth
|
||||
(min (+ my-depth amt)
|
||||
(send my-pond get-depth))))))
|
||||
(define pond%
|
||||
(class ... (define current-depth ...)
|
||||
(define/public (get-depth) current-depth)))
|
||||
(values fish% pond%)))
|
||||
]
|
||||
|
||||
External names are in a namespace that separates them from other Scheme
|
||||
names. This separate namespace is implicitly used for the method name in
|
||||
@scheme[send], for initialization-argument names in @scheme[new], or for
|
||||
the external name in a member definition. The special
|
||||
@scheme[member-name-key] provides access to the binding of an external name
|
||||
in an arbitrary expression position: @scheme[(member-name-key id)] form
|
||||
produces the member-key binding of @scheme[id] in the current scope.
|
||||
|
||||
A member-key value is primarily used on with a
|
||||
@scheme[define-member-name] form. Normally, then,
|
||||
@scheme[(member-name-key id)] captures the method key of @scheme[id]
|
||||
so that it can be communicated to a use of @scheme[define-member-name]
|
||||
in a different scope. This capability turns out to be useful for
|
||||
generalizing mixins (see \SecRef{sec:parammixins}).
|
|
@ -133,8 +133,8 @@ To make a structure type @defterm{transparent}, use the
|
|||
field-name sequence:
|
||||
|
||||
@def+int[
|
||||
'(define-struct posn (x y)
|
||||
#:inspector #f)
|
||||
(define-struct posn (x y)
|
||||
#:inspector #f)
|
||||
(make-posn 1 2)
|
||||
]
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
@require[(lib "manual.ss" "scribble")]
|
||||
@require[(lib "eval.ss" "scribble")]
|
||||
@require["guide-utils.ss"]
|
||||
|
||||
@interaction-eval[(require (lib "string.ss"))]
|
||||
@require[(lib "string.ss")]
|
||||
|
||||
@title{Definitions: @scheme[define]}
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
@require[(lib "manual.ss" "scribble")]
|
||||
@require[(lib "eval.ss" "scribble")]
|
||||
@require["guide-utils.ss"]
|
||||
|
||||
@interaction-eval[(require (lib "for.ss"))]
|
||||
@require[(lib "for.ss")]
|
||||
|
||||
@title[#:tag "guide:for"]{Iterations and Comprehensions}
|
||||
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
(module guide-utils mzscheme
|
||||
(module guide-utils (lib "new-lambda.ss" "scribblings")
|
||||
(require (lib "manual.ss" "scribble")
|
||||
(lib "struct.ss" "scribble")
|
||||
(lib "decode.ss" "scribble")
|
||||
(lib "kw.ss")
|
||||
(lib "eval.ss" "scribble"))
|
||||
|
||||
(interaction-eval (require (lib "new-lambda.ss" "scribblings")))
|
||||
|
||||
|
||||
(provide Quick MzScheme HtDP
|
||||
tool
|
||||
refdetails
|
||||
|
@ -26,7 +23,7 @@
|
|||
(define (tool name . desc)
|
||||
(apply item (bold name) ", " desc))
|
||||
|
||||
(define/kw (refdetails* tag what #:body s)
|
||||
(define (refdetails* tag what . s)
|
||||
(apply margin-note
|
||||
(decode-content (append (list "For " what " on ")
|
||||
s
|
||||
|
@ -34,10 +31,10 @@
|
|||
(refsecref tag)
|
||||
".")))))
|
||||
|
||||
(define/kw (refdetails tag #:body s)
|
||||
(define (refdetails tag . s)
|
||||
(apply refdetails* tag "more" s))
|
||||
|
||||
(define/kw (refdetails/gory tag #:body s)
|
||||
(define (refdetails/gory tag . s)
|
||||
(apply refdetails* tag "gory details" s))
|
||||
|
||||
(define (refsecref s)
|
||||
|
|
|
@ -38,7 +38,7 @@ describes the acceptable arguments and the result of the procedure
|
|||
using @idefterm{contracts}.
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@section[#:tag "classes"]{Classes and Objects}
|
||||
@include-section["class.scrbl"]
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
@require[(lib "eval.ss" "scribble")]
|
||||
@require["guide-utils.ss"]
|
||||
|
||||
@interaction-eval[(require (lib "file.ss"))]
|
||||
|
||||
@title{Local Binding}
|
||||
|
||||
Although internal @scheme[define]s can be used for local binding,
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
@require[(lib "eval.ss" "scribble")]
|
||||
@require[(lib "bnf.ss" "scribble")]
|
||||
@require["guide-utils.ss"]
|
||||
@require[(lib "list.ss")]
|
||||
@require[(lib "for.ss")]
|
||||
|
||||
@interaction-eval[(require (lib "list.ss"))]
|
||||
@interaction-eval[(require (lib "for.ss"))]
|
||||
@define[step @elem{=}]
|
||||
|
||||
@title{Lists, Iteration, and Recursion}
|
||||
|
@ -212,12 +212,12 @@ argument @scheme[len]:
|
|||
|
||||
@schemeblock[
|
||||
(define (my-length lst)
|
||||
(code:comment #, @elem{local function @scheme[iter]:})
|
||||
(code:comment #, @t{local function @scheme[iter]:})
|
||||
(define (iter lst len)
|
||||
(cond
|
||||
[(empty? lst) len]
|
||||
[else (iter (rest lst) (+ len 1))]))
|
||||
(code:comment #, @elem{body of @scheme[my-length] calls @scheme[iter]:})
|
||||
(code:comment #, @t{body of @scheme[my-length] calls @scheme[iter]:})
|
||||
(iter lst 0))
|
||||
]
|
||||
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
@require[(lib "manual.ss" "scribble")]
|
||||
@require[(lib "eval.ss" "scribble")]
|
||||
@require["guide-utils.ss"]
|
||||
|
||||
@interaction-eval[(require (lib "list.ss"))]
|
||||
@interaction-eval[(define mutable-cons cons)]
|
||||
@require[(lib "list.ss")]
|
||||
@define[mutable-cons cons]
|
||||
|
||||
@title{Pairs and Lists}
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
@require[(lib "manual.ss" "scribble")]
|
||||
@require[(lib "eval.ss" "scribble")]
|
||||
@require["guide-utils.ss"]
|
||||
|
||||
@interaction-eval[(require (lib "list.ss"))]
|
||||
@require[(lib "list.ss")]
|
||||
|
||||
@title{Pairs, Lists, and Scheme Syntax}
|
||||
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
(module new-lambda mzscheme
|
||||
(require-for-syntax (lib "name.ss" "syntax")
|
||||
(lib "define.ss" "syntax"))
|
||||
(require "new-struct.ss")
|
||||
|
||||
(provide (all-from-except mzscheme #%datum lambda define #%app)
|
||||
(provide (all-from-except mzscheme #%datum lambda define #%app define-struct)
|
||||
(rename new-datum #%datum)
|
||||
(rename new-lambda lambda)
|
||||
(rename new-define define)
|
||||
(rename new-app #%app)
|
||||
(rename *make-keyword-procedure make-keyword-procedure)
|
||||
keyword-apply
|
||||
procedure-keywords)
|
||||
procedure-keywords
|
||||
(rename define-struct* define-struct)
|
||||
struct-field-index)
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
|
@ -366,7 +369,7 @@
|
|||
(make-optional-keyword-procedure
|
||||
with-kws
|
||||
null
|
||||
'(kw ...)
|
||||
'kws
|
||||
no-kws))))]
|
||||
[else
|
||||
;; just the keywords part dispatches to core,
|
||||
|
|
413
collects/scribblings/new-struct.ss
Normal file
|
@ -0,0 +1,413 @@
|
|||
|
||||
;; Based on
|
||||
;; (planet "struct.ss" ("ryanc" "macros.plt" 1 0)))
|
||||
;; though, strangely and embarassingly, Matthew didn't know that until
|
||||
;; after he had mostly re-implemented it.
|
||||
|
||||
(module new-struct mzscheme
|
||||
(require (lib "stxparam.ss"))
|
||||
|
||||
(provide define-struct*
|
||||
struct-field-index)
|
||||
|
||||
(define-syntax-parameter struct-field-index
|
||||
(lambda (stx)
|
||||
(raise-syntax-error #f "allowed only within a structure type definition" stx)))
|
||||
|
||||
(define (check-struct-type name what)
|
||||
(when what
|
||||
(unless (struct-type? what)
|
||||
(raise-type-error name "struct-type or #f" what)))
|
||||
what)
|
||||
|
||||
(define (check-inspector name what)
|
||||
(when what
|
||||
(unless (inspector? what)
|
||||
(raise-type-error name "inspector or #f" what)))
|
||||
what)
|
||||
|
||||
(define-syntax (define-struct* stx)
|
||||
(define make-field list)
|
||||
(define field-id car)
|
||||
(define field-default-value cadr)
|
||||
(define field-auto? caddr)
|
||||
(define field-immutable? cadddr)
|
||||
|
||||
(define (struct-declaration-info? x)
|
||||
(define (identifier/#f? x)
|
||||
(or (not x)
|
||||
(identifier? x)))
|
||||
(define (id/#f-list? id? x)
|
||||
(or (null? x)
|
||||
(and (pair? x)
|
||||
(if (null? (cdr x))
|
||||
(identifier/#f? (car x))
|
||||
(and (id? (car x))
|
||||
(id/#f-list? id? (cdr x)))))))
|
||||
(and (list? x)
|
||||
(= (length x) 6)
|
||||
(identifier/#f? (car x))
|
||||
(identifier/#f? (cadr x))
|
||||
(identifier/#f? (caddr x))
|
||||
(id/#f-list? identifier? (list-ref x 3))
|
||||
(id/#f-list? identifier/#f? (list-ref x 4))
|
||||
(or (eq? #t (list-ref x 5)) (identifier/#f? (list-ref x 5)))))
|
||||
|
||||
(define (build-name id . parts)
|
||||
(datum->syntax-object
|
||||
id
|
||||
(string->symbol
|
||||
(apply string-append
|
||||
(map (lambda (p)
|
||||
(if (syntax? p)
|
||||
(symbol->string (syntax-e p))
|
||||
p))
|
||||
parts)))
|
||||
id))
|
||||
|
||||
(define (bad why kw where)
|
||||
(raise-syntax-error
|
||||
#f
|
||||
(format "~a ~a specification~a"
|
||||
why
|
||||
(syntax-e kw)
|
||||
where)
|
||||
stx
|
||||
kw))
|
||||
|
||||
(define (check-exprs n ps)
|
||||
(let loop ([nps (cdr ps)][n n])
|
||||
(unless (zero? n)
|
||||
(unless (and (pair? nps)
|
||||
(not (keyword? (syntax-e (car nps)))))
|
||||
(raise-syntax-error
|
||||
#f
|
||||
(format "expected ~a expression~a after keyword~a"
|
||||
n
|
||||
(if (= n 1) "" "s")
|
||||
(if (pair? nps)
|
||||
", found a keyword"
|
||||
""))
|
||||
stx
|
||||
(car ps)))
|
||||
(loop (cdr nps) (sub1 n)))))
|
||||
|
||||
;; Parse one field with a sequence of keyword-based specs:
|
||||
(define (parse-field f)
|
||||
(syntax-case f ()
|
||||
[id
|
||||
(identifier? #'id)
|
||||
(make-field #'id #f #f #f)]
|
||||
[(id p ...)
|
||||
(identifier? #'id)
|
||||
(let loop ([ps (syntax->list #'(p ...))]
|
||||
[def-val #f]
|
||||
[auto? #f]
|
||||
[immutable? #f])
|
||||
(cond
|
||||
[(null? ps) (make-field #'id def-val auto? immutable?)]
|
||||
[(eq? #:immutable (syntax-e (car ps)))
|
||||
(when immutable?
|
||||
(bad "redundant" (car ps) " for field"))
|
||||
(loop (cdr ps) def-val auto? #t)]
|
||||
[(eq? #:default (syntax-e (car ps)))
|
||||
(check-exprs 1 ps)
|
||||
(when def-val
|
||||
(bad "multiple" (car ps) " for field"))
|
||||
(loop (cddr ps) (cadr ps) auto? immutable?)]
|
||||
[(eq? #:auto (syntax-e (car ps)))
|
||||
(when auto?
|
||||
(bad "redundant" (car ps) " for field"))
|
||||
(loop (cdr ps) def-val #t immutable?)]
|
||||
[else
|
||||
(raise-syntax-error
|
||||
#f
|
||||
(if (keyword? (syntax-e (car ps)))
|
||||
"unrecognized field-specification keyword"
|
||||
"expected a field-spefication keyword")
|
||||
stx
|
||||
(car ps))]))]
|
||||
[_else
|
||||
(raise-syntax-error
|
||||
#f
|
||||
"expected a field identifier or a parenthesized identifier and field-specification sequence"
|
||||
stx
|
||||
f)]))
|
||||
|
||||
(define (lookup config s)
|
||||
(cdr (assq s config)))
|
||||
|
||||
(define (extend-config config s val)
|
||||
(cond
|
||||
[(null? config) (error 'struct "internal error: can't find config element: ~s" s)]
|
||||
[(eq? (caar config) s) (cons (cons s val) (cdr config))]
|
||||
[else (cons (car config) (extend-config (cdr config) s val))]))
|
||||
|
||||
;; Parse sequence of keyword-based struct specs
|
||||
(define (parse-props p super-id)
|
||||
(let loop ([p p]
|
||||
[config '((#:super . #f)
|
||||
(#:inspector . #f)
|
||||
(#:auto-value . #f)
|
||||
(#:props . ())
|
||||
(#:immutable . #f)
|
||||
(#:guard . #f)
|
||||
(#:omit-define-values . #f)
|
||||
(#:omit-define-syntaxes . #f))])
|
||||
(cond
|
||||
[(null? p) config]
|
||||
[(eq? #:super (syntax-e (car p)))
|
||||
(check-exprs 1 p)
|
||||
(when (lookup config '#:super)
|
||||
(bad "multiple" (car p) ""))
|
||||
(when super-id
|
||||
(raise-syntax-error
|
||||
#f
|
||||
(string-append
|
||||
"#:super specification disallowed because a struct supertype id"
|
||||
" was supplied with the struct type id")
|
||||
stx
|
||||
(car p)))
|
||||
(loop (cddr p)
|
||||
(extend-config config '#:super (cadr p)))]
|
||||
[(memq (syntax-e (car p))
|
||||
'(#:inspector #:guard #:auto-value))
|
||||
(let ([key (syntax-e (car p))])
|
||||
(check-exprs 1 p)
|
||||
(when (lookup config key)
|
||||
(bad "multiple" (car p) ""))
|
||||
(loop (cddr p)
|
||||
(extend-config config key (cadr p))))]
|
||||
[(eq? #:property (syntax-e (car p)))
|
||||
(check-exprs 2 p)
|
||||
(loop (cdddr p)
|
||||
(extend-config config
|
||||
'#:props
|
||||
(cons (cons (cadr p) (caddr p))
|
||||
(lookup config '#:props))))]
|
||||
[(memq (syntax-e (car p))
|
||||
'(#:immutable #:omit-define-values #:omit-define-syntaxes))
|
||||
(let ([key (syntax-e (car p))])
|
||||
(when (lookup config key)
|
||||
(bad "redundant" (car p) ""))
|
||||
(loop (cdr p)
|
||||
(extend-config config key #t)))]
|
||||
[else
|
||||
(raise-syntax-error
|
||||
#f
|
||||
(if (keyword? (syntax-e (car p)))
|
||||
"unrecognized struct-specification keyword"
|
||||
"expected a struct-spefication keyword")
|
||||
stx
|
||||
(car p))])))
|
||||
|
||||
(syntax-case stx ()
|
||||
[(fm id (field ...) prop ...)
|
||||
(let-values ([(id super-id)
|
||||
(if (identifier? #'id)
|
||||
(values #'id #f)
|
||||
(syntax-case #'id ()
|
||||
[(id super-id)
|
||||
(and (identifier? #'id)
|
||||
(identifier? #'super-id))
|
||||
(values #'id #'super-id)]
|
||||
[else
|
||||
(raise-syntax-error
|
||||
#f
|
||||
(string-append
|
||||
"expected an identifier for the struct type name, or a parenthesized sequence"
|
||||
" with an identifier followed by the struct supertype identifier")
|
||||
stx)]))])
|
||||
(let ([super-info
|
||||
(and super-id
|
||||
(let ([v (syntax-local-value super-id (lambda () #f))])
|
||||
(if (struct-declaration-info? v)
|
||||
v
|
||||
(raise-syntax-error
|
||||
#f
|
||||
(format "parent struct type not defined~a"
|
||||
(if v
|
||||
(format " (~a does not name struct type information)"
|
||||
(syntax-e super-id))
|
||||
""))
|
||||
stx
|
||||
super-id))))])
|
||||
(when (and super-info
|
||||
(not (car super-info)))
|
||||
(raise-syntax-error
|
||||
#f
|
||||
"no structure type descriptor available for supertype"
|
||||
stx
|
||||
super-id))
|
||||
(let* ([field-stxes (syntax->list #'(field ...))]
|
||||
[fields (map parse-field field-stxes)]
|
||||
[dup (check-duplicate-identifier (map field-id fields))])
|
||||
(when dup
|
||||
(raise-syntax-error
|
||||
#f
|
||||
"duplicate field identifier"
|
||||
stx
|
||||
dup))
|
||||
(let ([auto-count
|
||||
(let loop ([fields fields] [field-stxes field-stxes] [auto? #f])
|
||||
(cond
|
||||
[(null? fields) 0]
|
||||
[(field-auto? (car fields))
|
||||
(+ 1 (loop (cdr fields) (cdr field-stxes) #t))]
|
||||
[auto?
|
||||
(raise-syntax-error
|
||||
#f
|
||||
"non-auto field after an auto field disallowed"
|
||||
stx
|
||||
(car field-stxes))]
|
||||
[else
|
||||
(loop (cdr fields) (cdr field-stxes) #f)]))])
|
||||
(let-values ([(inspector super-expr props auto-val guard immutable?
|
||||
omit-define-values? omit-define-syntaxes?)
|
||||
(let ([config (parse-props (syntax->list #'(prop ...)) super-id)])
|
||||
(values (lookup config '#:inspector)
|
||||
(lookup config '#:super)
|
||||
(lookup config '#:props)
|
||||
(lookup config '#:auto-value)
|
||||
(lookup config '#:guard)
|
||||
(lookup config '#:immutable)
|
||||
(lookup config '#:omit-define-values)
|
||||
(lookup config '#:omit-define-syntaxes)))])
|
||||
(when immutable?
|
||||
(for-each (lambda (f f-stx)
|
||||
(when (field-immutable? f)
|
||||
(raise-syntax-error
|
||||
#f
|
||||
"redundant #:immutable specification in field"
|
||||
stx
|
||||
f-stx)))
|
||||
fields field-stxes))
|
||||
(let ([struct: (build-name id "struct:" id)]
|
||||
[make- (build-name id "make-" id)]
|
||||
[? (build-name id id "?")]
|
||||
[sels (map (lambda (f)
|
||||
(build-name (field-id f)
|
||||
id "-" (field-id f)))
|
||||
fields)]
|
||||
[sets (if immutable?
|
||||
null
|
||||
(let loop ([fields fields])
|
||||
(cond
|
||||
[(null? fields) null]
|
||||
[(field-immutable? (car fields))
|
||||
(loop (cdr fields))]
|
||||
[else
|
||||
(cons (build-name (field-id (car fields))
|
||||
"set-"
|
||||
id
|
||||
"-"
|
||||
(field-id (car fields))
|
||||
"!")
|
||||
(loop (cdr fields)))])))]
|
||||
[super-struct: (if super-info
|
||||
(or (car super-info)
|
||||
(raise-syntax-error
|
||||
#f
|
||||
"no structure type descriptor available for supertype"
|
||||
stx
|
||||
super-id))
|
||||
(and super-expr
|
||||
#`(check-struct-type 'fm #,super-expr)))])
|
||||
(let ([run-time-defns
|
||||
(lambda ()
|
||||
(quasisyntax/loc stx
|
||||
(define-values (#,struct: #,make- #,? #,@sels #,@sets)
|
||||
(let-values ([(struct: make- ? -ref -set!)
|
||||
(syntax-parameterize ([struct-field-index
|
||||
(lambda (stx)
|
||||
(syntax-case stx #,(map field-id fields)
|
||||
#,@(let loop ([fields fields][pos 0])
|
||||
(cond
|
||||
[(null? fields) null]
|
||||
[else (cons #`[(_ #,(field-id (car fields))) #'#,pos]
|
||||
(loop (cdr fields) (add1 pos)))]))
|
||||
[(_ name) (raise-syntax-error #f "no such field" stx #'name)]))])
|
||||
(make-struct-type '#,id
|
||||
#,super-struct:
|
||||
#,(- (length fields) auto-count)
|
||||
#,auto-count
|
||||
#,auto-val
|
||||
#,(if (null? props)
|
||||
#'null
|
||||
#`(list #,@(map (lambda (p)
|
||||
#`(cons #,(car p) #,(cdr p)))
|
||||
props)))
|
||||
#,(if inspector
|
||||
#`(check-inspector 'fm #,inspector)
|
||||
#`(current-inspector))
|
||||
#f
|
||||
'#,(let loop ([i 0]
|
||||
[fields fields])
|
||||
(cond
|
||||
[(null? fields) null]
|
||||
[(or immutable? (field-immutable? (car fields)))
|
||||
(cons i (loop (add1 i) (cdr fields)))]
|
||||
[else (loop (add1 i) (cdr fields))]))
|
||||
#,guard))])
|
||||
(values struct: make- ?
|
||||
#,@(let loop ([i 0][fields fields])
|
||||
(if (null? fields)
|
||||
null
|
||||
(cons #`(make-struct-field-accessor -ref #,i '#,(field-id (car fields)))
|
||||
(loop (add1 i) (cdr fields)))))
|
||||
#,@(if immutable?
|
||||
null
|
||||
(let loop ([i 0][fields fields])
|
||||
(if (null? fields)
|
||||
null
|
||||
(if (field-immutable? (car fields))
|
||||
(loop (add1 i) (cdr fields))
|
||||
(cons #`(make-struct-field-mutator -set! #,i '#,(field-id (car fields)))
|
||||
(loop (add1 i) (cdr fields))))))))))))]
|
||||
[compile-time-defns
|
||||
(lambda ()
|
||||
(let ([protect (lambda (sel)
|
||||
(if (syntax-e sel)
|
||||
#`(c (quote-syntax #,sel))
|
||||
sel))])
|
||||
(quasisyntax/loc stx
|
||||
(define-syntaxes (#,id)
|
||||
(let ([c (syntax-local-certifier)])
|
||||
(list-immutable
|
||||
(c (quote-syntax #,struct:))
|
||||
(c (quote-syntax #,make-))
|
||||
(c (quote-syntax #,?))
|
||||
(list-immutable
|
||||
#,@(map protect sels)
|
||||
#,@(if super-info
|
||||
(map protect (list-ref super-info 3))
|
||||
(if super-expr
|
||||
'(#f)
|
||||
null)))
|
||||
(list-immutable
|
||||
#,@(let loop ([fields fields][sets sets])
|
||||
(cond
|
||||
[(null? fields) null]
|
||||
[(or immutable? (field-immutable? (car fields)))
|
||||
(cons #f (loop (cdr fields) sets))]
|
||||
[else
|
||||
(cons (protect (car sets))
|
||||
(loop (cdr fields) (cdr sets)))]))
|
||||
#,@(if super-info
|
||||
(map protect (list-ref super-info 4))
|
||||
(if super-expr
|
||||
'(#f)
|
||||
null)))
|
||||
#,(if super-id
|
||||
(protect super-id)
|
||||
(if super-expr
|
||||
#f
|
||||
#t))))))))])
|
||||
(cond
|
||||
[(and (not omit-define-values?) (not omit-define-syntaxes?))
|
||||
#`(begin #,(run-time-defns) #,(compile-time-defns))]
|
||||
[omit-define-syntaxes?
|
||||
(run-time-defns)]
|
||||
[omit-define-values?
|
||||
(compile-time-defns)]
|
||||
[else #'(begin)]))))))))])))
|
|
@ -1,7 +1,3 @@
|
|||
(0 () 0 () () (c! require c! (c! lib c! "slideshow.ss" c! "slideshow")))
|
||||
(0 () 0 () () (void))
|
||||
(0 () 0 () () (c! require-for-syntax c! mzscheme))
|
||||
(0 () 0 () () (void))
|
||||
(0 () 0 () () 5)
|
||||
(0 () 0 () () 5)
|
||||
(0 () 0 () () "art gallery")
|
||||
|
|
Before Width: | Height: | Size: 209 B After Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 102 B After Width: | Height: | Size: 102 B |
Before Width: | Height: | Size: 710 B After Width: | Height: | Size: 658 B |
Before Width: | Height: | Size: 143 B After Width: | Height: | Size: 143 B |
Before Width: | Height: | Size: 209 B After Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 77 B After Width: | Height: | Size: 77 B |
Before Width: | Height: | Size: 300 B After Width: | Height: | Size: 288 B |
Before Width: | Height: | Size: 837 B After Width: | Height: | Size: 819 B |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 102 B After Width: | Height: | Size: 102 B |
Before Width: | Height: | Size: 300 B After Width: | Height: | Size: 288 B |
Before Width: | Height: | Size: 388 B After Width: | Height: | Size: 372 B |
Before Width: | Height: | Size: 77 B After Width: | Height: | Size: 77 B |
Before Width: | Height: | Size: 242 B After Width: | Height: | Size: 236 B |
18
collects/scribblings/quick/mred-doc.ss
Normal file
|
@ -0,0 +1,18 @@
|
|||
(module mred-doc mzscheme
|
||||
|
||||
(define mr-eval? (getenv "MREVAL"))
|
||||
|
||||
(define-syntax bounce
|
||||
(syntax-rules ()
|
||||
[(_ id)
|
||||
(begin
|
||||
(provide id)
|
||||
(define id (if mr-eval?
|
||||
(dynamic-require '(lib "mred.ss" "mred") 'id)
|
||||
#f)))]
|
||||
[(_ id ...)
|
||||
(begin (bounce id) ...)]))
|
||||
|
||||
(bounce frame% canvas%
|
||||
bitmap% bitmap-dc%
|
||||
color%))
|
|
@ -7,6 +7,8 @@
|
|||
(lib "file.ss")
|
||||
(lib "runtime-path.ss")
|
||||
(lib "serialize.ss")
|
||||
"slideshow-doc.ss"
|
||||
"mred-doc.ss"
|
||||
(lib "exn.ss" "scribblings" "quick"))
|
||||
|
||||
(define-syntax define-mr
|
||||
|
@ -17,8 +19,7 @@
|
|||
(define-syntax mr
|
||||
(syntax-rules ()
|
||||
[(_ x (... ...))
|
||||
(parameterize ([scribble-eval-handler mr-eval-handler]
|
||||
[current-int-namespace mr-namespace])
|
||||
(parameterize ([scribble-eval-handler mr-eval-handler])
|
||||
(orig x (... ...)))])))]))
|
||||
|
||||
(define-mr mr-interaction interaction)
|
||||
|
@ -46,7 +47,7 @@
|
|||
(let ([eh (scribble-eval-handler)]
|
||||
[log-file (open-output-file exprs-dat-file 'truncate/replace)])
|
||||
(lambda (catching-exns? expr)
|
||||
(write (serialize expr) log-file)
|
||||
(write (serialize (syntax-object->datum expr)) log-file)
|
||||
(newline log-file)
|
||||
(flush-output log-file)
|
||||
(let ([result
|
||||
|
@ -76,7 +77,7 @@
|
|||
(if (eof-object? v)
|
||||
(error "expression not in log file")
|
||||
(let ([v (deserialize v)])
|
||||
(if (equal? v expr)
|
||||
(if (equal? v (syntax-object->datum expr))
|
||||
(let ([v (read log-file)])
|
||||
(if (eof-object? v)
|
||||
(error "expression result missing in log file")
|
||||
|
@ -91,50 +92,22 @@
|
|||
expr
|
||||
v))))))))))
|
||||
|
||||
(define mr-namespace
|
||||
(if mred?
|
||||
((dynamic-require '(lib "mred.ss" "mred") 'make-namespace-with-mred))
|
||||
(let ([ns (make-namespace)])
|
||||
(namespace-attach-module (current-namespace)
|
||||
'(lib "struct.ss" "scribble")
|
||||
ns)
|
||||
(namespace-attach-module (current-namespace)
|
||||
'(lib "exn.ss" "scribblings" "quick")
|
||||
ns)
|
||||
ns)))
|
||||
(define mr-namespace (current-namespace))
|
||||
|
||||
(define image-counter 0)
|
||||
|
||||
(define (ss:pict?)
|
||||
(with-handlers ([exn:fail? (lambda (x) (lambda (x) #f))])
|
||||
(eval 'pict? mr-namespace)))
|
||||
(define (ss:pict-width)
|
||||
(eval 'pict-width mr-namespace))
|
||||
(define (ss:pict-height)
|
||||
(eval 'pict-height mr-namespace))
|
||||
(define (ss:make-pict-drawer)
|
||||
(eval 'make-pict-drawer mr-namespace))
|
||||
(define (ss:colorize)
|
||||
(eval 'colorize mr-namespace))
|
||||
(define (mred:canvas%)
|
||||
(dynamic-require '(lib "mred.ss" "mred") 'canvas%))
|
||||
(define (mred:bitmap%)
|
||||
(dynamic-require '(lib "mred.ss" "mred") 'bitmap%))
|
||||
(define (mred:bitmap-dc%)
|
||||
(dynamic-require '(lib "mred.ss" "mred") 'bitmap-dc%))
|
||||
|
||||
(define (fixup-picts v)
|
||||
(cond
|
||||
[((ss:pict?) v)
|
||||
[(pict? v)
|
||||
(let ([fn (format "~a/img~a.png" img-dir image-counter)])
|
||||
(set! image-counter (add1 image-counter))
|
||||
(let* ([bm (make-object (mred:bitmap%)
|
||||
(inexact->exact (ceiling ((ss:pict-width) v)))
|
||||
(inexact->exact (ceiling ((ss:pict-height) v))))]
|
||||
[dc (make-object (mred:bitmap-dc%) bm)])
|
||||
(let* ([bm (make-object bitmap%
|
||||
(inexact->exact (ceiling (pict-width v)))
|
||||
(inexact->exact (ceiling (pict-height v))))]
|
||||
[dc (make-object bitmap-dc% bm)])
|
||||
(send dc set-smoothing 'aligned)
|
||||
(send dc clear)
|
||||
(((ss:make-pict-drawer) v) dc 0 0)
|
||||
((make-pict-drawer (colorize v (make-object color% 0 0 #xAF))) dc 0 0)
|
||||
(send bm save-file fn 'png)
|
||||
(make-element #f (list (make-element (make-image-file fn) (list "[image]"))))))]
|
||||
[(pair? v) (cons (fixup-picts (car v))
|
||||
|
|
|
@ -7,9 +7,16 @@
|
|||
@require[(lib "manual.ss" "scribble")]
|
||||
@require["mreval.ss"]
|
||||
@require[(lib "urls.ss" "scribble")]
|
||||
@require[(lib "class.ss")]
|
||||
@require["slideshow-doc.ss"]
|
||||
@require["slideshow-code-doc.ss"]
|
||||
@require["mred-doc.ss"]
|
||||
@require-for-syntax[mzscheme]
|
||||
|
||||
@mr-interaction-eval[(require (lib "slideshow.ss" "slideshow"))]
|
||||
@mr-interaction-eval[(require-for-syntax mzscheme)]
|
||||
@define[filled-flash (lambda args (apply (eval 'filled-flash) args))]
|
||||
@define[random-gaussian (lambda args (apply (eval 'random-gaussian) args))]
|
||||
@define-syntax[code (syntax-rules () [(_ v) (typeset-code (quote-syntax v))])]
|
||||
@provide[filled-flash random-gaussian code]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@section{Why Pictures? Why DrScheme?}
|
||||
|
|
18
collects/scribblings/quick/slideshow-code-doc.ss
Normal file
|
@ -0,0 +1,18 @@
|
|||
(module slideshow-code-doc mzscheme
|
||||
(require (only "slideshow-doc.ss"))
|
||||
|
||||
(define mr-eval? (getenv "MREVAL"))
|
||||
|
||||
(define-syntax bounce
|
||||
(syntax-rules ()
|
||||
[(_ id)
|
||||
(begin
|
||||
(provide id)
|
||||
(define id (if mr-eval?
|
||||
(dynamic-require '(lib "code.ss" "slideshow") 'id)
|
||||
#f)))]
|
||||
[(_ id ...)
|
||||
(begin (bounce id) ...)]))
|
||||
|
||||
(bounce typeset-code))
|
||||
|
30
collects/scribblings/quick/slideshow-doc.ss
Normal file
|
@ -0,0 +1,30 @@
|
|||
(module slideshow-doc mzscheme
|
||||
|
||||
(define mr-eval? (getenv "MREVAL"))
|
||||
|
||||
(when mr-eval?
|
||||
(parameterize ([current-command-line-arguments #()])
|
||||
(dynamic-require '(lib "slideshow.ss" "slideshow") #f)))
|
||||
|
||||
(define-syntax bounce
|
||||
(syntax-rules ()
|
||||
[(_ id)
|
||||
(begin
|
||||
(provide id)
|
||||
(define id (if mr-eval?
|
||||
(dynamic-require '(lib "slideshow.ss" "slideshow") 'id)
|
||||
#f)))]
|
||||
[(_ id ...)
|
||||
(begin (bounce id) ...)]))
|
||||
|
||||
(bounce circle
|
||||
rectangle
|
||||
hc-append
|
||||
filled-rectangle
|
||||
vc-append
|
||||
colorize
|
||||
scale
|
||||
bitmap
|
||||
make-pict-drawer
|
||||
|
||||
pict? pict-width pict-height))
|
|
@ -1,7 +1,6 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
|
||||
@interaction-eval[(require (lib "for.ss"))]
|
||||
@require[(lib "for.ss")]
|
||||
|
||||
@title[#:tag "mz:for"]{Iterations and Comprehensions: @scheme[for], @scheme[for/list], ...}
|
||||
|
||||
|
|
|
@ -497,11 +497,13 @@ forms. As a result, future references of the @tech{variable} always
|
|||
access the same @tech{location}.
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Modules and Module-Level Variables}
|
||||
@section[#:tag "mz:module-eval-model"]{Modules and Module-Level Variables}
|
||||
|
||||
Most definitions in PLT Scheme are in modules. In terms of evaluation,
|
||||
a module is essentially a prefix on a defined name, so that different
|
||||
modules can define the name.
|
||||
modules can define the name. That is, a @deftech{module-level
|
||||
variable} is like a @tech{top-level variable} from the perspective of
|
||||
evaluation.
|
||||
|
||||
One difference between a module an a top-level definition is that a
|
||||
module can be declared without instantiating its module-level
|
||||
|
@ -621,7 +623,7 @@ is created) as all other threads.
|
|||
@;------------------------------------------------------------------------
|
||||
@section{Parameters}
|
||||
|
||||
A @deftech{parameter} is essentially a derived concept in Scheme; they
|
||||
@deftech{Parameters} are essentially a derived concept in Scheme; they
|
||||
are defined in terms of continuation marks and thread cells. However,
|
||||
parameters are also built in, in the sense that some primitive
|
||||
procedures consult parameter values. For example, the default output
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
(lib "decode.ss" "scribble")
|
||||
(lib "kw.ss"))
|
||||
|
||||
(interaction-eval (require (lib "new-lambda.ss" "scribblings")))
|
||||
|
||||
(provide (all-from (lib "manual.ss" "scribble"))
|
||||
(all-from (lib "eval.ss" "scribble")))
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
Scheme's reader is a recursive-descent parser that can be configured
|
||||
through a @seclink["mz:readtables"]{readtable} and various other
|
||||
@seclink["parameters"]{parameters}. This section describes the reader's
|
||||
parsing when using the default readtable.
|
||||
@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
|
||||
|
@ -28,7 +28,7 @@ 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 @seclink["stxobj"]{syntax object} that includes
|
||||
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
|
||||
|
@ -164,7 +164,7 @@ 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] parameter is set to @scheme[#f],
|
||||
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},
|
||||
|
@ -202,7 +202,7 @@ which specifies its parsing as an exact or inexact number; see
|
|||
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] parameter is set to @scheme[#f], then
|
||||
@scheme[read-decimal-as-inexact] @tech{parameter} is set to @scheme[#f], then
|
||||
all numbers without an exactness specifier are instead parsed as
|
||||
exact.
|
||||
|
||||
|
@ -344,10 +344,10 @@ being parsed, then the @exnraise[exn:fail:read].
|
|||
"(1 . 2 . 3)"
|
||||
]
|
||||
|
||||
If the @scheme[read-square-bracket-as-paren] parameter is set to
|
||||
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] parameter is set to @scheme[#f],
|
||||
@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}.
|
||||
|
||||
|
@ -701,7 +701,7 @@ 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] parameter; the result is used as a
|
||||
@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]
|
||||
|
@ -718,7 +718,7 @@ 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] parameter is set to @scheme[#f],
|
||||
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].
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
|
||||
(module reader-example mzscheme
|
||||
(module reader-example (lib "new-lambda.ss" "scribblings")
|
||||
(require (lib "struct.ss" "scribble")
|
||||
(lib "decode.ss" "scribble")
|
||||
(lib "manual.ss" "scribble")
|
||||
(lib "scheme.ss" "scribble")
|
||||
(lib "kw.ss")
|
||||
(lib "class.ss"))
|
||||
|
||||
(provide reader-examples
|
||||
|
@ -22,10 +21,9 @@
|
|||
|
||||
(define spacer (hspace 1))
|
||||
|
||||
(define/kw (reader-examples #:key
|
||||
[symbols? #t]
|
||||
[example-note ""]
|
||||
#:body strs)
|
||||
(define (reader-examples #:symbols? [symbols? #t]
|
||||
#:example-note [example-note ""]
|
||||
. strs)
|
||||
(make-table
|
||||
#f
|
||||
(list
|
||||
|
@ -125,7 +123,7 @@
|
|||
(define (dispatch a . b)
|
||||
(list a (make-element #f (decode-content b))))
|
||||
|
||||
(define/kw (metavar #:body s)
|
||||
(define (metavar . s)
|
||||
(make-element 'italic (decode-content s)))
|
||||
|
||||
(define (cilitchar s)
|
||||
|
|
|
@ -308,9 +308,9 @@ things:
|
|||
identifier (third case in the previous enumeration), and
|
||||
parsing continues.}
|
||||
|
||||
@item{A core syntactic form, which is parsed as described for each
|
||||
form in @secref["mz:syntax"]. Parsing a core syntactic form
|
||||
typically involves recursive parsing of sub-forms, and may
|
||||
@item{A core @deftech{syntactic form}, which is parsed as described
|
||||
for each form in @secref["mz:syntax"]. Parsing a core syntactic
|
||||
form typically involves recursive parsing of sub-forms, and may
|
||||
introduce @tech{bindings} that determine the parsing of
|
||||
sub-forms.}
|
||||
|
||||
|
@ -340,7 +340,7 @@ contexts. The possible @tech{contexts} are as follows:
|
|||
@item{@deftech{internal-definition context} : in a nested context that allows
|
||||
both definitions and expressions.}
|
||||
|
||||
@item{@deftech{expression content} : in a context where only
|
||||
@item{@deftech{expression context} : in a context where only
|
||||
expressions are allowed.}
|
||||
|
||||
}
|
||||
|
@ -440,10 +440,10 @@ be @tech{expand}ed (i.e. parsed) before it can be evaluated, and it is
|
|||
expanded at @tech{phase level} 1 instead of @tech{phase level} 0.
|
||||
|
||||
The if resulting @scheme[value] is a procedure of one argument, then
|
||||
is it used as a @deftech{transformer procedure}. The procedure is
|
||||
is it used as a @deftech{syntax transformer}. The procedure is
|
||||
expected to accept a syntax object and return a syntax object. A use
|
||||
of the binding (at @tech{phase level} 0) triggers a call of the
|
||||
@tech{transformer procedure} by the expander; see
|
||||
@tech{syntax transformer} by the expander; see
|
||||
@secref["mz:expand-steps"].
|
||||
|
||||
Before the expander passes a @tech{syntax object} to a transformer,
|
||||
|
@ -547,7 +547,7 @@ If the last expression form turns out to be a @scheme[define-values]
|
|||
or @scheme[define-syntaxes] form, expansion fails with a syntax error.
|
||||
|
||||
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@subsection{Module Phases}
|
||||
@subsection[#:tag "mz:mod-parse"]{Module Phases}
|
||||
|
||||
A @scheme[require] form not only introduces @tech{bindings} at
|
||||
expansion time, but also @deftech{visits} the referenced module when
|
||||
|
|
|
@ -50,6 +50,48 @@ Within such specifications,
|
|||
|
||||
}} }
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Literals: @scheme[quote] and @scheme[#%datum]}
|
||||
|
||||
@defform[(quote datum)]{
|
||||
|
||||
Produces a constant value corresponding to @scheme[datum] (i.e., the
|
||||
actual representation of the program fragment) without its
|
||||
@tech{lexical information} or source location.
|
||||
|
||||
@examples[
|
||||
(eval:alts (#,(schemekeywordfont "quote") x) 'x)
|
||||
(eval:alts (#,(schemekeywordfont "quote") (+ 1 2)) '(+ 1 2))
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
@defform[(#%datum . datum)]{
|
||||
|
||||
Expands to @scheme[(#,(schemekeywordfont "quote") datum)]. See also @secref["mz:expand-steps"]
|
||||
for information on how the expander introduces @schemeidfont{#%datum}
|
||||
identifiers.
|
||||
|
||||
@examples[
|
||||
(#%datum . 10)
|
||||
(#%datum . x)
|
||||
]
|
||||
}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Expression Wrapper: @scheme[#%expression]}
|
||||
|
||||
@defform[(#%expression expr)]{
|
||||
|
||||
Produces the same result as @scheme[expr]. The only use of
|
||||
@scheme[#%expression] is to force the parsing of a form as an
|
||||
expression.
|
||||
|
||||
@examples[
|
||||
(#%expression (+ 1 2))
|
||||
(#%expression (define x 10))
|
||||
]}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Variable References and @scheme[#%top]}
|
||||
|
||||
|
@ -64,7 +106,7 @@ When the expander encounters an @scheme[id] that is not bound by a
|
|||
module-level or local binding, it converts the expression to @scheme[(#,
|
||||
@schemeidfont{#%top} . id)] giving @schemeidfont{#%top} the lexical
|
||||
context of the @scheme[id]; typically, that context refers to
|
||||
@scheme[#%top].
|
||||
@scheme[#%top]. See also @secref["mz:expand-steps"].
|
||||
|
||||
@examples[
|
||||
(define x 10)
|
||||
|
@ -75,15 +117,31 @@ x
|
|||
|
||||
@defform[(#%top . id)]{
|
||||
|
||||
Refers to a top-level definition that could bind @scheme[id],
|
||||
even if @scheme[id] has a local binding in its context. Such
|
||||
references are disallowed anywhere within a @scheme[module] form.
|
||||
Refers to a top-level definition that could bind @scheme[id], even if
|
||||
@scheme[id] has a local binding in its context. Such references are
|
||||
disallowed anywhere within a @scheme[module] form. See also
|
||||
@secref["mz:expand-steps"] for information on how the expander
|
||||
introduces @schemeidfont{#%top} identifiers.
|
||||
|
||||
@examples[
|
||||
(define x 12)
|
||||
(let ([x 5]) (#%top . x))
|
||||
]}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Locations: @scheme[#%variable-reference]}
|
||||
|
||||
@defform*[#:literals (#%top)
|
||||
[(#%variable-reference id)
|
||||
(#%variable-reference (#%top . id))]]{
|
||||
|
||||
Produces an opaque value representing the location of @scheme[id],
|
||||
which must be bound as a @tech{top-level variable} or
|
||||
@tech{module-level variable}.
|
||||
|
||||
The result is useful only to low-level extensions; see
|
||||
@secref["inside-mzscheme"].}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:application"]{Procedure Applications and @scheme[#%app]}
|
||||
|
||||
|
@ -100,7 +158,8 @@ More precisely, the expander converts this form to @scheme[(#,
|
|||
the lexical context that is associated with the original form (i.e.,
|
||||
the pair that combines @scheme[proc-expr] and its
|
||||
arguments). Typically, the lexical context of the pair indicates the
|
||||
procedure-application @scheme[#%app] that is described next.
|
||||
procedure-application @scheme[#%app] that is described next. See also
|
||||
@secref["mz:expand-steps"].
|
||||
|
||||
@examples[
|
||||
(+ 1 2)
|
||||
|
@ -138,6 +197,9 @@ the @scheme[_keyword]s, and not their positions. The other
|
|||
@scheme[_arg-expr] values, in contrast, are associated with variables
|
||||
according to their order in the application form.
|
||||
|
||||
See also @secref["mz:expand-steps"] for information on how the
|
||||
expander introduces @schemeidfont{#%app} identifiers.
|
||||
|
||||
@examples[
|
||||
(#%app + 1 2)
|
||||
(#%app (lambda (x #:arg y) (list y x)) #:arg 2 1)
|
||||
|
@ -442,8 +504,8 @@ using the @|cvt| meta-function defined as follows:
|
|||
|
||||
At the top level, the top-level binding @scheme[id] is created after
|
||||
evaluating @scheme[expr], if it does not exist already, and the
|
||||
top-level mapping of @scheme[id] (see @secref["mz:namespace"]) is set
|
||||
to the binding at the same time.
|
||||
top-level mapping of @scheme[id] (in the @techlink{namespace} linked
|
||||
with the compiled definition) is set to the binding at the same time.
|
||||
|
||||
@defexamples[
|
||||
(define x 10)
|
||||
|
@ -472,8 +534,9 @@ the @exnraise[exn:fail:contract].
|
|||
|
||||
At the top level, the top-level binding for each @scheme[id] is
|
||||
created after evaluating @scheme[expr], if it does not exist already,
|
||||
and the top-level mapping of each @scheme[id] (see
|
||||
@secref["mz:namespace"]) is set to the binding at the same time.
|
||||
and the top-level mapping of each @scheme[id] (in the
|
||||
@techlink{namespace} linked with the compiled definition) is set to
|
||||
the binding at the same time.
|
||||
|
||||
@defexamples[
|
||||
(define-values () (values))
|
||||
|
@ -526,6 +589,42 @@ in tail position only if no @scheme[body]s are present.
|
|||
(printf "hi\n"))
|
||||
]}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Assignment: @scheme[set!] and @scheme[set!-values]}
|
||||
|
||||
@defform[(set! id expr)]{
|
||||
|
||||
Evaluates @scheme[expr] and installs the result into the location for
|
||||
@scheme[id], which must be bound as a local variable or defined as a
|
||||
@tech{top-level variable} or @tech{module-level variable}. If
|
||||
@scheme[id] refers to a @tech{top-level variable} that has not been
|
||||
defined, the @exnraise[exn:fail:contract].
|
||||
|
||||
@defexamples[
|
||||
(define x 12)
|
||||
(set! x (add1 x))
|
||||
x
|
||||
(let ([x 5])
|
||||
(set! x (add1 x))
|
||||
x)
|
||||
(set! i-am-not-defined 10)
|
||||
]}
|
||||
|
||||
@defform[(set!-values (id ...) expr)]{
|
||||
|
||||
Evaluates @scheme[expr], which must produce as many values as supplied
|
||||
@scheme[id]s. The location of each @scheme[id] is filled wih to the
|
||||
corresponding value from @scheme[expr] in the same way as for
|
||||
@scheme[set!].
|
||||
|
||||
@examples[
|
||||
(let ([a 1]
|
||||
[b 2])
|
||||
(set!-values (a b) (values b a))
|
||||
(list a b))
|
||||
]}
|
||||
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Continuation Marks: @scheme[with-continuation-mark]}
|
||||
|
||||
|
@ -540,11 +639,196 @@ current continuation frame (see @secref["mz:contmarks"]), and then
|
|||
@section{Syntax Quoting: @scheme[quote-syntax]}
|
||||
|
||||
@defform[(quote-syntax datum)]{
|
||||
Produces a syntax object that preserves
|
||||
lexical and source-location information attached to @scheme[datum]
|
||||
at expansion time.
|
||||
|
||||
Produces a @tech{syntax object} that preserves the @tech{lexical
|
||||
information} and source-location information attached to
|
||||
@scheme[datum] at expansion time.
|
||||
|
||||
@examples[
|
||||
(syntax? (quote-syntax x))
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:require"]{Importing: @scheme[require], @scheme[require-for-syntax], @scheme[require-for-template]}
|
||||
|
||||
@defform/subs[#:literals (only prefix all-except prefix-all-except rename lib file planet)
|
||||
(require require-spec ...)
|
||||
([require-spec module-path
|
||||
(only require-spec id-maybe-renamed ...)
|
||||
(except require-spec id ...)
|
||||
(prefix require-spec prefix-id)
|
||||
(rename require-spec [orig-id bind-id] ...)]
|
||||
[module-path id
|
||||
rel-string
|
||||
(lib rel-string)
|
||||
(file string)
|
||||
(planet rel-string (user-string pkg-string vers ...))]
|
||||
[id-maybe-renamed id
|
||||
[orig-id bind-id]]
|
||||
[vers nat
|
||||
(nat nat)
|
||||
(= nat)
|
||||
(+ nat)
|
||||
(- nat)])]{
|
||||
|
||||
In a @tech{top-level context}, @scheme[require] instantiates modules
|
||||
(see @secref["mz:module-eval-model"]). In a @tech{module context},
|
||||
@scheme[require] visits modules (see @secref["mz:mod-parse"]). In both
|
||||
contexts, @scheme[require] introduces bindings into a @tech{namespace}
|
||||
or a module (see @secref["mz:intro-binding"]). A @scheme[require] form
|
||||
in a @tech{expression context} or @tech{internal-definition context}
|
||||
is a syntax error.
|
||||
|
||||
A @scheme[require-spec] designates a particular set of identifiers to
|
||||
be bound in the importing context. Each identifier is mapped to a
|
||||
particular export of a particular module; the identifier to bind may
|
||||
be different from the symbolic name of the originally exported
|
||||
identifier.
|
||||
|
||||
@specsubform[module-path]{ Imports all exported bindings from the
|
||||
named module, using the export identifier as the local identifiers.}
|
||||
|
||||
@specsubform[#:literals (only) (only require-spec id-maybe-renamed ...)]{
|
||||
Like @scheme[require-spec], but constrained to those exports for
|
||||
which the identifiers to bind match @scheme[id-maybe-renamed]: as
|
||||
@scheme[id] or as @scheme[orig-id] in @scheme[[orig-id bind-id]]. If
|
||||
the @scheme[id] of @scheme[orig-id] of any @scheme[id-maybe-renamed]
|
||||
is not in the set that @scheme[require-spec] describes, a syntax
|
||||
error is reported.}
|
||||
|
||||
@specsubform[#:literals (except) (except require-spec id ...)]{ Like
|
||||
@scheme[require-spec], but omitting those exports for which
|
||||
@scheme[id]s are the identifiers to bind; if any @scheme[id] is not
|
||||
in the set that @scheme[require-spec] describes, a syntax error is
|
||||
reported.}
|
||||
|
||||
@specsubform[#:literals (prefix) (prefix require-spec prefix-id)]{
|
||||
Like @scheme[require-spec], but adjusting each identifier to be bound
|
||||
by prefixing it with @scheme[prefix-id].}
|
||||
|
||||
@specsubform[#:literals (rename)
|
||||
(rename require-spec [orig-id bind-id] ...)]{
|
||||
Like @scheme[require-spec], but replacing the identifier to
|
||||
bind @scheme[orig-id] with @scheme[bind-id]; if any
|
||||
@scheme[orig-id] is not in the set that @scheme[require-spec]
|
||||
describes, a syntax error is reported.}
|
||||
|
||||
A @scheme[module-path] identifies a module, either through a concrete
|
||||
name in the form of an identifier, or through an indirect name that
|
||||
can trigger automatic loading of the module declaration:
|
||||
|
||||
@specsubform[id]{ Refers to a module previously declared with the name
|
||||
@scheme[id].}
|
||||
|
||||
@specsubform[rel-string]{A path relative to the containing source (as
|
||||
determined by @scheme[current-load-relative-directory] or
|
||||
@scheme[current-directory]). Regardless of the current platform,
|
||||
@scheme[rel-string] is always parsed as a Unix-format relative path:
|
||||
@litchar{/} is the path delimiter (multiple adjacent @litchar{/}s are
|
||||
treated as a single delimiter), @litchar{..} accesses the parent
|
||||
directory, and @litchar{.} accesses the current directory. The path
|
||||
cannot be empty or contain a leading or trailing slash.}
|
||||
|
||||
@specsubform[#:literals (lib) (lib rel-string)]{Like the plain
|
||||
@scheme[rel-string] case, but @scheme[rel-string] must contain at
|
||||
least two path elements. All path elements up to the last one form a
|
||||
@tech{collection} path, which is used to locate the relevant
|
||||
directory (not relative to the containing source), and the last path
|
||||
element refers to a file.}
|
||||
|
||||
@specsubform[#:literals (file) (file string)]{Similar to the plain
|
||||
@scheme[rel-string] case, but @scheme[string] is a path (possibly
|
||||
absolute) using the current platform's path conventions.}
|
||||
|
||||
@specsubform[#:literals(planet)
|
||||
(planet rel-string (user-string pkg-string vers ...))]{
|
||||
Specifies a library available via the @PLaneT server.
|
||||
}
|
||||
|
||||
No identifier can be bound multiple times by an import, unless all of
|
||||
the bindings refer to the same original definition in the same module.
|
||||
In a @tech{module context}, an identifier can be either imported or
|
||||
defined for a given @tech{phase level}, but not both.}
|
||||
|
||||
@defform[(require-for-syntax require-spec ...)]{
|
||||
Like @scheme[require], but @tech{instantiate}s a module at phase 1
|
||||
(see @secref["mz:module-eval-model"]) in a @tech{top-level context} or
|
||||
@tech{module context}, and introduces bindings at phase level 1 (see
|
||||
@secref["mz:intro-binding"] and @secref["mz:mod-parse"]).
|
||||
}
|
||||
|
||||
@defform[(require-for-template require-spec ...)]{ Like
|
||||
@scheme[require], but without @tech{instantiation} (see
|
||||
@secref["mz:module-eval-model"]) in a @tech{top-level context}, and
|
||||
introduces bindings at phase level -1 (see @secref["mz:intro-binding"]
|
||||
and @secref["mz:mod-parse"]).
|
||||
}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Exporting: @scheme[provide] and @scheme[provide-for-syntax]}
|
||||
|
||||
@defform/subs[#:literals (protect all-defined all-from rename except prefix)
|
||||
(provide protected-provide-spec ...)
|
||||
([protected-provide-spec provide-spec
|
||||
(protect provide-spec)]
|
||||
[provide-spec id
|
||||
(all-defined)
|
||||
(all-from module-name)
|
||||
(rename [orig-id export-id] ...)
|
||||
(except provide-spec id ...)
|
||||
(prefix provide-spec prefix-id)])]{
|
||||
|
||||
Declares exports from a module. A @scheme[provide] form must appear in
|
||||
a @tech{module context} or a @tech{module-begin} context.
|
||||
|
||||
A @scheme[provide-spec] indicates one or more bindings to provide,
|
||||
specifying for each an export symbol that can be different from
|
||||
the symbolic form of the identifier bound within the module:
|
||||
|
||||
@specsubform[id]{ Exports @scheme[id], which must be @tech{bound}
|
||||
within the module (i.e., either defined or imported), at @tech{phase
|
||||
level} 0 using the symbolic form of @scheme[id] as the external
|
||||
name.}
|
||||
|
||||
@specsubform[#:literals (all-defined) (all-defined)]{ Exports all
|
||||
identifiers that are defined at @tech{phase level} 0 within the
|
||||
exporting module. The external name for each identifier is the
|
||||
symbolic form of the identifier; note that this can lead to an
|
||||
illegal multiple export for a single symbolic name if different
|
||||
defined identifiers use the same symbolic name.}
|
||||
|
||||
@specsubform[#:literals (all-from) (all-from module-name)]{ Exports
|
||||
all identifiers that are imported into the exporting module at
|
||||
@tech{phase level} 0 using a @scheme[require-spec] built on
|
||||
@scheme[module-name] (see @secref["mz:require"]). The symbolic name
|
||||
for export is derived from the name that is bound within the module,
|
||||
as opposed to the symbolic name of the export from
|
||||
@scheme[module-name].}
|
||||
|
||||
@specsubform[#:literals (rename) (rename [orig-id export-id] ...)]{
|
||||
Exports each @scheme[orig-id], which must be @tech{bound} within the
|
||||
module at @tech{phase level} 0. The symbolic name for each export is
|
||||
@scheme[export-id] instead @scheme[orig-d].}
|
||||
|
||||
@specsubform[#:literals (except) (except provide-spec id ...)]{ Like
|
||||
@scheme[provide-spec], but omitting an export for each binding
|
||||
@scheme[id]. If @scheme[id] is not specified as an export by
|
||||
@scheme[provide-spec], a syntax error is reported.}
|
||||
|
||||
@specsubform[#:literals (prefix) (prefix provide-spec prefix-id)]{
|
||||
Like @scheme[provide-spec], but with each symbolic export name from
|
||||
@scheme[provide-spec] prefixed with @scheme[prefix-id].}
|
||||
|
||||
If @scheme[provide] wraps a @scheme[provide-spec], then the exports of
|
||||
the @scheme[provide-spec] are protected; see
|
||||
@secref["mz:protected-exports"]. The @scheme[provide-spec] must
|
||||
specify only bindings that are defined within the exporting module.
|
||||
|
||||
Each export specified within a module must have a distinct symbolic
|
||||
export name, though the same binding can be specified with the
|
||||
multiple symbolic names.}
|
||||
|
||||
@defform[(provide-for-syntax protected-provide-spec ...)]{Like
|
||||
@scheme[provide], but exports at @tech{phase level} 1 bindings within
|
||||
the module at @tech{phase level} 1.}
|
||||
|
|
|
@ -10,24 +10,24 @@ especially to show example uses of defined procedures and syntax.
|
|||
|
||||
@defform[(interaction datum ...)]{Like @scheme[schemeinput], except
|
||||
that the result for each input @scheme[datum] is shown on the next
|
||||
line. The result is determined by evaluating the quoted form of the
|
||||
datum.
|
||||
line. The result is determined by evaluating the syntax-quoted form of
|
||||
the @scheme[datum].
|
||||
|
||||
Uses of @scheme[code:comment] and @schemeidfont{code:blank} are
|
||||
stipped from each @scheme[datum] before evaluation.
|
||||
|
||||
If a datum has the form @scheme[(#,(scheme code:line) #,(svar datum)
|
||||
(#,(scheme code:comment) ...))], then only the @svar[datum] is
|
||||
evaluated.
|
||||
If a @scheme[datum] has the form @scheme[(#,(scheme code:line)
|
||||
_code-datum (#,(scheme code:comment) ...))], then only
|
||||
@scheme[_code-datum] is evaluated.
|
||||
|
||||
If a datum has the form @scheme[(eval:alts #,(svar show-datum) #,(svar
|
||||
eval-datum))], then @svar[show-datum] is typeset, while
|
||||
@svar[eval-datum] is evaluated.}
|
||||
|
||||
@defform[(interaction-eval datum)]{Evaluates the quoted form of
|
||||
@defform[(interaction-eval datum)]{Evaluates the syntax-quoted form of
|
||||
each @scheme[datum] via @scheme[do-eval] and returns the empty string.}
|
||||
|
||||
@defform[(interaction-eval-show datum)]{Evaluates the quoted form of
|
||||
@defform[(interaction-eval-show datum)]{Evaluates the syntax-quoted form of
|
||||
@scheme[datum] and produces an element represeting the printed form of
|
||||
the result.}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ more...
|
|||
@defform[(schemeblock datum ...)]{
|
||||
|
||||
Typesets the @scheme[datum] sequence as a table of Scheme code inset
|
||||
by two spaces. The source locations of the @scheme[datum]s determines
|
||||
by two spaces. The source locations of the @scheme[datum]s determine
|
||||
the generated layout. For example,
|
||||
|
||||
@schemeblock[
|
||||
|
@ -32,10 +32,13 @@ produces the output
|
|||
|
||||
with the @scheme[(loop (not x))] indented under @scheme[define],
|
||||
because that's the way it is idented the use of @scheme[schemeblock].
|
||||
|
||||
Furthermore, @scheme[define] is typeset as a keyword (bold and black)
|
||||
and as a hyperlink to @scheme[define]'s definition in the reference
|
||||
manual, because this document was built using information about the
|
||||
MzScheme manual. Similarly, @scheme[not] is a hyperlink to the its
|
||||
reference manual, and because the lexical binding of @scheme[define]
|
||||
(in the source) matches the lexical binding of the definition in the
|
||||
reference manual. Similarly, @scheme[not] is a hyperlink to the its
|
||||
definition in the reference manual.
|
||||
|
||||
Use @scheme[unsyntax] to escape back to an expression that produces an
|
||||
|
@ -127,7 +130,7 @@ useful with @scheme[verbatim].}
|
|||
|
||||
@defproc[(schemefont [pre-content any/c] ...) element?]{Typesets the given
|
||||
content as uncolored, unhyperlinked Scheme. This procedure is useful
|
||||
for typesetting thngs like @scheme{#module}, which are not
|
||||
for typesetting things like @scheme{#module}, which are not
|
||||
@scheme[read]able by themselves.}
|
||||
|
||||
@defproc[(schemevalfont [pre-content any/c] ...) element?]{Like
|
||||
|
@ -143,7 +146,7 @@ for typesetting thngs like @scheme{#module}, which are not
|
|||
@scheme[schemefont], but colored as a syntactic form name.}
|
||||
|
||||
@defproc[(procedure [pre-content any/c] ...) element?]{Typesets the given
|
||||
content as a procedure name in a REPL result (e.g., in typewrite font
|
||||
content as a procedure name in a REPL result (e.g., in typewriter font
|
||||
with a @schemefont{#<procedure:} prefix and @schemefont{>} suffix.).}
|
||||
|
||||
@defform[(var datum)]{Typesets @scheme[var] as an identifier that is
|
||||
|
@ -164,9 +167,9 @@ in a form definition.}
|
|||
pre-flow ...)]{
|
||||
|
||||
Produces a sequence of flow elements (encaptured in a @scheme[splice])
|
||||
to document a procedure named @scheme[id]. The
|
||||
@scheme[id] is registered so that @scheme[scheme]-typeset uses
|
||||
of the identifier are hyperlinked to this documentation.
|
||||
to document a procedure named @scheme[id]. The @scheme[id] is
|
||||
registered so that @scheme[scheme]-typeset uses of the identifier
|
||||
(with the same lexical binding) are hyperlinked to this documentation.
|
||||
|
||||
Each @scheme[arg-spec] must have one of the following forms:
|
||||
|
||||
|
@ -213,39 +216,54 @@ Like @scheme[defproc], but for multiple cases with the same
|
|||
@scheme[id]. }
|
||||
|
||||
|
||||
@defform[(defform (id . datum) pre-flow ...)]{Produces a
|
||||
a sequence of flow elements (encaptured in a @scheme[splice]) to
|
||||
document a syntatic form named by @scheme[id]. The
|
||||
@scheme[id] is registered so that @scheme[scheme]-typeset uses
|
||||
of the identifier are hyperlinked to this documentation.
|
||||
@defform/subs[(defform maybe-literals (id . datum) pre-flow ...)
|
||||
([maybe-literals code:blank
|
||||
(code:line #:literals (literal-id ...))])]{
|
||||
|
||||
Produces a a sequence of flow elements (encaptured in a
|
||||
@scheme[splice]) to document a syntatic form named by @scheme[id]. The
|
||||
@scheme[id] is registered so that @scheme[scheme]-typeset uses of the
|
||||
identifier (with the same lexical binding) are hyperlinked to this
|
||||
documentation.
|
||||
|
||||
The @scheme[pre-flow]s list is parsed as a flow that documents the
|
||||
procedure. In this description, a reference to any identifier in
|
||||
@scheme[datum] is typeset as a sub-form non-terminal.
|
||||
@scheme[datum] is typeset as a sub-form non-terminal. If
|
||||
@scheme[#:literals] clause is provided, however, instances of the
|
||||
@scheme[literal-id]s are typeset normally.
|
||||
|
||||
The typesetting of @scheme[(id . datum)] preserves the source
|
||||
layout, like @scheme[schemeblock], and unlike @scheme[defproc].}
|
||||
|
||||
@defform[(defform* [(id . datum) ..+] pre-flow ...)]{Like @scheme[defform],
|
||||
but for multiple forms using the same @scheme[id].}
|
||||
@defform[(defform* maybe-literals [(id . datum) ..+] pre-flow ...)]{
|
||||
|
||||
@defform[(defform/subs (id . datum)
|
||||
([nonterm-id clause-datum ...+] ...)
|
||||
pre-flow ...)]{
|
||||
Like @scheme[defform], but for multiple forms using the same
|
||||
@scheme[id].}
|
||||
|
||||
@defform/subs[(defform/subs maybe-literals (id . datum)
|
||||
([nonterm-id clause-datum ...+] ...)
|
||||
pre-flow ...)
|
||||
([maybe-literals code:blank
|
||||
(code:line #:literals (literal-id ...))])]{
|
||||
Like @scheme[defform], but including an auxiliary grammar of
|
||||
non-terminals shown with the @scheme[id] form. Each
|
||||
@scheme[nonterm-id] is specified as being any of the corresponding
|
||||
@scheme[clause-datum]s, where the formatting of each
|
||||
@scheme[clause-datum] is preserved.}
|
||||
|
||||
@defform[(specform (id . datum) pre-flow ...)]{Like @scheme[defform],
|
||||
with without registering a definition, and with indenting on the left
|
||||
for both the specification and the @scheme[pre-flow]s.}
|
||||
@defform/subs[(specform maybe-literals (id . datum) pre-flow ...)
|
||||
([maybe-literals code:blank
|
||||
(code:line #:literals (literal-id ...))])]{
|
||||
|
||||
@defform[(specsubform datum pre-flow ...)]{Similar to
|
||||
@scheme[defform], but without any specific identifier being defined,
|
||||
and the table and flow are typeset indented. This form is intended for
|
||||
use when refining the syntax of a non-terminal used in a
|
||||
Like @scheme[defform], with without registering a definition, and with
|
||||
indenting on the left for both the specification and the
|
||||
@scheme[pre-flow]s.}
|
||||
|
||||
@defform[(specsubform maybe-literals datum pre-flow ...)]{
|
||||
|
||||
Similar to @scheme[defform], but without any specific identifier being
|
||||
defined, and the table and flow are typeset indented. This form is
|
||||
intended for use when refining the syntax of a non-terminal used in a
|
||||
@scheme[defform] or other @scheme[specsubform]. For example, it is
|
||||
used in the documentation for @scheme[defproc] in the itemization of
|
||||
possible shapes for @svar[arg-spec].
|
||||
|
@ -254,8 +272,9 @@ The @scheme[pre-flow]s list is parsed as a flow that documents the
|
|||
procedure. In this description, a reference to any identifier in
|
||||
@scheme[datum] is typeset as a sub-form non-terminal.}
|
||||
|
||||
@defform[(defthing id contract-expr-datum pre-flow ...)]{Like
|
||||
@scheme[defproc], but for a non-procedure binding.}
|
||||
@defform[(defthing id contract-expr-datum pre-flow ...)]{
|
||||
|
||||
Like @scheme[defproc], but for a non-procedure binding.}
|
||||
|
||||
@defform/subs[(defstruct struct-name ([field-name contract-expr-datum] ...)
|
||||
pre-flow ...)
|
||||
|
@ -265,13 +284,19 @@ procedure. In this description, a reference to any identifier in
|
|||
Similar to @scheme[defform] or @scheme[defproc], but for a structure
|
||||
definition.}
|
||||
|
||||
@defform/subs[(schemegrammar literals ? id clause-datum ...+)
|
||||
([literals (code:line #:literals (literal-id ...))])]{
|
||||
Creates a table to define the grammar of @scheme[id]. Each identifier mentioned
|
||||
in a @scheme[clause-datum] is typeset as a non-terminal, except for the
|
||||
identifiers listed as @scheme[literal-id]s, which are typeset as with
|
||||
@scheme[scheme].
|
||||
}
|
||||
@defform/subs[(schemegrammar maybe-literals id clause-datum ...+)
|
||||
([maybe-literals code:blank
|
||||
(code:line #:literals (literal-id ...))])]{
|
||||
|
||||
Creates a table to define the grammar of @scheme[id]. Each identifier
|
||||
mentioned in a @scheme[clause-datum] is typeset as a non-terminal,
|
||||
except for the identifiers listed as @scheme[literal-id]s, which are
|
||||
typeset as with @scheme[scheme].}
|
||||
|
||||
@defform[(schemegrammar* maybe-literals [id clause-datum ...+] ...)]{
|
||||
|
||||
Like @scheme[schemegrammar], but for typesetting multiple productions
|
||||
at once, aligned around the @litchar{=} and @litchar{|}.}
|
||||
|
||||
@; ------------------------------------------------------------------------
|
||||
@section{Various String Forms}
|
||||
|
|