merge to trunk a while ago

svn: r14353
This commit is contained in:
Sam Tobin-Hochstadt 2009-03-30 12:52:30 +00:00
commit b1f5b19563
234 changed files with 16415 additions and 7053 deletions

View File

@ -135,7 +135,7 @@
;; Symbol Any String -> Void ;; Symbol Any String -> Void
(define (check-pos t c r) (define (check-pos t c r)
(check-arg (check-arg
t (and (number? c) (> (number->integer c) 0)) "positive integer" r c)) t (and (number? c) (>= (number->integer c) 0)) "positive integer" r c))
;; Symbol Any String String *-> Void ;; Symbol Any String String *-> Void
(define (check-image tag i rank . other-message) (define (check-image tag i rank . other-message)

View File

@ -146,15 +146,18 @@
(syntax-case #'E () (syntax-case #'E ()
[(V) (set! rec? #'V)] [(V) (set! rec? #'V)]
[_ (err 'record? stx)])) [_ (err 'record? stx)]))
(cons (syntax-e #'kw) (syntax E)))] (cons #'kw #;(syntax-e #'kw) (syntax E)))]
[_ (raise-syntax-error [_ (raise-syntax-error
'big-bang "not a legal big-bang clause" stx)])) 'big-bang "not a legal big-bang clause" stx)]))
(syntax->list (syntax (s ...))))] (syntax->list (syntax (s ...))))]
;; assert: all bind = (kw . E) and kw is constrained via Bind ;; assert: all bind = (kw . E) and kw is constrained via Bind
[args (map (lambda (x) [args (map (lambda (x)
(define kw (car x)) (define kw (car x))
(define co (assq kw Spec)) (define co ;; patch from Jay to allow rename on import
(list kw ((cadr co) (cdr x)))) (findf (lambda (n) (free-identifier=? kw (car n)))
(map (lambda (k s) (cons k (cdr s)))
kwds Spec)))
(list (syntax-e (car co)) ((cadr co) (cdr x))))
spec)]) spec)])
#`(send (new (if #,rec? aworld% world%) [world0 w] #,@args) last))])) #`(send (new (if #,rec? aworld% world%) [world0 w] #,@args) last))]))
@ -276,7 +279,7 @@
[(kw . E) [(kw . E)
(and (identifier? #'kw) (and (identifier? #'kw)
(for/or ([n kwds]) (free-identifier=? #'kw n))) (for/or ([n kwds]) (free-identifier=? #'kw n)))
(cons (syntax-e #'kw) (syntax E))] (cons #'kw (syntax E))]
[(kw E) [(kw E)
(and (identifier? #'kw) (and (identifier? #'kw)
(for/or ([n kwds]) (free-identifier=? #'kw n))) (for/or ([n kwds]) (free-identifier=? #'kw n)))
@ -285,6 +288,15 @@
'universe "not a legal universe clause" stx)])) 'universe "not a legal universe clause" stx)]))
(syntax->list (syntax (bind ...))))] (syntax->list (syntax (bind ...))))]
;; assert: all bind = (kw . E) and kw is constrained via Bind ;; assert: all bind = (kw . E) and kw is constrained via Bind
[args (map (lambda (x)
(define kw (car x))
(define co ;; patch from Jay to allow rename on import
(findf (lambda (n) (free-identifier=? kw (car n)))
(map (lambda (k s) (cons k (cdr s)))
kwds Spec)))
(list (syntax-e (car co)) ((cadr co) (cdr x))))
spec)]
#;
[args (map (lambda (x) [args (map (lambda (x)
(define kw (car x)) (define kw (car x))
(define co (assq kw Spec)) (define co (assq kw Spec))

View File

@ -1,6 +1,7 @@
#lang scheme/base #lang scheme/base
(require dynext/compile (require dynext/compile
setup/dirs
(prefix-in xform: "private/xform.ss")) (prefix-in xform: "private/xform.ss"))
(provide xform) (provide xform)
@ -11,7 +12,9 @@
(current-extension-preprocess-flags))] (current-extension-preprocess-flags))]
[headers (apply append [headers (apply append
(map (current-make-compile-include-strings) (map (current-make-compile-include-strings)
header-dirs))]) (append
header-dirs
(list (find-include-dir)))))])
(xform:xform quiet? (xform:xform quiet?
(cons exe (cons exe
(append flags headers)) (append flags headers))

View File

@ -927,7 +927,7 @@
(define rst (read-bytes size* port)) (define rst (read-bytes size* port))
(unless (eof-object? (read port)) (unless (eof-object? (read-byte port))
(error 'not-end)) (error 'not-end))
(unless (= size* (bytes-length rst)) (unless (= size* (bytes-length rst))

View File

@ -177,6 +177,7 @@
(run-in-user-thread (run-in-user-thread
(lambda () (lambda ()
(read-accept-quasiquote (get-accept-quasiquote?)) (read-accept-quasiquote (get-accept-quasiquote?))
(ensure-drscheme-secrets-declared drs-namespace)
(namespace-attach-module drs-namespace ''drscheme-secrets) (namespace-attach-module drs-namespace ''drscheme-secrets)
(namespace-attach-module drs-namespace deinprogramm-struct-module-name) (namespace-attach-module drs-namespace deinprogramm-struct-module-name)
(error-display-handler teaching-languages-error-display-handler) (error-display-handler teaching-languages-error-display-handler)
@ -244,6 +245,27 @@
(super-new))) (super-new)))
;; this inspector should be powerful enough to see
;; any structure defined in the user's namespace
(define drscheme-inspector (current-inspector))
;; FIXME: brittle, mimics drscheme-secrets
;; as declared in lang/htdp-langs.ss.
;; Is it even needed for DeinProgramm langs?
;; Only used by htdp/hangman teachpack.
(define (ensure-drscheme-secrets-declared drs-namespace)
(parameterize ((current-namespace drs-namespace))
(define (declare)
(eval `(,#'module drscheme-secrets mzscheme
(provide drscheme-inspector)
(define drscheme-inspector ,drscheme-inspector)))
(namespace-require ''drscheme-secrets))
(with-handlers ([exn:fail? (lambda (e) (declare))])
;; May have been declared by lang/htdp-langs tool, if loaded
(dynamic-require ''drscheme-secrets 'drscheme-inspector))
(void)))
;; { ;; {
;; all this copied from collects/drscheme/private/language.ss ;; all this copied from collects/drscheme/private/language.ss
@ -1051,24 +1073,31 @@
answer) answer)
(define (stepper-settings-language %) (define (stepper-settings-language %)
(class* % (stepper-language<%>) (if (implementation? % stepper-language<%>)
(init-field stepper:supported) (class* % (stepper-language<%>)
(define/override (stepper:supported?) stepper:supported) (init-field stepper:supported)
(define/override (stepper:render-to-sexp val settings language-level) (define/override (stepper:supported?) stepper:supported)
(parameterize ([pc:current-print-convert-hook (make-print-convert-hook settings)]) (define/override (stepper:render-to-sexp val settings language-level)
(set-print-settings (parameterize ([pc:current-print-convert-hook (make-print-convert-hook settings)])
language-level (set-print-settings
settings language-level
(lambda () settings
(stepper-convert-value val settings))))) (lambda ()
(stepper-convert-value val settings)))))
(super-new))) (super-new))
(class %
(init stepper:supported)
(super-new))))
(define (debugger-settings-language %) (define (debugger-settings-language %)
(class* % (debugger-language<%>) (if (implementation? % debugger-language<%>)
(init-field [debugger:supported #f]) (class* % (debugger-language<%>)
(define/override (debugger:supported?) debugger:supported) (init-field [debugger:supported #f])
(super-new))) (define/override (debugger:supported?) debugger:supported)
(super-new))
(class %
(init [debugger:supported #f])
(super-new))))
;; make-print-convert-hook: ;; make-print-convert-hook:
;; simple-settings -> (TST (TST -> TST) (TST -> TST) -> TST) ;; simple-settings -> (TST (TST -> TST) (TST -> TST) -> TST)

View File

@ -10,7 +10,7 @@
lang/prim)) lang/prim))
@(define DMdA @italic{Die Macht der Abstraktion}) @(define DMdA @italic{Die Macht der Abstraktion})
@(define (DMdA-ref s) @secref[#:doc '(lib "deinprogramm/scribblings/deinprogramm-langs.scrbl") s]) @(define (DMdA-ref s) @secref[#:doc '(lib "deinprogramm/scribblings/deinprogramm.scrbl") s])
Note: This is documentation for the language levels that go with the Note: This is documentation for the language levels that go with the
German textbook @italic{@link["http://www.deinprogramm.de/dmda/"]{Die German textbook @italic{@link["http://www.deinprogramm.de/dmda/"]{Die

View File

@ -1,25 +0,0 @@
#lang scribble/doc
@(require scribblings/htdp-langs/common)
@title{Sprachebenen für @italic{Die Macht der Abstraktion}}
Note: This is documentation for the language levels that go with the
German textbook @italic{@link["http://www.deinprogramm.de/dmda/"]{Die
Macht der Abstraktion}}.
Die Sprachebenen in diesem Handbuch sind für Verwendung mit dem Buch
the @italic{@link["http://www.deinprogramm.de/dmda/"]{Die Macht der
Abstraktion}} gedacht.
@table-of-contents[]
@;------------------------------------------------------------------------
@include-section["DMdA-beginner.scrbl"]
@include-section["DMdA-vanilla.scrbl"]
@include-section["DMdA-assignments.scrbl"]
@include-section["DMdA-advanced.scrbl"]
@;------------------------------------------------------------------------
@index-section[]

View File

@ -0,0 +1,33 @@
#lang scribble/doc
@(require scribble/manual
(for-label scheme))
@title[#:style '(toc) #:tag "deinprogramm"]{Sprachebenen und Material zu @italic{Die Macht der Abstraktion}}
Note: This is documentation for the teachpacks that go with the German
textbook @italic{@link["http://www.deinprogramm.de/dmda/"]{Die Macht
der Abstraktion}}.
Das Material in diesem Handbuch ist für die Verwendung mit dem Buch
the @italic{@link["http://www.deinprogramm.de/dmda/"]{Die Macht der
Abstraktion}} gedacht.
@table-of-contents[]
@include-section["DMdA-beginner.scrbl"]
@include-section["DMdA-vanilla.scrbl"]
@include-section["DMdA-assignments.scrbl"]
@include-section["DMdA-advanced.scrbl"]
@include-section["ka.scrbl"]
@include-section["image.scrbl"]
@include-section["world.scrbl"]
@include-section["turtle.scrbl"]
@include-section["sound.scrbl"]
@include-section["line3d.scrbl"]
@include-section["DMdA-lib.scrbl"]
@index-section[]

View File

@ -1,6 +1,4 @@
#lang setup/infotab #lang setup/infotab
(define scribblings '(("deinprogramm-langs.scrbl" (multi-page) (language -14)) (define scribblings '(("deinprogramm.scrbl" (multi-page) (language -14))))
("ka.scrbl" (multi-page) (other -10))
("DMdA-lib.scrbl")))

View File

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -1,6 +1,6 @@
#lang setup/infotab #lang setup/infotab
(define tools '("syncheck.ss")) (define tools '("syncheck.ss" #;"sprof.ss"))
(define tool-names '("Check Syntax")) (define tool-names '("Check Syntax" #;"Sampling Profiler"))
(define mred-launcher-names '("DrScheme")) (define mred-launcher-names '("DrScheme"))
(define mred-launcher-libraries '("drscheme.ss")) (define mred-launcher-libraries '("drscheme.ss"))

View File

@ -521,9 +521,9 @@
(send language default-settings)))] (send language default-settings)))]
[else (values #f #f)])]) [else (values #f #f)])])
(cond (cond
[(not vis-lang) (void)] [(and vis-lang
[(equal? (send vis-lang get-language-position) (equal? (send vis-lang get-language-position)
(send language get-language-position)) (send language get-language-position)))
(get/set-settings vis-settings) (get/set-settings vis-settings)
(send details-panel active-child language-details-panel)] (send details-panel active-child language-details-panel)]
[else [else
@ -761,8 +761,6 @@
(send revert-to-defaults-outer-panel stretchable-height #f) (send revert-to-defaults-outer-panel stretchable-height #f)
(send outermost-panel set-alignment 'center 'center) (send outermost-panel set-alignment 'center 'center)
(update-show/hide-details)
(for-each add-language-to-dialog languages) (for-each add-language-to-dialog languages)
(send languages-hier-list sort (send languages-hier-list sort
(λ (x y) (λ (x y)
@ -820,6 +818,7 @@
(get/set-selected-language-settings settings-to-show)) (get/set-selected-language-settings settings-to-show))
(when details-shown? (when details-shown?
(do-construct-details)) (do-construct-details))
(update-show/hide-details)
(send languages-hier-list focus) (send languages-hier-list focus)
(values (values
(λ () selected-language) (λ () selected-language)

398
collects/drscheme/sprof.ss Normal file
View File

@ -0,0 +1,398 @@
#lang scheme/base
(require scheme/gui/base
framework
scheme/class)
;; how long between samples
(define pause-time 0.1)
;; gui updates occur every 'update-frequency' samples
(define update-frequency 4)
(define (make-prod-thread get-threads update-gui)
(thread (lambda ()
(define traces-table (make-hash))
(let loop ([i 0])
(sleep pause-time)
(let ([new-traces
(map (λ (t) (continuation-mark-set->context (continuation-marks t)))
(get-threads))])
(for-each
(λ (trace)
(for-each
(λ (line)
(hash-set! traces-table line (cons trace (hash-ref traces-table line '()))))
trace))
new-traces)
(cond
[(zero? i)
(update-gui traces-table)
(loop update-frequency)]
[else
(loop (- i 1))]))))))
(define (format-fn-name i)
(let ([id (car i)]
[src (cdr i)])
(cond
[id (format "~a" id)]
[src
(format "~a:~a~a"
(cond
[(path? (srcloc-source src))
(let-values ([(base name dir?) (split-path (srcloc-source src))])
name)]
[else (srcloc-source src)])
(if (srcloc-line src)
(format "~a:~a"
(srcloc-line src)
(srcloc-column src))
(srcloc-position src))
(if id
(format ": ~a" id)
""))]
[else "???"])))
(define (insert-long-fn-name t i)
(send t begin-edit-sequence)
(send t erase)
(let ([id (car i)]
[src (cdr i)])
(when src
(send t insert
(format "~a:~a"
(srcloc-source src)
(if (srcloc-line src)
(format "~a:~a"
(srcloc-line src)
(srcloc-column src))
(format ":~a" (srcloc-position src))))))
(when (and id src)
(send t insert "\n"))
(when id
(send t insert (format (format "~a" id))))
(unless (or id src)
(send t insert "???")))
(send t end-edit-sequence))
(define (format-percentage n)
(let ([trunc (floor (* n 100))])
(format "~a%" (pad3 trunc))))
(define (pad3 n)
(cond
[(< n 10) (format "00~a" n)]
[(< n 100) (format "0~a" n)]
[else (format "~a" n)]))
(define cumulative-t%
(class text:basic%
(init-field open-button vp ec1 lp info-editor)
(inherit begin-edit-sequence
end-edit-sequence
erase
find-position
get-admin
dc-location-to-editor-location
position-paragraph
insert
last-position
highlight-range
last-paragraph
lock)
(define gui-display-data '())
(define clicked-srcloc-pr #f)
(define line-to-source (make-hasheq))
(define clear-old-pr void)
(define/override (on-event event)
(cond
[(send event button-up? 'left)
(let ([admin (get-admin)])
(when admin
(let ([dc (send admin get-dc)])
(let-values ([(x y) (dc-location-to-editor-location (send event get-x)
(send event get-y))])
(let* ([loc (find-position x y)]
[para (position-paragraph loc)])
(set! clicked-srcloc-pr (and (<= 0 para (last-paragraph))
(car (list-ref gui-display-data para))))
(update-gui-display))))))]
[else (void)]))
(define/public (set-gui-display-data/refresh traces-table)
(set! gui-display-data
(sort (hash-map traces-table (λ (k v) (cons k v)))
>
#:key (λ (x) (length (cdr x)))))
(update-gui-display))
(define/public (clear-clicked)
(set! clicked-srcloc-pr #f)
(update-gui-display))
(define/private (update-gui-display)
(lock #f)
(begin-edit-sequence)
(erase)
(set! line-to-source (make-hasheq))
(clear-old-pr)
(set! clear-old-pr void)
(let* ([denom-ht (make-hasheq)]
[filtered-gui-display-data
(map
(λ (pr)
(let ([id (car pr)]
[stacks (filter-stacks (cdr pr))])
(for-each (λ (stack) (hash-set! denom-ht stack #t)) stacks)
(cons id stacks)))
gui-display-data)]
[denom-count (hash-count denom-ht)])
(let loop ([prs filtered-gui-display-data]
[first? #t]
[i 0])
(cond
[(null? prs) (void)]
[else
(let* ([pr (car prs)]
[fn (car pr)]
[count (length (cdr pr))])
(cond
[(zero? count)
(loop (cdr prs) first? i)]
[else
(unless first? (insert "\n"))
(let ([before (last-position)])
(hash-set! line-to-source i pr)
(insert (format-percentage (/ count denom-count)))
(insert (format " ~a" (format-fn-name fn)))
(let ([after (last-position)])
(when (equal? (car pr) clicked-srcloc-pr)
(set! clear-old-pr (highlight-range before after "NavajoWhite")))))
(loop (cdr prs) #f (+ i 1))]))]))
(lock #t)
(end-edit-sequence)
(update-info-editor clicked-srcloc-pr)
(send open-button enable (and clicked-srcloc-pr (path? (srcloc-source (cdr clicked-srcloc-pr)))))))
(define/private (filter-stacks stacks)
(cond
[(not clicked-srcloc-pr) stacks]
[else
(filter (λ (stack) (ormap (λ (stack-ent) (equal? clicked-srcloc-pr stack-ent))
stack))
stacks)]))
(define/public (open-current-pr)
(when clicked-srcloc-pr
(let ([src (cdr clicked-srcloc-pr)])
(when (path? (srcloc-source src))
(printf "open ~s\n" (srcloc-source src))
(when (number? (srcloc-position src))
(printf "go to ~s\n" (srcloc-position src)))))))
(define/private (update-info-editor pr)
(send vp change-children (λ (l) (if pr (list ec1 lp) (list ec1))))
(when pr
(insert-long-fn-name info-editor pr)))
(super-new)))
(define (construct-gui f)
(define info-editor (new text%))
(define vp (new vertical-panel% [parent f]))
(define ec1 (new editor-canvas% [parent vp]))
(define lp (new vertical-panel% [parent vp] [stretchable-height #f]))
(define ec2 (new editor-canvas%
[parent lp]
[min-height 100]
[stretchable-height #f]
[editor info-editor]))
(define bp (new horizontal-panel% [stretchable-height #f] [parent lp] [alignment '(center center)]))
(define open-button (new button%
[parent bp]
[label "Open"]
[callback
(λ (x y)
(send cumulative-t open-current-pr))]))
(define unlock (new button%
[label "Show All"]
[parent bp]
[callback
(λ (x y)
(send cumulative-t clear-clicked))]))
(define cumulative-t (new cumulative-t%
[open-button open-button]
[vp vp]
[ec1 ec1]
[lp lp]
[info-editor info-editor]))
(send ec1 set-editor cumulative-t)
(send vp change-children (λ (l) (list ec1)))
(send cumulative-t hide-caret #t)
(send cumulative-t lock #t)
(send info-editor auto-wrap #t)
(values vp cumulative-t))
;; running an example outside of drscheme
#;
(begin
(define evt (make-eventspace))
(define f (parameterize ([current-eventspace evt])
(new frame%
[label ""]
[width 400]
[height 800])))
(define-values (panel cumulative-t) (construct-gui f))
(send f show #t)
(void (make-prod-thread (let ([t (current-thread)])
(λ () (list t)))
(λ (traces-table)
(parameterize ([current-eventspace evt])
(queue-callback
(λ ()
(send cumulative-t set-gui-display-data/refresh traces-table)))))))
(time (dynamic-require '(lib "scribblings/reference/reference.scrbl")
#f)))
;; tool code, for integration with drscheme
(begin
(require drscheme/tool
scheme/unit
string-constants/string-constant)
(define sc-show-sprof "Show SProfile")
(define sc-hide-sprof "Hide SProfile")
(provide tool@)
(define tool@
(unit
(import drscheme:tool^)
(export drscheme:tool-exports^)
(define (phase1) (void))
(define (phase2) (void))
(define-local-member-name
show/hide-sprof-panel
update-sprof-panel
toggle-sprof-visiblity
stop-profiling-thread
start-profiling-thread
get-threads-to-profile)
(define unit-frame-mixin
(mixin (drscheme:unit:frame<%>) ()
(inherit get-current-tab)
(define main-panel #f)
(define sprof-main-panel #f)
(define everything-else #f)
(define cumulative-t #f)
(define show/hide-menu-item #f)
(define/public (show/hide-sprof-panel show?)
(let ([main-children (send main-panel get-children)])
(send show/hide-menu-item
set-label
(if show? sc-hide-sprof sc-show-sprof))
(unless (or (and show? (= 2 (length main-children)))
(and (not show?) (= 1 (length main-children))))
(send main-panel change-children
(λ (l)
(if show?
(list everything-else sprof-main-panel)
(list everything-else)))))))
(define/override (make-root-area-container cls parent)
(set! main-panel (super make-root-area-container panel:horizontal-dragable% parent))
(set! everything-else (make-object cls main-panel))
(set!-values (sprof-main-panel cumulative-t) (construct-gui main-panel))
(send main-panel change-children (λ (l) (list everything-else)))
everything-else)
(define/augment (on-tab-change from-tab to-tab)
(inner (void) on-tab-change from-tab to-tab)
(send to-tab update-sprof-panel))
(define/override (add-show-menu-items show-menu)
(super add-show-menu-items show-menu)
(set! show/hide-menu-item
(new menu-item%
[parent show-menu]
[label sc-show-sprof]
[callback
(λ (x y)
(send (get-current-tab) toggle-sprof-visiblity))])))
;; FIX: the cumulative-t text object shouldn't be handed out like this
;; instead its contents need to be tab specific, so switching tabs
;; (ala the update-sprof-panel method) should change the contents of
;; the cumulative-t, presumably via the set-gui-display-data/refresh method.
(define/public (get-cumulative-t) cumulative-t)
(super-new)))
(define tab-mixin
(mixin (drscheme:unit:tab<%>) ()
(inherit get-frame get-ints)
(define prof-visible? #f)
(define/public (toggle-sprof-visiblity)
(set! prof-visible? (not prof-visible?))
(cond
[prof-visible?
(start-profiling-thread)]
[else
(stop-profiling-thread)])
(update-sprof-panel))
(define/public (update-sprof-panel)
(send (get-frame) show/hide-sprof-panel prof-visible?))
(define profiling-thread #f)
(define/public (stop-profiling-thread)
(when profiling-thread
(kill-thread profiling-thread))
(set! profiling-thread #f))
(define current-traces-table #f)
(define/public (start-profiling-thread)
(stop-profiling-thread)
(set! profiling-thread (make-prod-thread
(λ () (send (get-ints) get-threads-to-profile))
(λ (traces-table)
(queue-callback
(λ ()
(send (send (get-frame) get-cumulative-t) set-gui-display-data/refresh traces-table)))))))
(super-new)))
(define system-custodian (current-custodian))
(define repl-mixin
(mixin (drscheme:rep:text<%>) ()
(inherit get-user-custodian)
(define/public (get-threads-to-profile)
(let ([thds '()])
(let loop ([cust (get-user-custodian)])
(for-each
(λ (obj)
(cond
[(custodian? obj) (loop obj)]
[(thread? obj) (set! thds (cons obj thds))]))
(custodian-managed-list cust system-custodian)))
thds))
;; FIX
;; something needs to happen here so that the profiling gets shutdown when the repl dies.
;; the right call back isn't obvious, tho. :(
(super-new)))
(drscheme:get/extend:extend-tab tab-mixin)
(drscheme:get/extend:extend-interactions-text repl-mixin)
(drscheme:get/extend:extend-unit-frame unit-frame-mixin))))

View File

@ -673,8 +673,8 @@ all of the names in the tools library, for use defining keybindings
(proc-doc/names (proc-doc/names
drscheme:get/extend:extend-tab drscheme:get/extend:extend-tab
(case-> (case->
((make-mixin-contract drscheme:unit:tab%) . -> . void?) ((make-mixin-contract drscheme:unit:tab<%>) . -> . void?)
((make-mixin-contract drscheme:unit:tab%) boolean? . -> . void?)) ((make-mixin-contract drscheme:unit:tab<%>) boolean? . -> . void?))
((mixin) (mixin before?)) ((mixin) (mixin before?))
@{This class implements the tabs in drscheme. One is created for each tab @{This class implements the tabs in drscheme. One is created for each tab

View File

@ -14,9 +14,7 @@
@title{@bold{Objective-C} FFI} @title{@bold{Objective-C} FFI}
@declare-exporting[ffi/private/objc-doc-unsafe #:use-sources (ffi/objc)] @defmodule[ffi/objc]{The @schememodname[ffi/objc] library builds on
@defmodule*/no-declare[(ffi/objc)]{The @schememodname[ffi/objc] library builds on
@schememodname[scheme/foreign] to support interaction with @schememodname[scheme/foreign] to support interaction with
@link["http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/"]{Objective-C}.} @link["http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/"]{Objective-C}.}

View File

@ -6,5 +6,11 @@
(objc-unsafe!) (objc-unsafe!)
(provide (protect-out (all-defined-out)) (provide (protect-out objc_msgSend/typed
objc_msgSendSuper/typed
import-class
get-ivar set-ivar!
selector
tell tellv
define-objc-class)
(all-from-out ffi/objc)) (all-from-out ffi/objc))

View File

@ -1,6 +1,6 @@
#lang scribble/doc #lang scribble/doc
@(require "common.ss" @(require "common.ss"
(for-label file/tar)) (for-label file/tar file/gzip))
@title[#:tag "tar"]{@exec{tar} File Creation} @title[#:tag "tar"]{@exec{tar} File Creation}
@ -13,7 +13,7 @@ information is not preserved; the owner that is stored in the archive
is always ``root.''} is always ``root.''}
@defproc[(tar [tar-file path-string?][path path-string?] ...) @defproc[(tar [tar-file path-string?][path path-string?] ...)
void?]{ exact-nonnegative-integer?]{
Creates @scheme[tar-file], which holds the complete content of all Creates @scheme[tar-file], which holds the complete content of all
@scheme[path]s. The given @scheme[path]s are all expected to be @scheme[path]s. The given @scheme[path]s are all expected to be
@ -23,12 +23,18 @@ to the current directory). If a nested path is provided as a
resulting tar file, up to the current directory (using resulting tar file, up to the current directory (using
@scheme[pathlist-closure]).} @scheme[pathlist-closure]).}
@defproc[(tar->output [paths (listof path-string?)] @defproc[(tar->output [paths (listof path?)]
[out output-port? (current-output-port)]) [out output-port? (current-output-port)])
void?]{ exact-nonnegative-integer?]{
Packages each of the given @scheme[paths] in a @exec{tar} format Packages each of the given @scheme[paths] in a @exec{tar} format
archive that is written directly to the @scheme[out]. The specified archive that is written directly to the @scheme[out]. The specified
@scheme[paths] are included as-is; if a directory is specified, its @scheme[paths] are included as-is; if a directory is specified, its
content is not automatically added, and nested directories are added content is not automatically added, and nested directories are added
without parent directories.} without parent directories.}
@defproc[(tar-gzip [tar-file path-string?] [paths path-string?] ...)
void?]{
Like @scheme[tar], but compresses the resulting file with @scheme[gzip].
}

View File

@ -1006,14 +1006,6 @@
(define/public (hide-debug) (define/public (hide-debug)
(send (get-frame) hide-debug)) (send (get-frame) hide-debug))
(define/override (enable-evaluation)
(send (send (get-frame) get-debug-button) enable #t)
(super enable-evaluation))
(define/override (disable-evaluation)
(send (send (get-frame) get-debug-button) enable #f)
(super disable-evaluation))
(super-new))) (super-new)))
(define debug-bitmap (define debug-bitmap
@ -1285,6 +1277,14 @@
(inherit register-toolbar-button) (inherit register-toolbar-button)
(register-toolbar-button debug-button) (register-toolbar-button debug-button)
(define/augment (enable-evaluation)
(send debug-button enable #t)
(inner (void) enable-evaluation))
(define/augment (disable-evaluation)
(send debug-button enable #f)
(inner (void) disable-evaluation))
(define pause-button (define pause-button
(instantiate button% () (instantiate button% ()
[label (make-pause-label this)] [label (make-pause-label this)]

View File

@ -183,8 +183,8 @@ Matthew
; ;
(define (nw:rectangle width height mode color) (define (nw:rectangle width height mode color)
(check-pos 'rectangle width "first") (check-size/0 'nw:rectangle width "first")
(check-pos 'rectangle height "second") (check-size/0 'nw:rectangle height "second")
(check-mode 'rectangle mode "third") (check-mode 'rectangle mode "third")
(check-color 'rectangle color "fourth") (check-color 'rectangle color "fourth")
(put-pinhole (rectangle width height mode color) 0 0)) (put-pinhole (rectangle width height mode color) 0 0))
@ -199,8 +199,8 @@ Matthew
(place-image0 image x y scene))) (place-image0 image x y scene)))
(define (empty-scene width height) (define (empty-scene width height)
(check-pos 'empty-scene width "first") (check-size/0 'empty-scene width "first")
(check-pos 'empty-scene height "second") (check-size/0 'empty-scene height "second")
(put-pinhole (put-pinhole
(overlay (rectangle width height 'solid 'white) (overlay (rectangle width height 'solid 'white)
(rectangle width height 'outline 'black)) (rectangle width height 'outline 'black))
@ -253,8 +253,8 @@ Matthew
(case-lambda (case-lambda
[(w h delta world) (big-bang w h delta world #f)] [(w h delta world) (big-bang w h delta world #f)]
[(w h delta world animated-gif) [(w h delta world animated-gif)
(check-pos 'big-bang w "first") (check-size/0 'big-bang w "first")
(check-pos 'big-bang h "second") (check-size/0 'big-bang h "second")
;; ============================================ ;; ============================================
;; WHAT IF THEY ARE NOT INTs? ;; WHAT IF THEY ARE NOT INTs?
;; ============================================ ;; ============================================
@ -361,8 +361,8 @@ Matthew
(define run-simulation0 (define run-simulation0
(case-lambda (case-lambda
[(width height rate f record?) [(width height rate f record?)
(check-pos 'run-simulation width "first") (check-size/0 'run-simulation width "first")
(check-pos 'run-simulation height "second") (check-size/0 'run-simulation height "second")
(check-arg 'run-simulation (number? rate) 'number "third" rate) (check-arg 'run-simulation (number? rate) 'number "third" rate)
(check-proc 'run-simulation f 1 "fourth" "one argument") (check-proc 'run-simulation f 1 "fourth" "one argument")
(check-arg 'run-simulation (boolean? record?) 'number "fifth [and optional]" record?) (check-arg 'run-simulation (boolean? record?) 'number "fifth [and optional]" record?)
@ -390,9 +390,9 @@ Matthew
; ;
;; Symbol Any String -> Void ;; Symbol Any String -> Void
(define (check-pos tag c rank) (define (check-size/0 tag c rank)
(check-arg tag (and (number? c) (> (coerce c) 0)) (check-arg tag (and (number? c) (>= (coerce c) 0))
"positive integer" rank c)) "natural number" rank c))
;; Symbol Any String String *-> Void ;; Symbol Any String String *-> Void
(define (check-image tag i rank . other-message) (define (check-image tag i rank . other-message)

View File

@ -864,7 +864,9 @@
(init-field [debugger:supported #f]) (init-field [debugger:supported #f])
(define/override (debugger:supported?) debugger:supported) (define/override (debugger:supported?) debugger:supported)
(super-new)) (super-new))
%)) (class %
(init [debugger:supported #f])
(super-new))))
;; filter/hide-ids : syntax[list] -> listof syntax ;; filter/hide-ids : syntax[list] -> listof syntax
(define (filter/hide-ids ids) (define (filter/hide-ids ids)

View File

@ -3,7 +3,6 @@
(require scheme/match (require scheme/match
"stx-util.ss" "stx-util.ss"
"deriv-util.ss" "deriv-util.ss"
"context.ss"
"deriv.ss" "deriv.ss"
"reductions-engine.ss") "reductions-engine.ss")
@ -61,7 +60,7 @@
[#:when (not (bound-identifier=? e1 e2)) [#:when (not (bound-identifier=? e1 e2))
[#:walk e2 'resolve-variable]])] [#:walk e2 'resolve-variable]])]
[(Wrap p:module (e1 e2 rs ?1 ?2 tag rename check tag2 ?3 body shift)) [(Wrap p:module (e1 e2 rs ?1 ?2 tag rename check tag2 ?3 body shift))
(R ;; [#:hide-check rs] ;; FIXME: test and enable!!! (R [#:hide-check rs]
[! ?1] [! ?1]
[#:pattern (?module ?name ?language . ?body-parts)] [#:pattern (?module ?name ?language . ?body-parts)]
[! ?2] [! ?2]

View File

@ -89,6 +89,13 @@
lp-datum)] lp-datum)]
[(pair? obj) [(pair? obj)
(pairloop obj)] (pairloop obj)]
[(struct? obj)
;; Only traverse prefab structs
(let ([pkey (prefab-struct-key obj)])
(if pkey
(let-values ([(refold fields) (unfold-pstruct obj)])
(refold (map loop fields)))
obj))]
[(symbol? obj) [(symbol? obj)
(unintern obj)] (unintern obj)]
[(null? obj) [(null? obj)
@ -117,6 +124,14 @@
flat=>stx flat=>stx
stx=>flat)))) stx=>flat))))
;; unfold-pstruct : prefab-struct -> (values (list -> prefab-struct) list)
(define (unfold-pstruct obj)
(define key (prefab-struct-key obj))
(define fields (cdr (vector->list (struct->vector obj))))
(values (lambda (new-fields)
(apply make-prefab-struct key new-fields))
fields))
;; check+convert-special-expression : syntax -> #f/syntaxish ;; check+convert-special-expression : syntax -> #f/syntaxish
(define (check+convert-special-expression stx) (define (check+convert-special-expression stx)
(define stx-list (stx->list stx)) (define stx-list (stx->list stx))

View File

@ -56,7 +56,7 @@
;; Printing parameters (mzscheme manual 7.9.1.4) ;; Printing parameters (mzscheme manual 7.9.1.4)
[print-unreadable #t] [print-unreadable #t]
[print-graph #f] [print-graph #f]
[print-struct #f] [print-struct #t]
[print-box #t] [print-box #t]
[print-vector-length #t] [print-vector-length #t]
[print-hash-table #f] [print-hash-table #f]

View File

@ -79,7 +79,6 @@
(define drscheme-eventspace (current-eventspace)) (define drscheme-eventspace (current-eventspace))
(define-local-member-name check-language) (define-local-member-name check-language)
(define-local-member-name get-debug-button)
(define macro-debugger-bitmap (define macro-debugger-bitmap
(make-object bitmap% (make-object bitmap%
@ -113,6 +112,13 @@
(inherit register-toolbar-button) (inherit register-toolbar-button)
(register-toolbar-button macro-debug-button) (register-toolbar-button macro-debug-button)
(define/augment (enable-evaluation)
(send macro-debug-button enable #t)
(inner (void) enable-evaluation))
(define/augment (disable-evaluation)
(send macro-debug-button enable #f)
(inner (void) disable-evaluation))
(define/override (execute-callback) (define/override (execute-callback)
(execute #f)) (execute #f))
@ -120,8 +126,6 @@
(send (get-interactions-text) enable-macro-debugging debugging?) (send (get-interactions-text) enable-macro-debugging debugging?)
(super execute-callback)) (super execute-callback))
(define/public (get-debug-button) macro-debug-button)
;; Hide button for inappropriate languages ;; Hide button for inappropriate languages
(define/augment (on-tab-change old new) (define/augment (on-tab-change old new)
@ -157,17 +161,6 @@
(inner (void) after-set-next-settings s)) (inner (void) after-set-next-settings s))
(super-new))) (super-new)))
(define (macro-debugger-tab-mixin %)
(class %
(inherit get-frame)
(define/override (enable-evaluation)
(super enable-evaluation)
(send (send (get-frame) get-debug-button) enable #t))
(define/override (disable-evaluation)
(super disable-evaluation)
(send (send (get-frame) get-debug-button) enable #f))
(super-new)))
(define (macro-debugger-interactions-text-mixin %) (define (macro-debugger-interactions-text-mixin %)
(class % (class %
(super-new) (super-new)
@ -268,7 +261,5 @@
macro-debugger-interactions-text-mixin) macro-debugger-interactions-text-mixin)
(drscheme:get/extend:extend-definitions-text (drscheme:get/extend:extend-definitions-text
macro-debugger-definitions-text-mixin) macro-debugger-definitions-text-mixin)
(drscheme:get/extend:extend-tab
macro-debugger-tab-mixin)
)) ))

View File

@ -2062,7 +2062,7 @@
(when header (when header
(put_short len) (put_short len)
(put_short (bitwise-not len)) (put_short (bitwise-and (bitwise-not len) #xFFFF))
(set! bits_sent (+ bits_sent (* 2 16)))) (set! bits_sent (+ bits_sent (* 2 16))))
(set! bits_sent (+ bits_sent (<< len 3))) (set! bits_sent (+ bits_sent (<< len 3)))
@ -2112,7 +2112,7 @@
;; /* Output a 32 bit value to the bit stream, lsb first */ ;; /* Output a 32 bit value to the bit stream, lsb first */
(define (put_long n) (define (put_long n)
(put_short (bitwise-and #xFFFF n)) (put_short (bitwise-and #xFFFF n))
(put_short (>> n 16))) (put_short (bitwise-and #xFFFF (>> n 16))))
(define outcnt 0) (define outcnt 0)
(define bytes_out 0) (define bytes_out 0)

File diff suppressed because it is too large Load Diff

View File

@ -1050,6 +1050,11 @@
(pp-two-up expr extra pp-expr-list depth (pp-two-up expr extra pp-expr-list depth
apair? acar acdr open close)) apair? acar acdr open close))
(define (pp-module expr extra depth
apair? acar acdr open close)
(pp-two-up expr extra pp-expr depth
apair? acar acdr open close))
(define (pp-make-object expr extra depth (define (pp-make-object expr extra depth
apair? acar acdr open close) apair? acar acdr open close)
(pp-one-up expr extra pp-expr-list depth (pp-one-up expr extra pp-expr-list depth
@ -1138,8 +1143,10 @@
((do letrec-syntaxes+values) ((do letrec-syntaxes+values)
(and (no-sharing? expr 2 apair? acdr) (and (no-sharing? expr 2 apair? acdr)
pp-do)) pp-do))
((module)
((send syntax-case instantiate module) (and (no-sharing? expr 2 apair? acdr)
pp-module))
((send syntax-case instantiate)
(and (no-sharing? expr 2 apair? acdr) (and (no-sharing? expr 2 apair? acdr)
pp-syntax-case)) pp-syntax-case))
((make-object) ((make-object)

View File

@ -96,32 +96,47 @@
;; -- operates on the default input port; the second value indicates whether ;; -- operates on the default input port; the second value indicates whether
;; reading stopped because an EOF was hit (as opposed to the delimiter being ;; reading stopped because an EOF was hit (as opposed to the delimiter being
;; seen); the delimiter is not part of the result ;; seen); the delimiter is not part of the result
(define (read-until-char ip delimiter) (define (read-until-char ip delimiter?)
(let loop ([chars '()]) (let loop ([chars '()])
(let ([c (read-char ip)]) (let ([c (read-char ip)])
(cond [(eof-object? c) (values (reverse chars) #t)] (cond [(eof-object? c) (values (reverse chars) #t)]
[(char=? c delimiter) (values (reverse chars) #f)] [(delimiter? c) (values (reverse chars) #f)]
[else (loop (cons c chars))])))) [else (loop (cons c chars))]))))
;; delimiter->predicate :
;; symbol -> (char -> bool)
;; returns a predicates to pass to read-until-char
(define (delimiter->predicate delimiter)
(case delimiter
[(eq) (lambda (c) (char=? c #\=))]
[(amp) (lambda (c) (char=? c #\&))]
[(semi) (lambda (c) (char=? c #\;))]
[(amp-or-semi) (lambda (c) (or (char=? c #\&) (char=? c #\;)))]))
;; read-name+value : iport -> (symbol + bool) x (string + bool) x bool ;; read-name+value : iport -> (symbol + bool) x (string + bool) x bool
;; -- If the first value is false, so is the second, and the third is true, ;; -- If the first value is false, so is the second, and the third is true,
;; indicating EOF was reached without any input seen. Otherwise, the first ;; indicating EOF was reached without any input seen. Otherwise, the first
;; and second values contain strings and the third is either true or false ;; and second values contain strings and the third is either true or false
;; depending on whether the EOF has been reached. The strings are processed ;; depending on whether the EOF has been reached. The strings are processed
;; to remove the CGI spec "escape"s. This code is _slightly_ lax: it allows ;; to remove the CGI spec "escape"s. This code is _slightly_ lax: it allows
;; an input to end in `&'. It's not clear this is legal by the CGI spec, ;; an input to end in (current-alist-separator-mode).
;; It's not clear this is legal by the CGI spec,
;; which suggests that the last value binding must end in an EOF. It doesn't ;; which suggests that the last value binding must end in an EOF. It doesn't
;; look like this matters. It would also introduce needless modality and ;; look like this matters. It would also introduce needless modality and
;; reduce flexibility. ;; reduce flexibility.
(define (read-name+value ip) (define (read-name+value ip)
(let-values ([(name eof?) (read-until-char ip #\=)]) (let-values ([(name eof?) (read-until-char ip (delimiter->predicate 'eq))])
(cond [(and eof? (null? name)) (values #f #f #t)] (cond [(and eof? (null? name)) (values #f #f #t)]
[eof? [eof?
(generate-error-output (generate-error-output
(list "Server generated malformed input for POST method:" (list "Server generated malformed input for POST method:"
(string-append (string-append
"No binding for `" (list->string name) "' field.")))] "No binding for `" (list->string name) "' field.")))]
[else (let-values ([(value eof?) (read-until-char ip #\&)]) [else (let-values ([(value eof?)
(read-until-char
ip
(delimiter->predicate
(current-alist-separator-mode)))])
(values (string->symbol (query-chars->string name)) (values (string->symbol (query-chars->string name))
(query-chars->string value) (query-chars->string value)
eof?))]))) eof?))])))

View File

@ -33,15 +33,15 @@
[(and (= (+ offset 2) len) [(and (= (+ offset 2) len)
(bytes=? CRLF/bytes (subbytes s offset len))) (bytes=? CRLF/bytes (subbytes s offset len)))
(void)] ; validated (void)] ; validated
[(= offset len) (error 'validate-header/bytes "missing ending CRLF")] [(= offset len) (error 'validate-header "missing ending CRLF")]
[(or (regexp-match re:field-start/bytes s offset) [(or (regexp-match re:field-start/bytes s offset)
(regexp-match re:continue/bytes s offset)) (regexp-match re:continue/bytes s offset))
(let ([m (regexp-match-positions #rx#"\r\n" s offset)]) (let ([m (regexp-match-positions #rx#"\r\n" s offset)])
(if m (if m
(loop (cdar m)) (loop (cdar m))
(error 'validate-header/bytes "missing ending CRLF")))] (error 'validate-header "missing ending CRLF")))]
[else (error 'validate-header/bytes "ill-formed header at ~s" [else (error 'validate-header "ill-formed header at ~s"
(subbytes s offset (string-length s)))]))) (subbytes s offset (bytes-length s)))])))
;; otherwise it should be a string: ;; otherwise it should be a string:
(begin (begin
(let ([m (regexp-match #rx"[^\000-\377]" s)]) (let ([m (regexp-match #rx"[^\000-\377]" s)])

View File

@ -1,6 +1,7 @@
#lang scribble/doc #lang scribble/doc
@(require "common.ss" @(require "common.ss"
(for-label net/cgi (for-label net/cgi
net/uri-codec
net/cgi-unit net/cgi-unit
net/cgi-sig)) net/cgi-sig))
@ -41,7 +42,10 @@ Returns the bindings that corresponding to the options specified by
the user. The @scheme[get-bindings/post] and the user. The @scheme[get-bindings/post] and
@scheme[get-bindings/get] variants work only when POST and GET forms @scheme[get-bindings/get] variants work only when POST and GET forms
are used, respectively, while @scheme[get-bindings] determines the are used, respectively, while @scheme[get-bindings] determines the
kind of form that was used and invokes the appropriate function.} kind of form that was used and invokes the appropriate function.
These functions respect @scheme[current-alist-separator-mode].
}
@defproc[(extract-bindings [key? (or/c symbol? string?)] @defproc[(extract-bindings [key? (or/c symbol? string?)]

View File

@ -81,7 +81,8 @@
(((special) act) (((special) act)
(not (ormap (not (ormap
(lambda (x) (lambda (x)
(module-or-top-identifier=? (syntax special) x)) (and (identifier? #'special)
(module-or-top-identifier=? (syntax special) x)))
ids))) ids)))
(_ #t))) (_ #t)))
spec/re-act-lst)) spec/re-act-lst))

View File

@ -157,8 +157,8 @@ are a few examples, using @scheme[:] prefixed SRE syntax:
action: action:
@itemize{ @itemize{
@item{@scheme[start-pos] --- a position struct for the first character matched.} @item{@scheme[start-pos] --- a @scheme[position] struct for the first character matched.}
@item{@scheme[end-pos] --- a position struct for the character after the last character in the match.} @item{@scheme[end-pos] --- a @scheme[position] struct for the character after the last character in the match.}
@item{@scheme[lexeme] --- the matched string.} @item{@scheme[lexeme] --- the matched string.}
@item{@scheme[input-port] --- the input-port being @item{@scheme[input-port] --- the input-port being
processed (this is useful for matching input with multiple processed (this is useful for matching input with multiple
@ -526,23 +526,27 @@ the right choice when using @scheme[lexer] in other situations.
Each action is scheme code that has the same scope as its Each action is scheme code that has the same scope as its
parser's definition, except that the variables @scheme[$1], ..., parser's definition, except that the variables @scheme[$1], ...,
@schemeidfont{$}@math{n} are bound, where @math{n} is the number @schemeidfont{$}@math{i} are bound, where @math{i} is the number
of @scheme[grammar-id]s in the corresponding production. Each of @scheme[grammar-id]s in the corresponding production. Each
@schemeidfont{$}@math{i} is bound to the result of the action @schemeidfont{$}@math{k} is bound to the result of the action
for the @math{i}@superscript{th} grammar symbol on the right of for the @math{k}@superscript{th} grammar symbol on the right of
the production, if that grammar symbol is a non-terminal, or the the production, if that grammar symbol is a non-terminal, or the
value stored in the token if the grammar symbol is a terminal. value stored in the token if the grammar symbol is a terminal.
If the @scheme[src-pos] option is present in the parser, then If the @scheme[src-pos] option is present in the parser, then
variables @scheme[$1-start-pos], ..., variables @scheme[$1-start-pos], ...,
@schemeidfont{$}@math{n}@schemeidfont{-start-pos} and @schemeidfont{$}@math{i}@schemeidfont{-start-pos} and
@scheme[$1-end-pos], ..., @scheme[$1-end-pos], ...,
@schemeidfont{$}@math{n}@schemeidfont{-end-pos} and are also @schemeidfont{$}@math{i}@schemeidfont{-end-pos} and are also
available, and they refer to the position structures available, and they refer to the position structures
corresponding to the start and end of the corresponding corresponding to the start and end of the corresponding
@scheme[grammar-symbol]. Grammar symbols defined as empty-tokens @scheme[grammar-symbol]. Grammar symbols defined as empty-tokens
have no @schemeidfont{$}@math{i} associated, but do have have no @schemeidfont{$}@math{k} associated, but do have
@schemeidfont{$}@math{k}@schemeidfont{-start-pos} and
@schemeidfont{$}@math{k}@schemeidfont{-end-pos}.
Also @schemeidfont{$n-start-pos} and @schemeidfont{$n-end-pos}
are bound to the largest start and end positions, (i.e.,
@schemeidfont{$}@math{i}@schemeidfont{-start-pos} and @schemeidfont{$}@math{i}@schemeidfont{-start-pos} and
@schemeidfont{$}@math{i}@schemeidfont{-end-pos}. @schemeidfont{$}@math{i}@schemeidfont{-end-pos}).
All of the productions for a given non-terminal must be grouped All of the productions for a given non-terminal must be grouped
with it. That is, no @scheme[non-terminal-id] may appear twice with it. That is, no @scheme[non-terminal-id] may appear twice

View File

@ -1,19 +1,16 @@
(module actions mzscheme #lang scheme/base
(provide (all-defined))
(require syntax/stx)
;; get-special-action: (syntax-object list) syntax-object syntax-object -> syntax-object (provide (all-defined-out))
;; Returns the first action from a rule of the form ((which-special) action) (require syntax/stx)
(define (get-special-action rules which-special none)
(cond
((null? rules) none)
(else
(syntax-case (car rules) ()
(((special) act)
(module-or-top-identifier=? (syntax special) which-special)
(syntax act))
(_ (get-special-action (cdr rules) which-special none))))))
;; get-special-action: (syntax-object list) syntax-object syntax-object -> syntax-object
;; Returns the first action from a rule of the form ((which-special) action)
) (define (get-special-action rules which-special none)
(cond
((null? rules) none)
(else
(syntax-case (car rules) ()
(((special) act)
(and (identifier? #'special) (module-or-top-identifier=? (syntax special) which-special))
(syntax act))
(_ (get-special-action (cdr rules) which-special none))))))

View File

@ -18,9 +18,10 @@
(define stx-for-original-property (read-syntax #f (open-input-string "original"))) (define stx-for-original-property (read-syntax #f (open-input-string "original")))
;; get-args: ??? ;; get-args: ??? -> (values (listof syntax) (or/c #f (cons integer? stx)))
(define (get-args i rhs src-pos term-defs) (define (get-args i rhs src-pos term-defs)
(let ((empty-table (make-hash-table))) (let ((empty-table (make-hash-table))
(biggest-pos #f))
(hash-table-put! empty-table 'error #t) (hash-table-put! empty-table 'error #t)
(for-each (lambda (td) (for-each (lambda (td)
(let ((v (syntax-local-value td))) (let ((v (syntax-local-value td)))
@ -29,24 +30,31 @@
(hash-table-put! empty-table (syntax-object->datum s) #t)) (hash-table-put! empty-table (syntax-object->datum s) #t))
(syntax->list (e-terminals-def-t v)))))) (syntax->list (e-terminals-def-t v))))))
term-defs) term-defs)
(let get-args ((i i) (let ([args
(rhs rhs)) (let get-args ((i i)
(cond (rhs rhs))
((null? rhs) null) (cond
(else ((null? rhs) null)
(let ((b (car rhs)) (else
(name (if (hash-table-get empty-table (syntax-object->datum (car rhs)) (lambda () #f)) (let ((b (car rhs))
(gensym) (name (if (hash-table-get empty-table (syntax-object->datum (car rhs)) (lambda () #f))
(string->symbol (format "$~a" i))))) (gensym)
(cond (string->symbol (format "$~a" i)))))
(src-pos (cond
`(,(datum->syntax-object b name b stx-for-original-property) (src-pos
,(datum->syntax-object b (string->symbol (format "$~a-start-pos" i)) b stx-for-original-property) (let ([start-pos-id
,(datum->syntax-object b (string->symbol (format "$~a-end-pos" i)) b stx-for-original-property) (datum->syntax-object b (string->symbol (format "$~a-start-pos" i)) b stx-for-original-property)]
,@(get-args (add1 i) (cdr rhs)))) [end-pos-id
(else (datum->syntax-object b (string->symbol (format "$~a-end-pos" i)) b stx-for-original-property)])
`(,(datum->syntax-object b name b stx-for-original-property) (set! biggest-pos (cons start-pos-id end-pos-id))
,@(get-args (add1 i) (cdr rhs))))))))))) `(,(datum->syntax-object b name b stx-for-original-property)
,start-pos-id
,end-pos-id
,@(get-args (add1 i) (cdr rhs)))))
(else
`(,(datum->syntax-object b name b stx-for-original-property)
,@(get-args (add1 i) (cdr rhs)))))))))])
(values args biggest-pos))))
;; Given the list of terminal symbols and the precedence/associativity definitions, ;; Given the list of terminal symbols and the precedence/associativity definitions,
;; builds terminal structures (See grammar.ss) ;; builds terminal structures (See grammar.ss)
@ -250,9 +258,18 @@
;; parse-action: syntax-object * syntax-object -> syntax-object ;; parse-action: syntax-object * syntax-object -> syntax-object
(parse-action (parse-action
(lambda (rhs act) (lambda (rhs act)
(quasisyntax/loc act (let-values ([(args biggest) (get-args 1 (syntax->list rhs) src-pos term-defs)])
(lambda #,(get-args 1 (syntax->list rhs) src-pos term-defs) (let ([act
#,act)))) (if biggest
(with-syntax ([$n-start-pos (datum->syntax-object (car biggest) '$n-start-pos)]
[$n-end-pos (datum->syntax-object (cdr biggest) '$n-end-pos)])
#`(let ([$n-start-pos #,(car biggest)]
[$n-end-pos #,(cdr biggest)])
#,act))
act)])
(quasisyntax/loc act
(lambda #,args
#,act))))))
;; parse-prod+action: non-term * syntax-object -> production ;; parse-prod+action: non-term * syntax-object -> production
(parse-prod+action (parse-prod+action

View File

@ -1,4 +1,4 @@
(module table mzscheme #lang scheme/base
;; Routine to build the LALR table ;; Routine to build the LALR table
@ -31,14 +31,14 @@
(list->vector (list->vector
(map (map
(lambda (state-entry) (lambda (state-entry)
(let ((ht (make-hash-table 'equal))) (let ((ht (make-hash)))
(for-each (for-each
(lambda (gs/actions) (lambda (gs/actions)
(let ((group (hash-table-get ht (car gs/actions) (lambda () null)))) (let ((group (hash-ref ht (car gs/actions) (lambda () null))))
(unless (member (cdr gs/actions) group) (unless (member (cdr gs/actions) group)
(hash-table-put! ht (car gs/actions) (cons (cdr gs/actions) group))))) (hash-set! ht (car gs/actions) (cons (cdr gs/actions) group)))))
state-entry) state-entry)
(hash-table-map ht cons))) (hash-map ht cons)))
(vector->list table)))) (vector->list table))))
;; table-map : (vectorof (listof (cons/c gram-sym? X))) (gram-sym? X -> Y) -> ;; table-map : (vectorof (listof (cons/c gram-sym? X))) (gram-sym? X -> Y) ->
@ -119,19 +119,23 @@
(print-entry sym (car act) port)) (print-entry sym (car act) port))
(else (else
(fprintf port "begin conflict:~n") (fprintf port "begin conflict:~n")
(if (> (count reduce? act) 1) (when (> (count reduce? act) 1)
(set! RR-conflicts (add1 RR-conflicts))) (set! RR-conflicts (add1 RR-conflicts)))
(if (> (count shift? act) 0) (when (> (count shift? act) 0)
(set! SR-conflicts (add1 SR-conflicts))) (set! SR-conflicts (add1 SR-conflicts)))
(map (lambda (x) (print-entry sym x port)) act) (map (lambda (x) (print-entry sym x port)) act)
(fprintf port "end conflict~n"))))) (fprintf port "end conflict~n")))))
(vector-ref grouped-table (kernel-index state))) (vector-ref grouped-table (kernel-index state)))
(newline port))) (newline port)))
(when (> SR-conflicts 0) (when (> SR-conflicts 0)
(fprintf port "~a shift/reduce conflicts~n" SR-conflicts)) (fprintf port "~a shift/reduce conflict~a~n"
SR-conflicts
(if (= SR-conflicts 1) "" "s")))
(when (> RR-conflicts 0) (when (> RR-conflicts 0)
(fprintf port "~a reduce/reduce conflicts~n" RR-conflicts)))) (fprintf port "~a reduce/reduce conflict~a~n"
RR-conflicts
(if (= RR-conflicts 1) "" "s")))))
;; resolve-conflict : (listof action?) -> action? bool bool ;; resolve-conflict : (listof action?) -> action? bool bool
(define (resolve-conflict actions) (define (resolve-conflict actions)
@ -176,12 +180,14 @@
(unless suppress (unless suppress
(when (> SR-conflicts 0) (when (> SR-conflicts 0)
(fprintf (current-error-port) (fprintf (current-error-port)
"~a shift/reduce conflicts~n" "~a shift/reduce conflict~a~n"
SR-conflicts)) SR-conflicts
(if (= SR-conflicts 1) "" "s")))
(when (> RR-conflicts 0) (when (> RR-conflicts 0)
(fprintf (current-error-port) (fprintf (current-error-port)
"~a reduce/reduce conflicts~n" "~a reduce/reduce conflict~a~n"
RR-conflicts))) RR-conflicts
(if (= RR-conflicts 1) "" "s"))))
table)) table))
@ -230,7 +236,7 @@
(end-terms (send g get-end-terms)) (end-terms (send g get-end-terms))
(table (make-parse-table (send a get-num-states))) (table (make-parse-table (send a get-num-states)))
(get-lookahead (compute-LA a g)) (get-lookahead (compute-LA a g))
(reduce-cache (make-hash-table 'equal))) (reduce-cache (make-hash)))
(for-each (for-each
(lambda (trans-key/state) (lambda (trans-key/state)
@ -256,17 +262,17 @@
(bit-vector-for-each (bit-vector-for-each
(lambda (term-index) (lambda (term-index)
(unless (start-item? item) (unless (start-item? item)
(let ((r (hash-table-get reduce-cache item-prod (let ((r (hash-ref reduce-cache item-prod
(lambda () (lambda ()
(let ((r (make-reduce item-prod))) (let ((r (make-reduce item-prod)))
(hash-table-put! reduce-cache item-prod r) (hash-set! reduce-cache item-prod r)
r))))) r)))))
(table-add! table (table-add! table
(kernel-index state) (kernel-index state)
(vector-ref term-vector term-index) (vector-ref term-vector term-index)
r)))) r))))
(get-lookahead state item-prod)))) (get-lookahead state item-prod))))
(append (hash-table-get (send a get-epsilon-trans) state (lambda () null)) (append (hash-ref (send a get-epsilon-trans) state (lambda () null))
(filter (lambda (item) (filter (lambda (item)
(not (move-dot-right item))) (not (move-dot-right item)))
(kernel-items state)))))) (kernel-items state))))))
@ -277,13 +283,12 @@
(lambda (e) (lambda (e)
(fprintf (fprintf
(current-error-port) (current-error-port)
"Cannot write debug output to file \"~a\".~n" "Cannot write debug output to file \"~a\": ~a\n"
file)))] file
(exn-message e))))]
(call-with-output-file file (call-with-output-file file
(lambda (port) (lambda (port)
(display-parser a grouped-table (send g get-prods) port))))) (display-parser a grouped-table (send g get-prods) port))
#:exists 'truncate)))
(resolve-conflicts grouped-table suppress)))) (resolve-conflicts grouped-table suppress))))
)

View File

@ -1,9 +1,10 @@
(module yacc mzscheme #lang scheme/base
(require-for-syntax "private-yacc/parser-builder.ss" (require (for-syntax scheme/base
"private-yacc/grammar.ss" "private-yacc/parser-builder.ss"
"private-yacc/yacc-helper.ss" "private-yacc/grammar.ss"
"private-yacc/parser-actions.ss") "private-yacc/yacc-helper.ss"
"private-yacc/parser-actions.ss"))
(require "private-lex/token.ss" (require "private-lex/token.ss"
"private-yacc/parser-actions.ss" "private-yacc/parser-actions.ss"
mzlib/etc mzlib/etc
@ -19,12 +20,12 @@
(list->vector (list->vector
(map (map
(lambda (state-entry) (lambda (state-entry)
(let ((ht (make-hash-table))) (let ((ht (make-hasheq)))
(for-each (for-each
(lambda (gs/action) (lambda (gs/action)
(hash-table-put! ht (hash-set! ht
(gram-sym-symbol (car gs/action)) (gram-sym-symbol (car gs/action))
(action->runtime-action (cdr gs/action)))) (action->runtime-action (cdr gs/action))))
state-entry) state-entry)
ht)) ht))
(vector->list table)))) (vector->list table))))
@ -177,13 +178,14 @@
yacc-output)))] yacc-output)))]
(call-with-output-file yacc-output (call-with-output-file yacc-output
(lambda (port) (lambda (port)
(display-yacc (syntax-object->datum grammar) (display-yacc (syntax->datum grammar)
tokens tokens
(map syntax-object->datum start) (map syntax->datum start)
(if precs (if precs
(syntax-object->datum precs) (syntax->datum precs)
#f) #f)
port))))) port))
#:exists 'truncate)))
(with-syntax ((check-syntax-fix check-syntax-fix) (with-syntax ((check-syntax-fix check-syntax-fix)
(err error) (err error)
(ends end) (ends end)
@ -245,7 +247,7 @@
(define (extract-no-src-pos ip) (define (extract-no-src-pos ip)
(extract-helper ip #f #f)) (extract-helper ip #f #f))
(define-struct stack-frame (state value start-pos end-pos) (make-inspector)) (define-struct stack-frame (state value start-pos end-pos) #:inspector (make-inspector))
(define (make-empty-stack i) (list (make-stack-frame i #f #f #f))) (define (make-empty-stack i) (list (make-stack-frame i #f #f #f)))
@ -304,17 +306,17 @@
(remove-states))))))))) (remove-states)))))))))
(define (find-action stack tok val start-pos end-pos) (define (find-action stack tok val start-pos end-pos)
(unless (hash-table-get all-term-syms (unless (hash-ref all-term-syms
tok tok
(lambda () #f)) #f)
(if src-pos (if src-pos
(err #f tok val start-pos end-pos) (err #f tok val start-pos end-pos)
(err #f tok val)) (err #f tok val))
(raise-read-error (format "parser: got token of unknown type ~a" tok) (raise-read-error (format "parser: got token of unknown type ~a" tok)
#f #f #f #f #f)) #f #f #f #f #f))
(hash-table-get (vector-ref table (stack-frame-state (car stack))) (hash-ref (vector-ref table (stack-frame-state (car stack)))
tok tok
(lambda () #f))) #f))
(define (make-parser start-number) (define (make-parser start-number)
(lambda (get-token) (lambda (get-token)
@ -341,7 +343,7 @@
src-pos))) src-pos)))
(let ((goto (let ((goto
(runtime-goto-state (runtime-goto-state
(hash-table-get (hash-ref
(vector-ref table (stack-frame-state (car new-stack))) (vector-ref table (stack-frame-state (car new-stack)))
(runtime-reduce-lhs action))))) (runtime-reduce-lhs action)))))
(parsing-loop (parsing-loop
@ -378,4 +380,3 @@
(cond (cond
((null? l) null) ((null? l) null)
(else (cons (make-parser i) (loop (cdr l) (add1 i)))))))))) (else (cons (make-parser i) (loop (cdr l) (add1 i))))))))))
)

View File

@ -1,10 +1,14 @@
(module main scheme/base (module main scheme/base
(require scheme/mpair (require scheme/mpair
(for-syntax scheme/base syntax/kerncase) (for-syntax scheme/base syntax/kerncase
"private/r5rs-trans.ss")
(only-in mzscheme transcript-on transcript-off)) (only-in mzscheme transcript-on transcript-off))
(provide (for-syntax syntax-rules ...) (provide (for-syntax syntax-rules ...
(rename-out [syntax-rules-only #%top]
[syntax-rules-only #%app]
[syntax-rules-only #%datum]))
(rename-out (rename-out
[mcons cons] [mcons cons]
[mcar car] [mcar car]

View File

@ -0,0 +1,11 @@
#lang scheme/base
(require (for-syntax scheme/base))
(provide syntax-rules-only)
(define-syntax (syntax-rules-only stx)
(syntax-case stx ()
[(_ . form)
(raise-syntax-error
'macro-transformer
"only a `syntax-rules' form is allowed"
#'form)]))

View File

@ -1,6 +1,7 @@
#lang scribble/doc #lang scribble/doc
@(require scribble/manual @(require scribble/manual
(for-label r5rs (for-label (only-meta-in 0 r5rs)
(only-in r5rs syntax-rules ...)
(only-in mzscheme #%plain-module-begin) (only-in mzscheme #%plain-module-begin)
(only-in scheme/mpair mmap) (only-in scheme/mpair mmap)
(only-in scheme/contract one-of/c) (only-in scheme/contract one-of/c)

View File

@ -18,8 +18,6 @@ before the pattern compiler is invoked.
(define-struct compiled-pattern (cp)) (define-struct compiled-pattern (cp))
(define count 0)
(define caching-enabled? (make-parameter #t)) (define caching-enabled? (make-parameter #t))
;; lang = (listof nt) ;; lang = (listof nt)

View File

@ -530,6 +530,14 @@
(decisions #:nt (patterns fourth first first second first first first) (decisions #:nt (patterns fourth first first second first first first)
#:var (list (λ _ 'x) (λ _ 'y)))) #:var (list (λ _ 'x) (λ _ 'y))))
(term (λ (x) (hole y))))) (term (λ (x) (hole y)))))
(let ()
(define-language L
(a ((a ...) ...)))
(test (generate-term/decisions
L (cross a) 3 0
(decisions #:nt (patterns second first)
#:seq (list (λ _ 0) (λ _ 0) (λ _ 0) (λ _ 0))))
(term ((hole)))))
;; generation failures increase size and attempt ;; generation failures increase size and attempt
(let () (let ()

View File

@ -620,7 +620,7 @@ To do a better job of not generating programs with free variables,
(struct-copy (struct-copy
compiled-lang lang compiled-lang lang
[lang (map (parse-nt 'grammar) (compiled-lang-lang lang))] [lang (map (parse-nt 'grammar) (compiled-lang-lang lang))]
[cclang (map (parse-nt 'top-level) (compiled-lang-cclang lang))])) [cclang (map (parse-nt 'cross) (compiled-lang-cclang lang))]))
;; unparse-pattern: parsed-pattern -> pattern ;; unparse-pattern: parsed-pattern -> pattern
(define unparse-pattern (define unparse-pattern

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,7 @@
add-between add-between
remove-duplicates remove-duplicates
filter-map filter-map
count
partition partition
argmin argmin
@ -237,6 +238,27 @@
(let ([x (f (car l))]) (let ([x (f (car l))])
(if x (cons x (loop (cdr l))) (loop (cdr l)))))))) (if x (cons x (loop (cdr l))) (loop (cdr l))))))))
;; very similar to `filter-map', one more such function will justify some macro
(define (count f l . ls)
(unless (and (procedure? f) (procedure-arity-includes? f (add1 (length ls))))
(raise-type-error
'count (format "procedure (arity ~a)" (add1 (length ls))) f))
(unless (and (list? l) (andmap list? ls))
(raise-type-error
'count "proper list"
(ormap (lambda (x) (and (not (list? x)) x)) (cons l ls))))
(if (pair? ls)
(let ([len (length l)])
(if (andmap (lambda (l) (= len (length l))) ls)
(let loop ([l l] [ls ls] [c 0])
(if (null? l)
c
(loop (cdr l) (map cdr ls)
(if (apply f (car l) (map car ls)) (add1 c) c))))
(error 'count "all lists must have same size")))
(let loop ([l l] [c 0])
(if (null? l) c (loop (cdr l) (if (f (car l)) (add1 c) c))))))
;; Originally from srfi-1 -- shares common tail with the input when possible ;; Originally from srfi-1 -- shares common tail with the input when possible
;; (define (partition f l) ;; (define (partition f l)
;; (unless (and (procedure? f) (procedure-arity-includes? f 1)) ;; (unless (and (procedure? f) (procedure-arity-includes? f 1))

View File

@ -1,66 +1,7 @@
#lang scheme/base #lang scheme/base
(require (for-syntax scheme/base)
(require (for-syntax scheme/base "private/local.ss")
syntax/context
syntax/kerncase))
(provide local) (provide local)
(define-syntax (local stx) (define-syntax (local stx)
(syntax-case stx () (do-local stx #'letrec-syntaxes+values))
[(_ (defn ...) body1 body ...)
(let ([defs (let ([expand-context (generate-expand-context)])
(let loop ([defns (syntax->list (syntax (defn ...)))])
(apply
append
(map
(lambda (defn)
(let ([d (local-expand
defn
expand-context
(kernel-form-identifier-list))]
[check-ids (lambda (ids)
(for-each
(lambda (id)
(unless (identifier? id)
(raise-syntax-error
#f
"not an identifier for definition"
stx
id)))
ids))])
(syntax-case d (define-values define-syntaxes begin)
[(begin defn ...)
(loop (syntax->list (syntax (defn ...))))]
[(define-values (id ...) body)
(begin
(check-ids (syntax->list (syntax (id ...))))
(list d))]
[(define-values . rest)
(raise-syntax-error
#f "ill-formed definition" stx d)]
[(define-syntaxes (id ...) body)
(begin
(check-ids (syntax->list (syntax (id ...))))
(list d))]
[(define-syntaxes . rest)
(raise-syntax-error
#f "ill-formed definition" stx d)]
[_else
(raise-syntax-error
#f "not a definition" stx defn)])))
defns))))])
(let ([ids (apply append
(map
(lambda (d)
(syntax-case d ()
[(_ ids . __) (syntax->list (syntax ids))]))
defs))])
(let ([dup (check-duplicate-identifier ids)])
(when dup
(raise-syntax-error #f "duplicate identifier" stx dup)))
(with-syntax ([(def ...) defs])
(syntax/loc stx
(let () def ... (let () body1 body ...))))))]
[(_ x body1 body ...)
(raise-syntax-error #f "not a definition sequence" stx (syntax x))]))

View File

@ -7,7 +7,7 @@
(provide pi (provide pi
sqr sqr
sgn conjugate sgn conjugate
sinh cosh) sinh cosh tanh)
(define (sqr z) (* z z)) (define (sqr z) (* z z))
@ -29,3 +29,5 @@
(define (cosh x) (define (cosh x)
(/ (+ (exp x) (exp (- x))) 2.0)) (/ (+ (exp x) (exp (- x))) 2.0))
(define (tanh x) (/ (sinh x) (cosh x)))

View File

@ -148,10 +148,12 @@
(define-for-syntax not-in-a-class (define-for-syntax not-in-a-class
(lambda (stx) (lambda (stx)
(raise-syntax-error (if (eq? (syntax-local-context) 'expression)
#f (raise-syntax-error
"use of a class keyword is not in a class" #f
stx))) "use of a class keyword is not in a class"
stx)
(quasisyntax/loc stx (#%expression #,stx)))))
(define-syntax define/provide-context-keyword (define-syntax define/provide-context-keyword
(syntax-rules () (syntax-rules ()

View File

@ -356,7 +356,9 @@
(define (flat-contract predicate) (coerce-flat-contract 'flat-contract predicate)) (define (flat-contract predicate) (coerce-flat-contract 'flat-contract predicate))
(define (check-flat-named-contract predicate) (coerce-flat-contract 'flat-named-contract predicate)) (define (check-flat-named-contract predicate) (coerce-flat-contract 'flat-named-contract predicate))
(define (flat-named-contract name predicate) (define (flat-named-contract name predicate)
(coerce-flat-contract 'flat-named-contract predicate) (unless (and (procedure? predicate)
(procedure-arity-includes? predicate 1))
(error 'flat-named-contract "expected a procedure of arity 1 as second argument, got ~e" predicate))
(make-predicate-contract name predicate)) (make-predicate-contract name predicate))
;; build-compound-type-name : (union contract symbol) ... -> (-> sexp) ;; build-compound-type-name : (union contract symbol) ... -> (-> sexp)

View File

@ -0,0 +1,104 @@
#lang scheme/base
(require (for-syntax scheme/base)
(for-syntax syntax/context)
(for-syntax syntax/kerncase))
(provide (for-syntax do-local))
(define-for-syntax (do-local stx letrec-syntaxes+values-id)
(syntax-case stx ()
[(_ (defn ...) body1 body ...)
(let* ([def-ctx (syntax-local-make-definition-context)]
[defs (let ([expand-context (cons (gensym 'intdef)
(let ([orig-ctx (syntax-local-context)])
(if (pair? orig-ctx)
orig-ctx
null)))])
(let loop ([defns (syntax->list (syntax (defn ...)))])
(apply
append
(map
(lambda (defn)
(let ([d (local-expand
defn
expand-context
(kernel-form-identifier-list)
def-ctx)]
[check-ids (lambda (defn ids)
(for-each
(lambda (id)
(unless (identifier? id)
(raise-syntax-error
#f
"not an identifier for definition"
defn
id)))
ids))])
(syntax-case d (define-values define-syntaxes begin)
[(begin defn ...)
(loop (syntax->list (syntax (defn ...))))]
[(define-values (id ...) body)
(let ([ids (syntax->list (syntax (id ...)))])
(check-ids d ids)
(syntax-local-bind-syntaxes ids #f def-ctx)
(list d))]
[(define-values . rest)
(raise-syntax-error
#f "ill-formed definition" stx d)]
[(define-syntaxes (id ...) rhs)
(let ([ids (syntax->list (syntax (id ...)))])
(check-ids d ids)
(with-syntax ([rhs (local-transformer-expand
#'rhs
'expression
null)])
(syntax-local-bind-syntaxes ids #'rhs def-ctx)
(list (quasisyntax/loc d (define-syntaxes #,ids rhs)))))]
[(define-syntaxes . rest)
(raise-syntax-error
#f "ill-formed definition" stx d)]
[_else
(raise-syntax-error
#f "not a definition" stx defn)])))
defns))))])
(internal-definition-context-seal def-ctx)
(let ([ids (apply append
(map
(lambda (d)
(syntax-case d ()
[(_ ids . __) (syntax->list (syntax ids))]))
defs))]
[vbindings (apply append
(map (lambda (d)
(syntax-case d (define-values)
[(define-values ids rhs)
(list #'(ids rhs))]
[_ null]))
defs))]
[sbindings (apply append
(map (lambda (d)
(syntax-case d (define-syntaxes)
[(define-syntaxes ids rhs)
(list #'(ids rhs))]
[_ null]))
defs))])
(let ([dup (check-duplicate-identifier ids)])
(when dup
(raise-syntax-error #f "duplicate identifier" stx dup)))
(with-syntax ([sbindings sbindings]
[vbindings vbindings]
[LSV letrec-syntaxes+values-id]
[(body ...)
(map (lambda (stx)
;; add def-ctx:
(let ([q (local-expand #`(quote #,stx)
'expression
(list #'quote)
def-ctx)])
(syntax-case q ()
[(_ stx) #'stx])))
(syntax->list #'(body1 body ...)))])
(syntax/loc stx
(LSV sbindings vbindings
body ...)))))]
[(_ x body1 body ...)
(raise-syntax-error #f "not a definition sequence" stx (syntax x))]))

View File

@ -317,12 +317,12 @@
(syntax->list #'(elem ...))))] (syntax->list #'(elem ...))))]
[_ (transform-simple in 0 #| run phase |#)]))]) [_ (transform-simple in 0 #| run phase |#)]))])
(syntax-case stx () (syntax-case stx ()
[(_ in ...) [(_ in)
(with-syntax ([(new-in ...) (with-syntax ([(new-in ...) (transform-one #'in)])
(apply append
(map transform-one (syntax->list #'(in ...))))])
(syntax/loc stx (syntax/loc stx
(#%require new-in ...)))]))) (#%require new-in ...)))]
[(_ in ...)
(syntax/loc stx (begin (require in) ...))])))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; require transformers ;; require transformers
@ -653,7 +653,16 @@
(memq 0 modes)) (memq 0 modes))
(map (lambda (id) (map (lambda (id)
(make-export id (syntax-e id) 0 #f stx)) (make-export id (syntax-e id) 0 #f stx))
(filter (same-ctx? free-identifier=?) (filter (lambda (id)
(and ((same-ctx? free-identifier=?) id)
(let-values ([(v id) (syntax-local-value/immediate
id
(lambda () (values #f #f)))])
(not
(and (rename-transformer? v)
(syntax-property
(rename-transformer-target v)
'not-provide-all-defined))))))
ids)) ids))
null)))])))) null)))]))))

View File

@ -627,6 +627,7 @@
(define user-thread #t) ; set later to the thread (define user-thread #t) ; set later to the thread
(define user-done-evt #t) ; set in the same place (define user-done-evt #t) ; set in the same place
(define terminated? #f) ; set to an exception value when the sandbox dies (define terminated? #f) ; set to an exception value when the sandbox dies
(define breaks-originally-enabled? (break-enabled))
(define (limit-thunk thunk) (define (limit-thunk thunk)
(let* ([sec (and limits (car limits))] (let* ([sec (and limits (car limits))]
[mb (and limits (cadr limits))] [mb (and limits (cadr limits))]
@ -665,42 +666,67 @@
(define (user-break) (define (user-break)
(when user-thread (break-thread user-thread))) (when user-thread (break-thread user-thread)))
(define (user-process) (define (user-process)
(with-handlers ([void (lambda (exn) (channel-put result-ch exn))]) (let ([break-paramz (current-break-parameterization)])
;; first set up the environment (parameterize-break
(init-hook) #f ;; disable breaks during administrative work
((sandbox-init-hook)) (with-handlers ([void (lambda (exn) (channel-put result-ch exn))])
;; now read and evaluate the input program (call-with-break-parameterization
(evaluate-program break-paramz
(if (procedure? program-maker) (program-maker) program-maker) (lambda ()
limit-thunk ;; enable breaks, maybe
(and coverage? (lambda (es+get) (set! uncovered es+get)))) (when breaks-originally-enabled? (break-enabled #t))
(channel-put result-ch 'ok)) ;; first set up the environment
(set! eval-handler (cadr (sandbox-eval-handlers))) ; interactions handler (init-hook)
;; finally wait for interaction expressions ((sandbox-init-hook))
(let ([n 0]) ;; now read and evaluate the input program
(let loop () (evaluate-program
(let ([expr (channel-get input-ch)]) (if (procedure? program-maker) (program-maker) program-maker)
(when (eof-object? expr) limit-thunk
(terminated! 'eof) (channel-put result-ch expr) (user-kill)) (and coverage? (lambda (es+get) (set! uncovered es+get))))))
(with-handlers ([void (lambda (exn) (channel-put result-ch 'ok))
(channel-put result-ch (cons 'exn exn)))]) (set! eval-handler (cadr (sandbox-eval-handlers))) ; interactions handler
(define run ;; finally wait for interaction expressions
(if (evaluator-message? expr) (let ([n 0])
(case (evaluator-message-msg expr) (let loop ()
[(thunk) (limit-thunk (car (evaluator-message-args expr)))] (let ([expr (channel-get input-ch)])
[(thunk*) (car (evaluator-message-args expr))] (when (eof-object? expr)
[else (error 'sandbox "internal error (bad message)")]) (terminated! 'eof) (channel-put result-ch expr) (user-kill))
(limit-thunk (with-handlers ([void (lambda (exn)
(lambda () (channel-put result-ch (cons 'exn exn)))])
(set! n (add1 n)) (define run
(eval* (map (lambda (expr) (cons '#%top-interaction expr)) (if (evaluator-message? expr)
(input->code (list expr) 'eval n))))))) (case (evaluator-message-msg expr)
(channel-put result-ch (cons 'vals (call-with-values run list)))) [(thunk) (limit-thunk (car (evaluator-message-args expr)))]
(loop))))) [(thunk*) (car (evaluator-message-args expr))]
[else (error 'sandbox "internal error (bad message)")])
(limit-thunk
(lambda ()
(set! n (add1 n))
(eval* (map (lambda (expr) (cons '#%top-interaction expr))
(input->code (list expr) 'eval n)))))))
(channel-put result-ch (cons 'vals
(call-with-break-parameterization
break-paramz
(lambda ()
(call-with-values run list))))))
(loop)))))))
(define (get-user-result) (define (get-user-result)
(with-handlers ([(if (sandbox-propagate-breaks) exn:break? (lambda (_) #f)) (if (and (sandbox-propagate-breaks)
(lambda (e) (user-break) (get-user-result))]) ;; The following test is weird. We reliably catch breaks if breaks
(sync user-done-evt result-ch))) ;; are enabled, except that a break just before or after isn't
;; reliably propagated. A `get-result/enable-breaks' function
;; would make more sense.
(break-enabled))
;; The following loop ensures that breaks are disabled while trying
;; to handle a break, which ensures that we don't fail to
;; propagate a break.
(parameterize-break
#f
(let loop ()
(with-handlers* ([exn:break? (lambda (e) (user-break) (loop))])
(sync/enable-break user-done-evt result-ch))))
;; The simple case doesn't have to deal with breaks:
(sync user-done-evt result-ch)))
(define (user-eval expr) (define (user-eval expr)
;; the thread will usually be running, but it might be killed outside of ;; the thread will usually be running, but it might be killed outside of
;; the sandboxed environment, for example, if you do something like ;; the sandboxed environment, for example, if you do something like
@ -856,7 +882,9 @@
;; evaluates the program in `run-in-bg') -- so this parameterization ;; evaluates the program in `run-in-bg') -- so this parameterization
;; must be nested in the above (which is what paramaterize* does), or ;; must be nested in the above (which is what paramaterize* does), or
;; it will not use the new namespace. ;; it will not use the new namespace.
[current-eventspace (make-eventspace)]) [current-eventspace (parameterize-break
#f
(make-eventspace))])
(let ([t (bg-run->thread (run-in-bg user-process))]) (let ([t (bg-run->thread (run-in-bg user-process))])
(set! user-done-evt (handle-evt t (lambda (_) (terminate+kill! #t #t)))) (set! user-done-evt (handle-evt t (lambda (_) (terminate+kill! #t #t))))
(set! user-thread t)) (set! user-thread t))

View File

@ -2,51 +2,54 @@
(require (for-syntax scheme/base (require (for-syntax scheme/base
syntax/kerncase) syntax/kerncase)
"stxparam.ss" "stxparam.ss"
"private/stxparam.ss") "private/stxparam.ss"
"private/local.ss")
(provide splicing-let-syntax (provide splicing-let-syntax
splicing-let-syntaxes splicing-let-syntaxes
splicing-letrec-syntax splicing-letrec-syntax
splicing-letrec-syntaxes splicing-letrec-syntaxes
splicing-let
splicing-let-values
splicing-letrec
splicing-letrec-values
splicing-letrec-syntaxes+values
splicing-local
splicing-syntax-parameterize) splicing-syntax-parameterize)
(define-for-syntax (do-let-syntax stx rec? multi? let-stx-id) (define-for-syntax ((check-id stx) id-stx)
(unless (identifier? id-stx)
(raise-syntax-error #f "expected an identifier" stx id-stx))
(list id-stx))
(define-for-syntax ((check-ids stx) ids-stx)
(let ([ids (syntax->list ids-stx)])
(unless ids
(raise-syntax-error
#f
"expected a parenthesized sequence of identifiers"
stx
ids-stx))
(for-each (check-id stx) ids)
ids))
(define-for-syntax (check-dup-binding stx idss)
(let ([dup-id (check-duplicate-identifier (apply append idss))])
(when dup-id
(raise-syntax-error #f "duplicate binding" stx dup-id))))
(define-for-syntax (do-let-syntax stx rec? multi? let-id def-id need-top-decl?)
(syntax-case stx () (syntax-case stx ()
[(_ ([ids expr] ...) body ...) [(_ ([ids expr] ...) body ...)
(let ([all-ids (map (lambda (ids-stx) (let ([all-ids (map ((if multi? check-ids check-id) stx)
(let ([ids (if multi?
(syntax->list ids-stx)
(list ids-stx))])
(unless ids
(raise-syntax-error
#f
"expected a parenthesized sequence of identifiers"
stx
ids-stx))
(for-each (lambda (id)
(unless (identifier? id)
(raise-syntax-error
#f
"expected an identifier"
stx
id)))
ids)
ids))
(syntax->list #'(ids ...)))]) (syntax->list #'(ids ...)))])
(let ([dup-id (check-duplicate-identifier (check-dup-binding stx all-ids)
(apply append all-ids))])
(when dup-id
(raise-syntax-error
#f
"duplicate binding"
stx
dup-id)))
(if (eq? 'expression (syntax-local-context)) (if (eq? 'expression (syntax-local-context))
(with-syntax ([let-stx let-stx-id]) (with-syntax ([LET let-id])
(syntax/loc stx (syntax/loc stx
(let-stx ([ids expr] ...) (LET ([ids expr] ...)
(#%expression body) (#%expression body)
...))) ...)))
(let ([def-ctx (syntax-local-make-definition-context)] (let ([def-ctx (syntax-local-make-definition-context)]
[ctx (list (gensym 'intdef))]) [ctx (list (gensym 'intdef))])
(syntax-local-bind-syntaxes (apply append all-ids) #f def-ctx) (syntax-local-bind-syntaxes (apply append all-ids) #f def-ctx)
@ -69,23 +72,97 @@
(map add-context exprs) (map add-context exprs)
exprs))] exprs))]
[(body ...) [(body ...)
(map add-context (syntax->list #'(body ...)))]) (map add-context (syntax->list #'(body ...)))]
#'(begin [DEF def-id])
(define-syntaxes (id ...) expr) (with-syntax ([(top-decl ...)
... (if (and need-top-decl? (equal? 'top-level (syntax-local-context)))
body ...))))))])) #'((define-syntaxes (id ... ...) (values)))
null)])
#'(begin
top-decl ...
(DEF (id ...) expr)
...
body ...)))))))]))
(define-syntax (splicing-let-syntax stx) (define-syntax (splicing-let-syntax stx)
(do-let-syntax stx #f #f #'let-syntax)) (do-let-syntax stx #f #f #'let-syntax #'define-syntaxes #f))
(define-syntax (splicing-let-syntaxes stx) (define-syntax (splicing-let-syntaxes stx)
(do-let-syntax stx #f #t #'let-syntaxes)) (do-let-syntax stx #f #t #'let-syntaxes #'define-syntaxes #f))
(define-syntax (splicing-letrec-syntax stx) (define-syntax (splicing-letrec-syntax stx)
(do-let-syntax stx #t #f #'letrec-syntax)) (do-let-syntax stx #t #f #'letrec-syntax #'define-syntaxes #f))
(define-syntax (splicing-letrec-syntaxes stx) (define-syntax (splicing-letrec-syntaxes stx)
(do-let-syntax stx #t #t #'letrec-syntaxes)) (do-let-syntax stx #t #t #'letrec-syntaxes #'define-syntaxes #f))
(define-syntax (splicing-let stx)
(do-let-syntax stx #f #f #'let #'define-values #f))
(define-syntax (splicing-let-values stx)
(do-let-syntax stx #f #t #'let-values #'define-values #f))
(define-syntax (splicing-letrec stx)
(do-let-syntax stx #t #f #'letrec #'define-values #t))
(define-syntax (splicing-letrec-values stx)
(do-let-syntax stx #t #t #'letrec-values #'define-values #t))
;; ----------------------------------------
(define-syntax (splicing-letrec-syntaxes+values stx)
(syntax-case stx ()
[(_ ([sids sexpr] ...) ([vids vexpr] ...) body ...)
(let* ([all-sids (map (check-ids stx)
(syntax->list #'(sids ...)))]
[all-vids (map (check-ids stx)
(syntax->list #'(vids ...)))]
[all-ids (append all-sids all-vids)])
(check-dup-binding stx all-ids)
(if (eq? 'expression (syntax-local-context))
(syntax/loc stx
(letrec-syntaxes+values ([sids sexpr] ...) ([vids vexpr] ...)
(#%expression body) ...))
(let ([def-ctx (syntax-local-make-definition-context)]
[ctx (list (gensym 'intdef))])
(syntax-local-bind-syntaxes (apply append all-ids) #f def-ctx)
(internal-definition-context-seal def-ctx)
(let* ([add-context
(lambda (expr)
(let ([q (local-expand #`(quote #,expr)
ctx
(list #'quote)
def-ctx)])
(syntax-case q ()
[(_ expr) #'expr])))]
[add-context-to-idss
(lambda (idss)
(map add-context idss))])
(with-syntax ([((sid ...) ...)
(map add-context-to-idss all-sids)]
[((vid ...) ...)
(map add-context-to-idss all-vids)]
[(sexpr ...)
(map add-context (syntax->list #'(sexpr ...)))]
[(vexpr ...)
(map add-context (syntax->list #'(vexpr ...)))]
[(body ...)
(map add-context (syntax->list #'(body ...)))])
(with-syntax ([top-decl
(if (equal? 'top-level (syntax-local-context))
#'(define-syntaxes (vid ... ...) (values))
#'(begin))])
(syntax/loc stx
(begin
top-decl
(define-syntaxes (sid ...) sexpr) ...
(define-values (vid ...) vexpr) ...
body ...))))))))]))
(define-syntax (splicing-local stx)
(do-local stx #'splicing-letrec-syntaxes+values))
;; ---------------------------------------- ;; ----------------------------------------

View File

@ -238,7 +238,8 @@
(call-with-trusted-sandbox-configuration (call-with-trusted-sandbox-configuration
(lambda () (lambda ()
(parameterize ([sandbox-output 'string] (parameterize ([sandbox-output 'string]
[sandbox-error-output 'string]) [sandbox-error-output 'string]
[sandbox-propagate-breaks #f])
(make-evaluator '(begin (require scheme/base))))))) (make-evaluator '(begin (require scheme/base)))))))
(define (close-eval e) (define (close-eval e)
@ -246,23 +247,24 @@
"") "")
(define (do-plain-eval ev s catching-exns?) (define (do-plain-eval ev s catching-exns?)
(call-with-values (lambda () (parameterize ([sandbox-propagate-breaks #f])
((scribble-eval-handler) (call-with-values (lambda ()
ev ((scribble-eval-handler)
catching-exns? ev
(let ([s (strip-comments s)]) catching-exns?
(cond (let ([s (strip-comments s)])
[(syntax? s) (cond
(syntax-case s (module) [(syntax? s)
[(module . _rest) (syntax-case s (module)
(syntax->datum s)] [(module . _rest)
[_else s])] (syntax->datum s)]
[(bytes? s) [_else s])]
`(begin ,s)] [(bytes? s)
[(string? s) `(begin ,s)]
`(begin ,s)] [(string? s)
[else s])))) `(begin ,s)]
list)) [else s]))))
list)))
(define-syntax-rule (quote-expr e) 'e) (define-syntax-rule (quote-expr e) 'e)

View File

@ -1076,6 +1076,7 @@
[(#f) null] [(#f) null]
[(top) '((valign "top"))] [(top) '((valign "top"))]
[(baseline) '((valign "baseline"))] [(baseline) '((valign "baseline"))]
[(center) '((valign "center"))]
[(bottom) '((valign "bottom"))]) [(bottom) '((valign "bottom"))])
,@(if (string? st) ,@(if (string? st)
`([class ,st]) `([class ,st])

View File

@ -302,12 +302,12 @@
(let ([flows (car flowss)] (let ([flows (car flowss)]
[row-style (car row-styles)]) [row-style (car row-styles)])
(let loop ([flows flows] (let loop ([flows flows]
[col-v-styles (and (list? row-style) [col-v-styles (or (and (list? row-style)
(or (let ([p (assoc 'valignment row-style)]) (let ([p (assoc 'valignment row-style)])
(and p (cdr p))) (and p (cdr p))))
(let ([p (and (list? (table-style t)) (let ([p (and (list? (table-style t))
(assoc 'valignment (table-style t)))]) (assoc 'valignment (table-style t)))])
(and p (cdr p)))))]) (and p (cdr p))))])
(unless (null? flows) (unless (null? flows)
(when index? (printf "\\item ")) (when index? (printf "\\item "))
(unless (eq? 'cont (car flows)) (unless (eq? 'cont (car flows))
@ -347,17 +347,20 @@
(printf "\\begin{tabular}~a{@{}l@{}}\n" (printf "\\begin{tabular}~a{@{}l@{}}\n"
(cond (cond
[(eq? vstyle 'top) "[t]"] [(eq? vstyle 'top) "[t]"]
[(eq? vstyle 'center) "[c]"]
[else ""]))) [else ""])))
(let loop ([ps (flow-paragraphs p)]) (let loop ([ps (flow-paragraphs p)])
(cond (cond
[(null? ps) (void)] [(null? ps) (void)]
[else [else
(let ([minipage? (not (or (paragraph? (car ps)) (let ([minipage? (or (not (or (paragraph? (car ps))
(table? (car ps))))]) (table? (car ps))))
(eq? vstyle 'center))])
(when minipage? (when minipage?
(printf "\\begin{minipage}~a{~a\\linewidth}\n" (printf "\\begin{minipage}~a{~a\\linewidth}\n"
(cond (cond
[(eq? vstyle 'top) "[t]"] [(eq? vstyle 'top) "[t]"]
[(eq? vstyle 'center) "[c]"]
[else ""]) [else ""])
(/ 1.0 twidth))) (/ 1.0 twidth)))
(render-block (car ps) part ri #f) (render-block (car ps) part ri #f)

View File

@ -106,6 +106,9 @@
[(_ #:literals lits [spec ...] desc ...) [(_ #:literals lits [spec ...] desc ...)
(syntax/loc stx (syntax/loc stx
(defform*/subs #:literals lits [spec ...] () desc ...))] (defform*/subs #:literals lits [spec ...] () desc ...))]
[(_ #:id id [spec ...] desc ...)
(syntax/loc stx
(defform*/subs #:id id [spec ...] () desc ...))]
[(_ [spec ...] desc ...) [(_ [spec ...] desc ...)
(syntax/loc stx (syntax/loc stx
(defform*/subs [spec ...] () desc ...))])) (defform*/subs [spec ...] () desc ...))]))

View File

@ -123,7 +123,8 @@
(make-element style content))) (make-element style content)))
(define (typeset-atom c out color? quote-depth) (define (typeset-atom c out color? quote-depth)
(if (var-id? (syntax-e c)) (if (and (var-id? (syntax-e c))
(zero? quote-depth))
(out (format "~s" (let ([v (var-id-sym (syntax-e c))]) (out (format "~s" (let ([v (var-id-sym (syntax-e c))])
(if (syntax? v) (if (syntax? v)
(syntax-e v) (syntax-e v)
@ -135,7 +136,9 @@
(let ([sc (syntax-e c)]) (let ([sc (syntax-e c)])
(let ([s (format "~s" (if (literal-syntax? sc) (let ([s (format "~s" (if (literal-syntax? sc)
(literal-syntax-stx sc) (literal-syntax-stx sc)
sc))]) (if (var-id? sc)
(var-id-sym sc)
sc)))])
(if (and (symbol? sc) (if (and (symbol? sc)
((string-length s) . > . 1) ((string-length s) . > . 1)
(char=? (string-ref s 0) #\_) (char=? (string-ref s 0) #\_)

View File

@ -2,7 +2,7 @@
(require scheme/promise) (require scheme/promise)
(provide output splice verbatim unverbatim flush prefix) (provide output)
;; Outputs some value, for the preprocessor langauge. ;; Outputs some value, for the preprocessor langauge.
;; ;;
@ -19,9 +19,11 @@
;; system (when line counts are enabled) -- this is used to tell what part of a ;; system (when line counts are enabled) -- this is used to tell what part of a
;; prefix is already displayed. ;; prefix is already displayed.
;; ;;
;; Each prefix is either an integer (for a number of spaces), a string, or #f ;; Each prefix is either an integer (for a number of spaces) or a
;; indicating that prefixes are disabled (different from 0 -- they will not be ;; string. The prefix mechanism can be disabled by using #f for the
;; accumulated). ;; global prefix, and in this case the line prefix can have (cons pfx
;; lpfx) so it can be restored -- used by `verbatim' and `unverbatim'
;; resp. (This is different from 0 -- no prefix will be accumulated).
;; ;;
(define (output x [p (current-output-port)]) (define (output x [p (current-output-port)])
;; these are the global prefix and the one that is local to the current line ;; these are the global prefix and the one that is local to the current line
@ -63,6 +65,37 @@
(let ([col (- col len1)] (let ([col (- col len1)]
[len2 (if (number? pfx2) pfx2 (string-length pfx2))]) [len2 (if (number? pfx2) pfx2 (string-length pfx2))])
(when (< col len2) (write-string (->str pfx2) p col )))]))))) (when (< col len2) (write-string (->str pfx2) p col )))])))))
;; the basic printing unit: strings
(define (output-string x)
(define pfx (mcar pfxs))
(if (not pfx) ; verbatim mode?
(write-string x p)
(let ([len (string-length x)]
[nls (regexp-match-positions* #rx"\n" x)])
(let loop ([start 0] [nls nls] [lpfx (mcdr pfxs)] [col (getcol)])
(cond [(pair? nls)
(let ([nl (car nls)])
(if (regexp-match? #rx"^ *$" x start (car nl))
(newline p) ; only spaces before the end of the line
(begin (output-pfx col pfx lpfx)
(write-string x p start (cdr nl))))
(loop (cdr nl) (cdr nls) 0 0))]
;; last substring from here (always set lpfx state when done)
[(start . = . len)
(set-mcdr! pfxs lpfx)]
[(col . > . (2pfx-length pfx lpfx))
(set-mcdr! pfxs lpfx)
;; the prefix was already shown, no accumulation needed
(write-string x p start)]
[else
(let ([m (regexp-match-positions #rx"^ +" x start)])
;; accumulate spaces to lpfx, display if it's not all spaces
(let ([lpfx (if m (pfx+ lpfx (- (cdar m) (caar m))) lpfx)])
(set-mcdr! pfxs lpfx)
(unless (and m (= len (cdar m)))
(output-pfx col pfx lpfx)
;; the spaces were already added to lpfx
(write-string x p (if m (cdar m) start)))))])))))
;; main loop ;; main loop
(define (loop x) (define (loop x)
(cond (cond
@ -72,16 +105,13 @@
;; one, then output the contents recursively (no need to change the ;; one, then output the contents recursively (no need to change the
;; state, since we pass the values in the loop, and we'd need to restore ;; state, since we pass the values in the loop, and we'd need to restore
;; it afterwards anyway) ;; it afterwards anyway)
[(pair? x) (let* ([pfx (mcar pfxs)] [lpfx (mcdr pfxs)] [(pair? x) (if (list? x)
[npfx (pfx+col (pfx+ pfx lpfx))]) (let* ([pfx (mcar pfxs)] [lpfx (mcdr pfxs)]
(set-mcar! pfxs npfx) (set-mcdr! pfxs 0) [npfx (pfx+col (pfx+ pfx lpfx))])
(if (list? x) (set-mcar! pfxs npfx) (set-mcdr! pfxs 0)
(for ([x (in-list x)]) (loop x)) (for ([x (in-list x)]) (loop x))
(let ploop ([x x]) (set-mcar! pfxs pfx) (set-mcdr! pfxs lpfx))
(if (pair? x) (begin (loop (car x)) (loop (cdr x))))]
(begin (loop (car x)) (ploop (cdr x)))
(loop x))))
(set-mcar! pfxs pfx) (set-mcdr! pfxs lpfx))]
;; delayed values ;; delayed values
[(and (procedure? x) (procedure-arity-includes? x 0)) (loop (x))] [(and (procedure? x) (procedure-arity-includes? x 0)) (loop (x))]
[(promise? x) (loop (force x))] [(promise? x) (loop (force x))]
@ -114,41 +144,16 @@
[else (error 'output "unknown special value flag: ~e" [else (error 'output "unknown special value flag: ~e"
(special-flag x))]))] (special-flag x))]))]
[else [else
(let* ([x (cond [(string? x) x] (output-string
[(bytes? x) (bytes->string/utf-8 x)] (cond [(string? x) x]
[(symbol? x) (symbol->string x)] [(bytes? x) (bytes->string/utf-8 x)]
[(path? x) (path->string x)] [(symbol? x) (symbol->string x)]
[(keyword? x) (keyword->string x)] [(path? x) (path->string x)]
[(number? x) (number->string x)] [(keyword? x) (keyword->string x)]
[(char? x) (string x)] [(number? x) (number->string x)]
;; generic fallback: throw an error [(char? x) (string x)]
[else (error 'output "don't know how to render value: ~v" ;; generic fallback: throw an error
x)])] [else (error 'output "don't know how to render value: ~v" x)]))]))
[len (string-length x)]
[nls (regexp-match-positions* #rx"\n" x)]
[pfx (mcar pfxs)])
(let loop ([start 0] [nls nls] [lpfx (mcdr pfxs)] [col (getcol)])
(cond [(pair? nls)
(let ([nl (car nls)])
(output-pfx col pfx lpfx)
(write-string x p start (cdr nl))
(loop (cdr nl) (cdr nls) 0 0))]
;; last substring from here (always set lpfx state when done)
[(start . = . len)
(set-mcdr! pfxs lpfx)]
[(col . > . (2pfx-length pfx lpfx))
(set-mcdr! pfxs lpfx)
;; the prefix was already shown, no accumulation needed
(write-string x p start)]
[else
(let ([m (regexp-match-positions #rx"^ +" x start)])
;; accumulate spaces to lpfx, display if it's not all spaces
(let ([lpfx (if m (pfx+ lpfx (- (cdar m) (caar m))) lpfx)])
(set-mcdr! pfxs lpfx)
(unless (and m (= len (cdar m)))
(output-pfx col pfx lpfx)
;; the spaces were already added to lpfx
(write-string x p (if m (cdar m) start)))))])))]))
;; ;;
(port-count-lines! p) (port-count-lines! p)
(loop x) (loop x)
@ -164,6 +169,10 @@
(set! last (cons p s)) (set! last (cons p s))
s))))) s)))))
;; special constructs
(provide splice verbatim unverbatim flush prefix)
(define-struct special (flag contents)) (define-struct special (flag contents))
(define (splice . contents) (make-special 'splice contents)) (define (splice . contents) (make-special 'splice contents))
@ -179,3 +188,25 @@
(let ([spaces (make-string n #\space)]) (let ([spaces (make-string n #\space)])
(if (< n 80) (vector-set! v n spaces) (hash-set! t n spaces)) (if (< n 80) (vector-set! v n spaces) (hash-set! t n spaces))
spaces))))) spaces)))))
;; Convenient utilities
(provide add-newlines)
(define (add-newlines list #:sep [sep "\n"])
(define r
(let loop ([list list])
(if (null? list)
null
(let ([1st (car list)])
(if (or (not 1st) (void? 1st))
(loop (cdr list))
(list* sep 1st (loop (cdr list))))))))
(if (null? r) r (cdr r)))
(provide split-lines)
(define (split-lines list)
(let loop ([list list] [cur '()] [r '()])
(cond
[(null? list) (reverse (cons (reverse cur) r))]
[(equal? "\n" (car list)) (loop (cdr list) '() (cons (reverse cur) r))]
[else (loop (cdr list) (cons (car list) cur) r)])))

View File

@ -159,8 +159,10 @@
(cond [(pair? rest) #`(list* #,@nondefns (begin/collect* #t #,@rest))] (cond [(pair? rest) #`(list* #,@nondefns (begin/collect* #t #,@rest))]
[(and (not always-list?) (= 1 (length nondefns))) (car nondefns)] [(and (not always-list?) (= 1 (length nondefns))) (car nondefns)]
[else #`(list #,@nondefns)])) [else #`(list #,@nondefns)]))
(local-expand (if (null? defns) body #`(let () #,@defns #,body)) (begin0
context stoplist (car context))) (local-expand (if (null? defns) body #`(let () #,@defns #,body))
context stoplist (car context))
(internal-definition-context-seal (car context))))
(define-syntax-rule (begin/collect x ...) (begin/collect* #f x ...)) (define-syntax-rule (begin/collect x ...) (begin/collect* #f x ...))
;; begin for templates (allowing definition blocks) ;; begin for templates (allowing definition blocks)

View File

@ -1,10 +1,15 @@
#lang scribble/doc #lang scribble/doc
@(require "common.ss" @(require "common.ss"
scribble/struct
scribble/bnf scribble/bnf
scheme/list
mrlib/tex-table
(for-label scheme/gui/base)) (for-label scheme/gui/base))
@(define (keybinding key . desc) @(define (keybinding key . desc)
(apply item @index[(list (format "~a keybinding" key)) key] " : " desc)) (let* ([keys (if (string? key) (list key) key)]
[key-str (apply string-append (add-between keys " "))])
(apply item @index[(map (lambda (x) (format "~a keybinding" x)) keys) key-str] " : " desc)))
@(define-syntax-rule (def-mod-beg id) @(define-syntax-rule (def-mod-beg id)
(begin (begin
@ -166,6 +171,25 @@ as the @tech{definitions window} plus a few more:
expression history down to the prompt} expression history down to the prompt}
] ]
@section{LaTeX and TeX inspired keybindings}
@itemize[
@keybinding['("C-\\" "M-\\")]{traces backwards from the insertion
point, looking for a backslash followed by a @index["LaTeX"]{LaTeX} macro name; if one is
found, it replaces the backslash and the macro's name with the keybinding.
These are the currently supported macro names and the keys they map into:
@(make-table
'()
(map (lambda (line)
(let ([macro (list-ref line 0)]
[char (list-ref line 1)])
(list (make-flow (list (make-paragraph (list (index (format "\\~a keyboard shortcut" macro))
(tt (format "\\~a" macro))))))
(make-flow (list (make-paragraph (list char)))))))
tex-shortcut-table))
}
]
@section[#:tag "defining-shortcuts"]{Defining Custom Shortcuts} @section[#:tag "defining-shortcuts"]{Defining Custom Shortcuts}
The @onscreen{Add User-defined Keybindings...} menu item in the The @onscreen{Add User-defined Keybindings...} menu item in the

View File

@ -64,8 +64,6 @@ obtain a tag. The tag is the string form of @schemevarfont{id}.}
@subsection{Unsafe Tagged C Pointer Functions} @subsection{Unsafe Tagged C Pointer Functions}
@declare-exporting[scribblings/foreign/unsafe-foreign]
@defproc*[([(cpointer-has-tag? [cptr any/c] [tag any/c]) boolean?] @defproc*[([(cpointer-has-tag? [cptr any/c] [tag any/c]) boolean?]
[(cpointer-push-tag! [cptr any/c] [tag any/c]) void])]{ [(cpointer-push-tag! [cptr any/c] [tag any/c]) void])]{
@ -157,8 +155,6 @@ Converts the list @scheme[lst] to a C vector of the given
@subsection{Unsafe C Vector Construction} @subsection{Unsafe C Vector Construction}
@declare-exporting[scribblings/foreign/unsafe-foreign]
@defproc[(make-cvector* [cptr any/c] [type ctype?] @defproc[(make-cvector* [cptr any/c] [type ctype?]
[length exact-nonnegative-integer?]) [length exact-nonnegative-integer?])
cvector?]{ cvector?]{

View File

@ -5,7 +5,7 @@
@author["Eli Barzilay"] @author["Eli Barzilay"]
@defmodule[scheme/foreign] @defmodule[scheme/foreign #:use-sources ('#%foreign)]
The @schememodname[scheme/foreign] library enables the direct use of The @schememodname[scheme/foreign] library enables the direct use of
C-based APIs within Scheme programs---without writing any new C C-based APIs within Scheme programs---without writing any new C

View File

@ -19,9 +19,6 @@ Returns @scheme[#t] if @scheme[v] is the result of @scheme[ffi-lib],
@section{Unsafe Library Functions} @section{Unsafe Library Functions}
@declare-exporting[scribblings/foreign/unsafe-foreign]
@defproc[(ffi-lib [path (or/c path-string? #f)] @defproc[(ffi-lib [path (or/c path-string? #f)]
[version (or/c string? (listof string?) #f) #f]) any]{ [version (or/c string? (listof string?) #f) #f]) any]{

View File

@ -54,8 +54,6 @@ Like @scheme[list->cblock], but for Scheme vectors.}
@section{Unsafe Miscellaneous Operations} @section{Unsafe Miscellaneous Operations}
@declare-exporting[scribblings/foreign/unsafe-foreign]
@defproc[(cblock->list [cblock any/c][type ctype?][length exact-nonnegative-integer?]) @defproc[(cblock->list [cblock any/c][type ctype?][length exact-nonnegative-integer?])
list?]{ list?]{

View File

@ -50,8 +50,6 @@ offset is always in bytes.}
@section{Unsafe Pointer Operations} @section{Unsafe Pointer Operations}
@declare-exporting[scribblings/foreign/unsafe-foreign]
@defproc[(set-ptr-offset! [cptr cpointer?][offset exact-integer?][ctype ctype? _byte]) @defproc[(set-ptr-offset! [cptr cpointer?][offset exact-integer?][ctype ctype? _byte])
void?]{ void?]{
@ -209,8 +207,6 @@ can contain other information).}
@section{Unsafe Memory Management} @section{Unsafe Memory Management}
@declare-exporting[scribblings/foreign/unsafe-foreign]
For general information on C-level memory management with PLT Scheme, For general information on C-level memory management with PLT Scheme,
see @|InsideMzScheme|. see @|InsideMzScheme|.

View File

@ -1,11 +1,31 @@
#lang scheme/base #lang scheme/base
(require scheme/foreign
(require scheme/foreign) (for-syntax scheme/base
scheme/provide-transform))
(error 'unsafe! "only `for-label' use in the documentation") (error 'unsafe! "only `for-label' use in the documentation")
(unsafe!) (unsafe!)
(provide (protect-out (all-defined-out)) ;; This is like `all-defined-out', but it ignores the 'not-provide-all-defined
;; property, so that the bindings introduced by `unsafe!' are exported.
(define-syntax all-unsafe-defined-out
(make-provide-transformer
(lambda (stx modes)
(syntax-case stx ()
[(_)
(let-values ([(ids stx-ids) (syntax-local-module-defined-identifiers)]
[(same-ctx?) (lambda (free-identifier=?)
(lambda (id)
(free-identifier=? id
(datum->syntax
stx
(syntax-e id)))))])
(map (lambda (id)
(make-export id (syntax-e id) 0 #f stx))
(filter (same-ctx? free-identifier=?)
ids)))]))))
(provide (protect-out (all-unsafe-defined-out))
(all-from-out scheme/foreign)) (all-from-out scheme/foreign))

View File

@ -67,7 +67,7 @@ scheme
In addition to the main @tech{collection} directory, which contains In addition to the main @tech{collection} directory, which contains
all collections that are part of the installation, collections can all collections that are part of the installation, collections can
also be installed in a user-specific location. Finally, additional also be installed in a user-specific location. Finally, additional
collection directories can be specified n configuration files or collection directories can be specified in configuration files or
through the @envvar{PLTCOLLECTS} search path. Try running the through the @envvar{PLTCOLLECTS} search path. Try running the
following program to find out where your collections are: following program to find out where your collections are:

View File

@ -1,6 +1,8 @@
#lang scribble/doc #lang scribble/doc
@(require scribble/manual @(require scribble/manual
(for-label scheme/base) (for-label scheme/base
compiler/xform
dynext/compile)
"common.ss") "common.ss")
@(define (xflag str) (as-index (DFlag str))) @(define (xflag str) (as-index (DFlag str)))
@ -55,3 +57,29 @@ loaded into the 3m variant of PLT Scheme. The @as-index{@DFlag{cgc}}
flag specifies that the extension is to be used with the CGC. The flag specifies that the extension is to be used with the CGC. The
default depends on @|mzc|: @DFlag{3m} if @|mzc| itself is running in default depends on @|mzc|: @DFlag{3m} if @|mzc| itself is running in
3m, @DFlag{cgc} if @|mzc| itself is running in CGC. 3m, @DFlag{cgc} if @|mzc| itself is running in CGC.
@section[#:tag "xform-api"]{Scheme API for 3m Transformation}
@defmodule[compiler/xform]
@defproc[(xform [quiet? any/c]
[input-file path-string?]
[output-file path-string?]
[include-dirs (listof path-string?)]
[#:keep-lines? keep-lines? boolean? #f])
any/c]{
Transforms C code that is written without explicit GC-cooperation
hooks to cooperate with PLT Scheme's 3m garbage collector; see
@secref[#:doc '(lib "scribblings/inside/inside.scrbl") "overview"] in
@other-manual['(lib "scribblings/inside/inside.scrbl")].
The arguments are as for @scheme[compile-extension]; in addition
@scheme[keep-lines?] can be @scheme[#t] to generate GCC-style
annotations to connect the generated C code with the original source
locations.
The file generated by @scheme[xform] can be compiled via
@scheme[compile-extension].}

View File

@ -89,7 +89,7 @@ separated by a prompt tagged with @scheme[prompt-tag]..}
@defproc[(continuation-mark-set->list* @defproc[(continuation-mark-set->list*
[mark-set continuation-mark-set?] [mark-set continuation-mark-set?]
[key-v any/c] [key-list (listof any/c)]
[none-v any/c #f] [none-v any/c #f]
[prompt-tag prompt-tag? (default-continuation-prompt-tag)]) [prompt-tag prompt-tag? (default-continuation-prompt-tag)])
(listof vector?)]{ (listof vector?)]{

View File

@ -367,7 +367,7 @@ The @scheme[case->] contract is a specialized contract,
designed to match @scheme[case-lambda] and designed to match @scheme[case-lambda] and
@scheme[unconstrained-domain->] allows range checking @scheme[unconstrained-domain->] allows range checking
without requiring that the domain have any particular shape without requiring that the domain have any particular shape
(see below for an exmaple use). (see below for an example use).
@defform*/subs[#:literals (any values) @defform*/subs[#:literals (any values)
[(-> dom ... range)] [(-> dom ... range)]

View File

@ -111,7 +111,8 @@ files that already exist:
@item{@indexed-scheme['update] --- open an existing file without @item{@indexed-scheme['update] --- open an existing file without
truncating it; if the file does not exist, the truncating it; if the file does not exist, the
@exnraise[exn:fail:filesystem].} @exnraise[exn:fail:filesystem]. Use @scheme[file-position]
to change the current read/write position.}
@item{@indexed-scheme['can-update] --- open an existing file without @item{@indexed-scheme['can-update] --- open an existing file without
truncating it, or create the file if it does not exist.} truncating it, or create the file if it does not exist.}

View File

@ -256,7 +256,9 @@ the module's explicit imports.}
Returns two association lists mapping @tech{phase level} values (where Returns two association lists mapping @tech{phase level} values (where
@scheme[#f] corresponds to the @tech{label phase level}) to exports at @scheme[#f] corresponds to the @tech{label phase level}) to exports at
the corresponding phase. The first association list is for exported the corresponding phase. The first association list is for exported
variables, and the second is for exported syntax. variables, and the second is for exported syntax. Beware however, that
value bindings re-exported though a @tech{rename transformer} are in
the syntax list instead of the value list.
Each associated list, which is represented by @scheme[list?] in the Each associated list, which is represented by @scheme[list?] in the
result contracts above, more precisely matches the contract result contracts above, more precisely matches the contract

View File

@ -890,6 +890,10 @@ Returns the hyperbolic sine of @scheme[z].}
Returns the hyperbolic cosine of @scheme[z].} Returns the hyperbolic cosine of @scheme[z].}
@defproc[(tanh [z number?]) number?]{
Returns the hyperbolic tangent of @scheme[z].}
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@close-eval[math-eval] @close-eval[math-eval]

View File

@ -633,6 +633,13 @@ Returns @scheme[(filter (lambda (x) x) (map proc lst ...))], but
without building the intermediate list.} without building the intermediate list.}
@defproc[(count [proc procedure?] [lst list?] ...+)
list?]{
Returns @scheme[(length (filter proc lst ...))], but
without building the intermediate list.}
@defproc[(partition [pred procedure?] [lst list?]) @defproc[(partition [pred procedure?] [lst list?])
(values list? list?)]{ (values list? list?)]{

View File

@ -411,12 +411,18 @@ collected by sandbox evaluators. Use
@defboolparam[sandbox-propagate-breaks propagate?]{ @defboolparam[sandbox-propagate-breaks propagate?]{
When this boolean parameter is true, breaking while an evaluator is When both this boolean parameter and @scheme[(break-enabled)] are true,
running evaluator propagates the break signal to the sandboxed breaking while an evaluator is
running propagates the break signal to the sandboxed
context. This makes the sandboxed evaluator break, typically, but context. This makes the sandboxed evaluator break, typically, but
beware that sandboxed evaluation can capture and avoid the breaks (so beware that sandboxed evaluation can capture and avoid the breaks (so
if safe execution of code is your goal, make sure you use it with a if safe execution of code is your goal, make sure you use it with a
time limit). The default is @scheme[#t].} time limit). Also, beware that a break may be received after the
evaluator's result, in which case the evaluation result is lost. Finally,
beware that a break may be propagated after an evaluator has produced
a result, so that the break is visible on the next interaction with
the evaluator (or the break is lost if the evaluator is not used
further). The default is @scheme[#t].}
@defparam[sandbox-namespace-specs spec (cons/c (-> namespace?) @defparam[sandbox-namespace-specs spec (cons/c (-> namespace?)

View File

@ -1,6 +1,7 @@
#lang scribble/doc #lang scribble/doc
@(require "mz.ss" @(require "mz.ss"
(for-syntax scheme/base)) (for-syntax scheme/base)
scribble/scheme)
@(define-syntax speed @(define-syntax speed
(syntax-rules () (syntax-rules ()
@ -246,23 +247,24 @@ the structure and returns a sequence. If @scheme[v] is an instance of
a structure type with this property, then @scheme[(sequence? v)] a structure type with this property, then @scheme[(sequence? v)]
produces @scheme[#t]. produces @scheme[#t].
@examples[ @let-syntax[([car (make-element-id-transformer (lambda (id) #'@schemeidfont{car}))])
(define-struct train (car next) @examples[
#:property prop:sequence (lambda (t) (define-struct train (car next)
(make-do-sequence #:property prop:sequence (lambda (t)
(lambda () (make-do-sequence
(values train-car (lambda ()
train-next (values train-car
t train-next
(lambda (t) t) t
(lambda (v) #t) (lambda (t) t)
(lambda (t v) #t)))))) (lambda (v) #t)
(for/list ([c (make-train 'engine (lambda (t v) #t))))))
(make-train 'boxcar (for/list ([c (make-train 'engine
(make-train 'caboose (make-train 'boxcar
#f)))]) (make-train 'caboose
c) #f)))])
]} c)
]]}
@section{Sequence Generators} @section{Sequence Generators}

View File

@ -1,7 +1,8 @@
#lang scribble/doc #lang scribble/doc
@(require "mz.ss" @(require "mz.ss"
(for-label scheme/splicing (for-label scheme/splicing
scheme/stxparam)) scheme/stxparam
scheme/local))
@(define splice-eval (make-base-eval)) @(define splice-eval (make-base-eval))
@interaction-eval[#:eval splice-eval (require scheme/splicing @interaction-eval[#:eval splice-eval (require scheme/splicing
@ -13,16 +14,24 @@
@note-lib-only[scheme/splicing] @note-lib-only[scheme/splicing]
@deftogether[( @deftogether[(
@defidform[splicing-let]
@defidform[splicing-letrec]
@defidform[splicing-let-values]
@defidform[splicing-letrec-values]
@defidform[splicing-let-syntax] @defidform[splicing-let-syntax]
@defidform[splicing-letrec-syntax] @defidform[splicing-letrec-syntax]
@defidform[splicing-let-syntaxes] @defidform[splicing-let-syntaxes]
@defidform[splicing-letrec-syntaxes] @defidform[splicing-letrec-syntaxes]
@defidform[splicing-letrec-syntaxes+values]
@defidform[splicing-local]
)]{ )]{
Like @scheme[let-syntax], @scheme[letrec-syntax], Like @scheme[let], @scheme[letrec], @scheme[let-values],
@scheme[let-syntaxes], and @scheme[letrec-syntaxes], except that in a @scheme[letrec-values], @scheme[let-syntax], @scheme[letrec-syntax],
@scheme[let-syntaxes], @scheme[letrec-syntaxes],
@scheme[letrec-syntaxes+values], and @scheme[local], except that in a
definition context, the body forms are spliced into the enclosing definition context, the body forms are spliced into the enclosing
definition context (in the same as as for @scheme[begin]). definition context (in the same way as for @scheme[begin]).
@examples[ @examples[
#:eval splice-eval #:eval splice-eval
@ -30,7 +39,23 @@ definition context (in the same as as for @scheme[begin]).
(define o one)) (define o one))
o o
one one
]} ]
When a splicing binding form occurs in a @tech{top-level context} or
@tech{module context}, its local bindings are treated similarly to
definitions. In particular, if a reference to one of the splicing
form's bound variables is evaluated before the variable is
initialized, an unbound variable error is raised, instead of the
variable evaluating to the undefined value. Also, syntax bindings are
evaluated every time the module is @tech{visit}ed, instead of only
once during compilation as in @scheme[let-syntax], etc.
@examples[
#:eval splice-eval
(splicing-letrec ([x bad]
[bad 1])
x)]
}
@defidform[splicing-syntax-parameterize]{ @defidform[splicing-syntax-parameterize]{

View File

@ -22,15 +22,16 @@ suitable expression context at the @tech{phase level} indicated by
Returns @scheme[#t] if @scheme[a-id] and @scheme[b-id] access the same Returns @scheme[#t] if @scheme[a-id] and @scheme[b-id] access the same
@tech{local binding}, @tech{module binding}, or @tech{top-level @tech{local binding}, @tech{module binding}, or @tech{top-level
binding} at the @tech{phase level} indicated by binding}---perhaps via @tech{rename transformers}---at the @tech{phase
@scheme[phase-level]. A @scheme[#f] value for @scheme[phase-level] level} indicated by @scheme[phase-level]. A @scheme[#f] value for
corresponds to the @tech{label phase level}. @scheme[phase-level] corresponds to the @tech{label phase level}.
``Same module binding'' means that the identifiers refer to the same ``Same module binding'' means that the identifiers refer to the same
original definition site, not necessarily the @scheme[require] or original definition site, and not necessarily to the same
@scheme[provide] site. Due to renaming in @scheme[require] and @scheme[require] or @scheme[provide] site. Due to renaming in
@scheme[provide], the identifiers may return distinct results with @scheme[require] and @scheme[provide], or due to a transformer binding
@scheme[syntax-e].} to a @tech{rename transformer}, the identifiers may return distinct
results with @scheme[syntax-e].}
@defproc[(free-transformer-identifier=? [a-id syntax?][b-id syntax?]) boolean?]{ @defproc[(free-transformer-identifier=? [a-id syntax?][b-id syntax?]) boolean?]{
@ -132,7 +133,13 @@ Returns one of three kinds of values, depending on the binding of
@tech{top-level binding} (or, equivalently, if it is @tech{top-level binding} (or, equivalently, if it is
@tech{unbound}).} @tech{unbound}).}
}} }
If @scheme[id-stx] is bound to a @tech{rename-transformer}, the result
from @scheme[identifier] binding is for the identifier in the
transformer, so that @scheme[identifier-binding] is consistent with
@scheme[free-identifier=?].}
@defproc[(identifier-transformer-binding [id-stx syntax?]) @defproc[(identifier-transformer-binding [id-stx syntax?])
(or/c 'lexical (or/c 'lexical

View File

@ -16,15 +16,22 @@ expander, otherwise the @exnraise[exn:fail:contract].})
@title[#:tag "stxtrans"]{Syntax Transformers} @title[#:tag "stxtrans"]{Syntax Transformers}
@defproc[(set!-transformer? [v any/c]) boolean?]{
Returns @scheme[#t] if @scheme[v] is a value created by
@scheme[make-set!-transformer] or an instance of a structure type with
the @scheme[prop:set!-transformer] property, @scheme[#f] otherwise.}
@defproc[(make-set!-transformer [proc (syntax? . -> . syntax?)]) @defproc[(make-set!-transformer [proc (syntax? . -> . syntax?)])
set!-transformer?]{ set!-transformer?]{
Creates a @tech{syntax transformer} that cooperates with Creates an @tech{assignment transformer} that cooperates with
@scheme[set!]. If the result of @scheme[make-set!-transformer] is @scheme[set!]. If the result of @scheme[make-set!-transformer] is
bound to @scheme[identifier] as a @tech{transformer binding}, then bound to @scheme[_id] as a @tech{transformer binding}, then
@scheme[proc] is applied as a transformer when @scheme[identifier] is @scheme[proc] is applied as a transformer when @scheme[_id] is
used in an expression position, or when it is used as the target of a used in an expression position, or when it is used as the target of a
@scheme[set!] assignment as @scheme[(set! identifier _expr)]. When the @scheme[set!] assignment as @scheme[(set! _id _expr)]. When the
identifier appears as a @scheme[set!] target, the entire @scheme[set!] identifier appears as a @scheme[set!] target, the entire @scheme[set!]
expression is provided to the transformer. expression is provided to the transformer.
@ -45,17 +52,48 @@ expression is provided to the transformer.
]} ]}
@defproc[(set!-transformer? [v any/c]) boolean?]{
Returns @scheme[#t] if @scheme[v] is a value created by
@scheme[make-set!-transformer], @scheme[#f] otherwise.}
@defproc[(set!-transformer-procedure [transformer set!-transformer?]) @defproc[(set!-transformer-procedure [transformer set!-transformer?])
(syntax? . -> . syntax?)]{ (syntax? . -> . syntax?)]{
Returns the procedure that was passed to Returns the procedure that was passed to
@scheme[make-set!-transformer] to create @scheme[transformer].} @scheme[make-set!-transformer] to create @scheme[transformer] or that
is identified by the @scheme[prop:set!-transformer] property of
@scheme[transformer].}
@defthing[prop:set!-transformer struct-type-property?]{
A @tech{structure type property} to indentify structure types that act
as @tech{assignment transformers} like the ones created by
@scheme[make-set!-transformer].
The property value must be an exact integer or procedure of one
argument. In the former case, the integer designates a field within
the structure that should contain a procedure; the integer must be
between @scheme[0] (inclusive) and the number of non-automatic fields
in the structure type (exclusive, not counting supertype fields), and
the designated field must also be specified as immutable.
If the property value is an procedure, then the procedure serves as a
@tech{syntax transformer} and for @scheme[set!] transformations. If
the property value is an integer, the target identifier is extracted
from the structure instance; if the field value is not a procedure of
one argument, then a procedure that always calls
@scheme[raise-syntax-error] is used, instead.
If a value has both the @scheme[prop:set!-transformer] and
@scheme[prop:rename-transformer] properties, then the latter takes
precedence. If a structure type has the @scheme[prop:set!-transformer]
and @scheme[prop:procedure] properties, then the former takes
precedence for the purposes of macro expansion.}
@defproc[(rename-transformer? [v any/c]) boolean?]{
Returns @scheme[#t] if @scheme[v] is a value created by
@scheme[make-rename-transformer] or an instance of a structure type
with the @scheme[prop:rename-transformer] property, @scheme[#f]
otherwise.}
@defproc[(make-rename-transformer [id-stx syntax?] @defproc[(make-rename-transformer [id-stx syntax?]
@ -64,26 +102,55 @@ Returns the procedure that was passed to
rename-transformer?]{ rename-transformer?]{
Creates a @tech{rename transformer} that, when used as a Creates a @tech{rename transformer} that, when used as a
@tech{transformer binding}, acts as a transformer that insert the @tech{transformer binding}, acts as a transformer that inserts the
identifier @scheme[id-stx] in place of whatever identifier binds the identifier @scheme[id-stx] in place of whatever identifier binds the
transformer, including in non-application positions, and in transformer, including in non-application positions, in @scheme[set!]
@scheme[set!] expressions. Such a transformer could be written expressions.
manually, but the one created by @scheme[make-rename-transformer]
cooperates specially with @scheme[syntax-local-value] and Such a transformer could be written manually, but the one created by
@scheme[make-rename-transformer] also causes the parser to install a
@scheme[free-identifier=?] and @scheme[identifier-binding]
equivalence, as long as @scheme[id-stx] does not have a true value for
the @indexed-scheme['not-free-identifier=?] @tech{syntax property}.
Also, if @scheme[id-stx] has a true value for the
@indexed-scheme['not-provide-all-defined] @tech{syntax property} and
it is bound as a module-level transformer, the bound identifier is not
exported by @scheme[all-defined-out]; the @scheme[provide] form
otherwise uses a symbol-valued @indexed-scheme['nominal-id] property
of @scheme[id-stx] to specify the ``nominal source identifier'' of the
binding. Finally, the rename transformer cooperates specially with
@scheme[syntax-local-value] and
@scheme[syntax-local-make-delta-introducer].} @scheme[syntax-local-make-delta-introducer].}
@defproc[(rename-transformer? [v any/c]) boolean?]{
Returns @scheme[#t] if @scheme[v] is a value created by
@scheme[make-rename-transformer], @scheme[#f] otherwise.}
@defproc[(rename-transformer-target [transformer rename-transformer?]) @defproc[(rename-transformer-target [transformer rename-transformer?])
syntax?]{ identifier?]{
Returns the identifier passed to @scheme[make-rename-transformer] to Returns the identifier passed to @scheme[make-rename-transformer] to
create @scheme[transformer].} create @scheme[transformer] or as indicated by a
@scheme[prop:rename-transformer] property on @scheme[transformer].}
@defthing[prop:rename-transformer struct-type-property?]{
A @tech{structure type property} to indentify structure types that act
as @tech{rename transformers} like the ones created by
@scheme[make-rename-transformer].
The property value must be an exact integer or an identifier
@tech{syntax object}. In the former case, the integer designates a
field within the structure that should contain an identifier; the
integer must be between @scheme[0] (inclusive) and the number of
non-automatic fields in the structure type (exclusive, not counting
supertype fields), and the designated field must also be specified as
immutable.
If the property value is an identifier, the identifier serves as the
target for renaming, just like the first argument to
@scheme[make-rename-transformer]. If the property value is an integer,
the target identifier is extracted from the structure instance; if the
field value is not an identifier, then an identifier @schemeidfont{?}
with an empty context is used, instead.}
@defproc[(local-expand [stx syntax?] @defproc[(local-expand [stx syntax?]
@ -307,6 +374,28 @@ being expanded for the body of a module, then resolving
@transform-time[]} @transform-time[]}
@defproc[(syntax-local-value/immediate [id-stx syntax?]
[failure-thunk (or/c (-> any) #f)
#f]
[intdef-ctx (or/c internal-definition-context?
#f)
#f])
any]{
Like @scheme[syntax-local-value], but the result is normally two
values. If @scheme[id-stx] is bound to a @tech{rename transformer},
the results are the rename transformer and the identifier in the
transformer augmented with certificates from @scheme[id-stx]. If
@scheme[id-stx] is not bound to a @tech{rename transformer}, then the
results are the value that @scheme[syntax-local-value] would produce
and @scheme[#f].
If @scheme[id-stx] has no transformer biding, then
@scheme[failure-thunk] is called (and it can return any number of
values), or an exception is raised if @scheme[failure-thunk] is
@scheme[#f].}
@defproc[(syntax-local-lift-expression [stx syntax?]) @defproc[(syntax-local-lift-expression [stx syntax?])
identifier?]{ identifier?]{

View File

@ -531,19 +531,28 @@ is the one left with a mark, and the reference @scheme[x] has no mark,
so the binding @scheme[x] is not @scheme[bound-identifier=?] to the so the binding @scheme[x] is not @scheme[bound-identifier=?] to the
body @scheme[x]. body @scheme[x].
The @scheme[set!] form and the @scheme[make-set!-transformer] The @scheme[set!] form works with the @scheme[make-set!-transformer]
procedure work together to support @deftech{assignment transformers} and @scheme[prop:set!-transformer] property to support
that transformer @scheme[set!] expression. @tech{Assignment @deftech{assignment transformers} that transform @scheme[set!]
transformers} are applied by @scheme[set!] in the same way as a normal expressions. An @tech{assignment transformer} contains a procedure
that is applied by @scheme[set!] in the same way as a normal
transformer by the expander. transformer by the expander.
The @scheme[make-rename-transformer] procedure creates a value that is The @scheme[make-rename-transformer] procedure or
also handled specially by the expander and by @scheme[set!] as a @scheme[prop:rename-transformer] property creates a value that is also
handled specially by the expander and by @scheme[set!] as a
transformer binding's value. When @scheme[_id] is bound to a transformer binding's value. When @scheme[_id] is bound to a
@deftech{rename transformer} produced by @deftech{rename transformer} produced by
@scheme[make-rename-transformer], it is replaced with the identifier @scheme[make-rename-transformer], it is replaced with the target
passed to @scheme[make-rename-transformer]. Furthermore, the binding identifier passed to @scheme[make-rename-transformer]. In addition, as
is also specially handled by @scheme[syntax-local-value] and long as the target identifier does not have a true value for the
@scheme['not-free-identifier=?] @tech{syntax property}, the lexical information that
contains the binding of @scheme[_id] is also enriched so that
@scheme[_id] is @scheme[free-identifier=?] to the target identifier,
@scheme[identifier-binding] returns the same results for both
identifiers, and @scheme[provide] exports @scheme[_id] as the target
identifier. Finally, the binding is treated specially by
@scheme[syntax-local-value], and
@scheme[syntax-local-make-delta-introducer] as used by @tech{syntax @scheme[syntax-local-make-delta-introducer] as used by @tech{syntax
transformer}s. transformer}s.

View File

@ -13,11 +13,13 @@
scheme/package scheme/package
scheme/splicing)) scheme/splicing))
@(define require-eval (make-base-eval))
@(define syntax-eval @(define syntax-eval
(lambda () (lambda ()
(let ([the-eval (make-base-eval)]) (let ([the-eval (make-base-eval)])
(the-eval '(require (for-syntax scheme/base))) (the-eval '(require (for-syntax scheme/base)))
the-eval))) the-eval)))
@(define meta-in-eval (syntax-eval))
@(define cvt (schemefont "CVT")) @(define cvt (schemefont "CVT"))
@(define unquote-id (scheme unquote)) @(define unquote-id (scheme unquote))
@ -202,11 +204,13 @@ be preserved in marshaled bytecode. See also
See also @secref["module-eval-model"] and @secref["mod-parse"]. See also @secref["module-eval-model"] and @secref["mod-parse"].
@defexamples[#:eval (syntax-eval) @defexamples[#:eval (syntax-eval)
(module example-module scheme (module duck scheme/base
(provide foo bar) (provide num-eggs quack)
(define foo 2) (define num-eggs 2)
(define (bar x) (define (quack n)
(+ x 1))) (unless (zero? n)
(printf "quack\n")
(quack (sub1 n)))))
] ]
@defform[(#%module-begin form ...)]{ @defform[(#%module-begin form ...)]{
@ -272,8 +276,8 @@ In a @tech{top-level context}, @scheme[require] instantiates modules
(see @secref["module-eval-model"]). In a @tech{module context}, (see @secref["module-eval-model"]). In a @tech{module context},
@scheme[require] @tech{visits} modules (see @secref["mod-parse"]). In @scheme[require] @tech{visits} modules (see @secref["mod-parse"]). In
both contexts, @scheme[require] introduces bindings into a both contexts, @scheme[require] introduces bindings into a
@tech{namespace} or a module (see @secref["intro-binding"]). A @tech{namespace} or a module (see @secref["intro-binding"]).
@scheme[require] form in a @tech{expression context} or A @scheme[require] form in a @tech{expression context} or
@tech{internal-definition context} is a syntax error. @tech{internal-definition context} is a syntax error.
A @scheme[require-spec] designates a particular set of identifiers to A @scheme[require-spec] designates a particular set of identifiers to
@ -284,8 +288,11 @@ identifier. Each identifier also binds at a particular @tech{phase
level}. level}.
The syntax of @scheme[require-spec] can be extended via The syntax of @scheme[require-spec] can be extended via
@scheme[define-require-syntax], but the @scheme[define-require-syntax], and when multiple
pre-defined forms are as follows. @scheme[require-spec]s are specified in a @scheme[require], the
bindings of each @scheme[require-spec] are visible for expanding later
@scheme[require-spec]s. The pre-defined forms (as exported by
@scheme[scheme/base]) are as follows:
@specsubform[module-path]{ Imports all exported bindings from the @specsubform[module-path]{ Imports all exported bindings from the
named module, using the export identifiers as the local identifiers. named module, using the export identifiers as the local identifiers.
@ -364,56 +371,34 @@ pre-defined forms are as follows.
binding that is not for @scheme[phase-level], where @scheme[#f] for binding that is not for @scheme[phase-level], where @scheme[#f] for
@scheme[phase-level] corresponds to the @tech{label phase level}. @scheme[phase-level] corresponds to the @tech{label phase level}.
This example only imports bindings at @tech{phase level} 1, the The following example imports bindings only at @tech{phase level} 1,
transform phase. the transform phase:
@defexamples[#:eval (syntax-eval) @interaction[#:eval meta-in-eval
(module test scheme (module nest scheme
(provide (for-syntax meta-eggs)
(for-meta 1 meta-chicks)
num-eggs)
(define-for-syntax meta-eggs 2)
(define-for-syntax meta-chicks 3)
(define num-eggs 2))
(provide (for-syntax meta-1a) (require (only-meta-in 1 'nest))
(for-meta 1 meta-1b)
meta-0)
(define-for-syntax meta-1a 'a) (define-syntax (desc stx)
(define-for-syntax meta-1b 'b) (printf "~s ~s\n" meta-eggs meta-chicks)
(define meta-0 2)) #'(void))
(require (only-meta-in 1 'test)) (desc)
num-eggs
(define-syntax bar
(lambda (stx)
(printf "~a\n" meta-1a)
(printf "~a\n" meta-1b)
#'1))
(bar)
meta-0
] ]
This example only imports bindings at @tech{phase level} 0, the The following example imports only bindings at @tech{phase level} 0, the
normal phase. normal phase.
@defexamples[#:eval (syntax-eval) @interaction[#:eval meta-in-eval
(module test scheme (require (only-meta-in 0 'nest))
num-eggs
(provide (for-syntax meta-1a)
(for-meta 1 meta-1b)
meta-0)
(define-for-syntax meta-1a 'a)
(define-for-syntax meta-1b 'b)
(define meta-0 2))
(require (only-meta-in 0 'test))
(define-syntax bar
(lambda (stx)
(printf "~a\n" meta-1a)
(printf "~a\n" meta-1b)
#'1))
meta-0
(bar)
]} ]}
@specsubform[#:literals (for-meta) @specsubform[#:literals (for-meta)
@ -424,23 +409,15 @@ pre-defined forms are as follows.
combination that involves @scheme[#f] produces @scheme[#f]. combination that involves @scheme[#f] produces @scheme[#f].
@defexamples[#:eval (syntax-eval) @defexamples[#:eval (syntax-eval)
(module test scheme (module nest scheme
(provide foo) (provide num-eggs)
(define foo 2)) (define num-eggs 2))
(require (for-meta 0 'test)) (require (for-meta 0 'nest))
foo num-eggs
]} (require (for-meta 1 'nest))
(define-syntax (roost stx)
@defexamples[#:eval (syntax-eval) (datum->syntax stx num-eggs))
(module test scheme (roost)
(provide foo)
(define foo 2))
(require (for-meta 1 'test))
(define-syntax bar
(lambda (stx)
(printf "~a\n" foo)
#'1))
(bar)
]} ]}
@specsubform[#:literals (for-syntax) @specsubform[#:literals (for-syntax)
@ -456,7 +433,8 @@ pre-defined forms are as follows.
@scheme[(for-meta #f require-spec ...)].} @scheme[(for-meta #f require-spec ...)].}
@specsubform[derived-require-spec]{See @scheme[define-require-syntax] @specsubform[derived-require-spec]{See @scheme[define-require-syntax]
for information on expanding the set of @scheme[require-spec] forms.} for information on expanding the set of @scheme[require-spec]
forms.}
@guideintro["module-paths"]{module paths} @guideintro["module-paths"]{module paths}
@ -523,8 +501,8 @@ corresponds to the default @tech{module name resolver}.
@tech{collection}, and @filepath{main.ss} is the library file name. @tech{collection}, and @filepath{main.ss} is the library file name.
Example: require swindle Example: require swindle
@defexamples[#:eval (syntax-eval) @defexamples[#:eval require-eval
(require (lib "swindle"))]} (eval:alts (require (lib "swindle")) (void))]}
@item{If a single @scheme[rel-string] is provided, and if it @item{If a single @scheme[rel-string] is provided, and if it
consists of multiple @litchar{/}-separated elements, then each consists of multiple @litchar{/}-separated elements, then each
@ -533,8 +511,8 @@ corresponds to the default @tech{module name resolver}.
no file suffix, @filepath{.ss} is added. no file suffix, @filepath{.ss} is added.
Example: require a file within the swindle collection Example: require a file within the swindle collection
@defexamples[#:eval (syntax-eval) @defexamples[#:eval require-eval
(require (lib "swindle/turbo"))]} (eval:alts (require (lib "swindle/turbo")) (void))]}
@item{If a single @scheme[rel-string] is provided, and if it @item{If a single @scheme[rel-string] is provided, and if it
consists of a single element @italic{with} a file suffix (i.e, consists of a single element @italic{with} a file suffix (i.e,
@ -543,8 +521,8 @@ corresponds to the default @tech{module name resolver}.
compatibility with older version of PLT Scheme.) compatibility with older version of PLT Scheme.)
Example: require the tar module from mzlib Example: require the tar module from mzlib
@defexamples[#:eval (syntax-eval) @defexamples[#:eval require-eval
(require (lib "tar.ss"))]} (eval:alts (require (lib "tar.ss")) (void))]}
@item{Otherwise, when multiple @scheme[rel-string]s are provided, @item{Otherwise, when multiple @scheme[rel-string]s are provided,
the first @scheme[rel-string] is effectively moved after the the first @scheme[rel-string] is effectively moved after the
@ -555,8 +533,8 @@ corresponds to the default @tech{module name resolver}.
with older version of PLT Scheme.) with older version of PLT Scheme.)
Example: require the tar module from mzlib Example: require the tar module from mzlib
@defexamples[#:eval (syntax-eval) @defexamples[#:eval require-eval
(require (lib "tar.ss" "mzlib"))]} (eval:alts (require (lib "tar.ss" "mzlib")) (void))]}
}} }}
@specsubform[id]{A shorthand for a @scheme[lib] form with a single @specsubform[id]{A shorthand for a @scheme[lib] form with a single
@ -564,14 +542,14 @@ corresponds to the default @tech{module name resolver}.
form of @scheme[id]. In addition to the constraints of a @scheme[lib] form of @scheme[id]. In addition to the constraints of a @scheme[lib]
@scheme[_rel-string], @scheme[id] must not contain @litchar{.}. @scheme[_rel-string], @scheme[id] must not contain @litchar{.}.
@defexamples[#:eval (syntax-eval) @examples[#:eval require-eval
(require scheme/tcp)]} (eval:alts (require scheme/tcp) (void))]}
@defsubform[(file string)]{Similar to the plain @scheme[rel-string] @defsubform[(file string)]{Similar to the plain @scheme[rel-string]
case, but @scheme[string] is a path---possibly absolute---using the case, but @scheme[string] is a path---possibly absolute---using the
current platform's path conventions and @scheme[expand-user-path]. current platform's path conventions and @scheme[expand-user-path].
@scheme[(require (file "~/tmp/x.ss"))]} @examples[(eval:alts (require (file "~/tmp/x.ss")) (void))]}
@defsubform*[((planet id) @defsubform*[((planet id)
(planet string) (planet string)
@ -631,27 +609,22 @@ corresponds to the default @tech{module name resolver}.
identifiers in a minor-version constraint are recognized identifiers in a minor-version constraint are recognized
symbolically. symbolically.
Example: Load main.ss file package foo owned by bar. @examples[
(code:comment #, @t{@filepath{main.ss} in package @filepath{farm} by @filepath{mcdonald}:})
@scheme[(require (planet bar/foo))] (eval:alts (require (planet mcdonald/farm)) (void))
(code:comment #, @t{@filepath{main.ss} in version >= 2.0 of package @filepath{farm} by @filepath{mcdonald}:})
Example: Load major version 2 of main.ss file package foo owned by bar. (eval:alts (require (planet mcdonald/farm:2)) (void))
(code:comment #, @t{@filepath{main.ss} in version >= 2.5 of package @filepath{farm} by @filepath{mcdonald}:})
@scheme[(require (planet bar/foo:2))] (eval:alts (require (planet mcdonald/farm:2:5)) (void))
(code:comment #, @t{@filepath{duck.ss} in version >= 2.5 of package @filepath{farm} by @filepath{mcdonald}:})
Example: Load major version 2 and minor version 5 of main.ss file package foo owned by bar. (eval:alts (require (planet mcdonald/farm:2:5/duck)) (void))
]}
@scheme[(require (planet bar/foo:2:5))]
Example: Load major version 2 and minor version 5 of buz.ss file package foo owned by bar.
@scheme[(require (planet bar/foo:2:5/buz))]}
No identifier can be bound multiple times in a given @tech{phase No identifier can be bound multiple times in a given @tech{phase
level} by an import, unless all of the bindings refer to the same level} by an import, unless all of the bindings refer to the same
original definition in the same module. In a @tech{module context}, original definition in the same module. In a @tech{module context},
an identifier can be either imported or defined for a given an identifier can be either imported or defined for a given
@tech{phase level}, but not both.} @tech{phase level}, but not both.}}
@guideintro["module-provide"]{@scheme[provide]} @guideintro["module-provide"]{@scheme[provide]}
@ -697,29 +670,37 @@ follows.
ambiguous). ambiguous).
@defexamples[#:eval (syntax-eval) @defexamples[#:eval (syntax-eval)
(module test scheme (module nest scheme
(provide foo) (provide num-eggs)
(define foo 2)) (define num-eggs 2))
(require 'test) (require 'nest)
foo num-eggs
]} ]
If @scheme[id] has a transformer binding to a @tech{rename
transformer}, then the exported binding is the target identifier of
the @tech{rename transformer}, instead of @scheme[id], unless the
target identifier has a true value for the
@scheme['not-free-identifier=?] @tech{syntax property}.}
@defsubform[(all-defined-out)]{ Exports all identifiers that are @defsubform[(all-defined-out)]{ Exports all identifiers that are
defined at @tech{phase level} 0 or @tech{phase level} 1 within the defined at @tech{phase level} 0 or @tech{phase level} 1 within the
exporting module, and that have the same lexical context as the exporting module, and that have the same lexical context as the
@scheme[(all-defined-out)] form. The external name for each @scheme[(all-defined-out)] form, excluding bindings to @tech{rename
identifier is the symbolic form of the identifier. Only identifiers transformers} where the target identifier has the
accessible from the lexical context of the @scheme[(all-defined-out)] @scheme['not-provide-all-defined] @tech{syntax property}. The
form are included; that is, macro-introduced imports are not external name for each identifier is the symbolic form of the
re-exported, unless the @scheme[(all-defined-out)] form was identifier. Only identifiers accessible from the lexical context of
introduced at the same time. the @scheme[(all-defined-out)] form are included; that is,
macro-introduced imports are not re-exported, unless the
@scheme[(all-defined-out)] form was introduced at the same time.
@defexamples[#:eval (syntax-eval) @defexamples[#:eval (syntax-eval)
(module test scheme (module nest scheme
(provide (all-defined-out)) (provide (all-defined-out))
(define foo 2)) (define num-eggs 2))
(require 'test) (require 'nest)
foo num-eggs
]} ]}
@defsubform[(all-from-out module-path ...)]{ Exports all identifiers @defsubform[(all-from-out module-path ...)]{ Exports all identifiers
@ -734,14 +715,14 @@ follows.
@scheme[module-path] was introduced at the same time. @scheme[module-path] was introduced at the same time.
@defexamples[#:eval (syntax-eval) @defexamples[#:eval (syntax-eval)
(module a scheme (module nest scheme
(provide foo) (provide num-eggs)
(define foo 2)) (define num-eggs 2))
(module b scheme (module hen-house scheme
(require 'a) (require 'nest)
(provide (all-from-out 'a))) (provide (all-from-out 'nest)))
(require 'b) (require 'hen-house)
foo num-eggs
]} ]}
@defsubform[(rename-out [orig-id export-id] ...)]{ Exports each @defsubform[(rename-out [orig-id export-id] ...)]{ Exports each
@ -750,12 +731,12 @@ follows.
@scheme[export-id] instead @scheme[orig-d]. @scheme[export-id] instead @scheme[orig-d].
@defexamples[#:eval (syntax-eval) @defexamples[#:eval (syntax-eval)
(module a scheme (module nest scheme
(provide (rename-out (foo myfoo))) (provide (rename-out [count num-eggs]))
(define foo 2)) (define count 2))
(require 'a) (require 'nest)
foo num-eggs
myfoo count
]} ]}
@defsubform[(except-out provide-spec provide-spec ...)]{ Like the @defsubform[(except-out provide-spec provide-spec ...)]{ Like the
@ -766,14 +747,14 @@ follows.
@scheme[provide-spec]s is ignored; only the bindings are used. @scheme[provide-spec]s is ignored; only the bindings are used.
@defexamples[#:eval (syntax-eval) @defexamples[#:eval (syntax-eval)
(module a scheme (module nest scheme
(provide (except-out (all-defined-out) (provide (except-out (all-defined-out)
bar)) num-chicks))
(define foo 2) (define num-eggs 2)
(define bar 3)) (define num-chicks 3))
(require 'a) (require 'nest)
foo num-eggs
bar num-chicks
]} ]}
@defsubform[(prefix-out prefix-id provide-spec)]{ @defsubform[(prefix-out prefix-id provide-spec)]{
@ -781,11 +762,11 @@ follows.
@scheme[provide-spec] prefixed with @scheme[prefix-id]. @scheme[provide-spec] prefixed with @scheme[prefix-id].
@defexamples[#:eval (syntax-eval) @defexamples[#:eval (syntax-eval)
(module a scheme (module nest scheme
(provide (prefix-out f: foo)) (provide (prefix-out chicken: num-eggs))
(define foo 2)) (define num-eggs 2))
(require 'a) (require 'nest)
f:foo chicken:num-eggs
]} ]}
@defsubform[(struct-out id)]{Exports the bindings associated with a @defsubform[(struct-out id)]{Exports the bindings associated with a
@ -803,28 +784,24 @@ follows.
included by @scheme[struct-out] for export. included by @scheme[struct-out] for export.
@defexamples[#:eval (syntax-eval) @defexamples[#:eval (syntax-eval)
(module a scheme (module nest scheme
(provide (struct-out foo)) (provide (struct-out egg))
(define-struct foo (a b c))) (define-struct egg (color wt)))
(require 'a) (require 'nest)
make-foo (egg-color (make-egg 'blue 10))
foo-a
foo-b
foo-c
foo?
]} ]}
@defsubform[(combine-out provide-spec ...)]{ The union of the @defsubform[(combine-out provide-spec ...)]{ The union of the
@scheme[provide-spec]s. @scheme[provide-spec]s.
@defexamples[#:eval (syntax-eval) @defexamples[#:eval (syntax-eval)
(module a scheme (module nest scheme
(provide (combine-out foo bar)) (provide (combine-out num-eggs num-chicks))
(define foo 2) (define num-eggs 2)
(define bar 1)) (define num-chicks 1))
(require 'a) (require 'nest)
foo num-eggs
bar num-chicks
]} ]}
@defsubform[(protect-out provide-spec ...)]{ Like the union of the @defsubform[(protect-out provide-spec ...)]{ Like the union of the
@ -832,31 +809,19 @@ follows.
@secref["modprotect"]. The @scheme[provide-spec] must specify only @secref["modprotect"]. The @scheme[provide-spec] must specify only
bindings that are defined within the exporting module. bindings that are defined within the exporting module.
@defexamples[#:eval (syntax-eval) @examples[#:eval (syntax-eval)
(module a scheme (module nest scheme
(provide (protect-out foo)) (provide num-eggs (protect-out num-chicks))
(define foo 1)) (define num-eggs 2)
(define num-chicks 3))
(define weak-inspector (make-inspector (current-code-inspector))) (define weak-inspector (make-inspector (current-code-inspector)))
(define (weak-eval x) (define (weak-eval x)
(parameterize ([current-code-inspector weak-inspector]) (parameterize ([current-code-inspector weak-inspector])
(eval x))) (eval x)))
(require 'a) (require 'nest)
foo (list num-eggs num-chicks)
(weak-eval 'foo) (weak-eval 'num-eggs)
] (weak-eval 'num-chicks)
Note that @scheme[require] works within eval as well.
@defexamples[#:eval (syntax-eval)
(module a scheme
(provide (protect-out foo))
(define foo 1))
(define weak-inspector (make-inspector (current-code-inspector)))
(define (weak-eval x)
(parameterize ([current-code-inspector weak-inspector])
(eval x)))
(weak-eval '(require 'a))
foo
(weak-eval 'foo)
]} ]}
@specsubform[#:literals (for-meta) @specsubform[#:literals (for-meta)
@ -1005,21 +970,7 @@ context of the @scheme[phaseless-spec] form.}
@note-lib-only[scheme/require] @note-lib-only[scheme/require]
The following forms support more complex selection and manipulation of The following forms support more complex selection and manipulation of
sets of imported identifiers. Note that a @scheme[require] form is sets of imported identifiers.
expanded before it is used, which means that requiring the library
itself should be a separate form. For example, use
@schemeblock[
(require scheme/require)
(require (matching-identifiers-in #rx"foo" "foo.ss"))
]
instead of
@schemeblock[
(require scheme/require
(matching-identifiers-in #rx"foo" "foo.ss"))
]
@defform[(matching-identifiers-in regexp require-spec)]{ Like @defform[(matching-identifiers-in regexp require-spec)]{ Like
@scheme[require-spec], but including only imports whose names match @scheme[require-spec], but including only imports whose names match
@ -1047,7 +998,7 @@ instead of
#rx"-" (string-titlecase name) ""))) #rx"-" (string-titlecase name) "")))
scheme/base))] scheme/base))]
will get the @scheme[scheme/base] bindings that match the regexp, will get the @scheme[scheme/base] bindings that match the regexp,
and renamed to use ``camel case''.} and renamed to use ``camel case.''}
@; -------------------- @; --------------------
@ -1489,8 +1440,8 @@ created first and filled with @|undefined-const|, and all
(or (zero? n) (or (zero? n)
(is-odd? (sub1 n))))] (is-odd? (sub1 n))))]
[is-odd? (lambda (n) [is-odd? (lambda (n)
(or (= n 1) (and (not (zero? n))
(is-even? (sub1 n))))]) (is-even? (sub1 n))))])
(is-odd? 11)) (is-odd? 11))
]} ]}
@ -2109,14 +2060,19 @@ Equivalent to @scheme[(when (not test-expr) expr ...)].
@defform[(set! id expr)]{ @defform[(set! id expr)]{
If @scheme[id] has a @tech{transformer binding} to an If @scheme[id] has a @tech{transformer binding} to an @tech{assignment
@tech{assignment transformer}, as produced by transformer}, as produced by @scheme[make-set!-transformer] or as an
@scheme[make-set!-transformer], then this form is expanded by calling instance of a structure type with the @scheme[prop:set!-transformer]
the assignment transformer with the full expressions. If @scheme[id] property, then this form is expanded by calling the assignment
has a @tech{transformer binding} to a @tech{rename transformer} as transformer with the full expressions. If @scheme[id] has a
produced by @scheme[make-rename-transformer], then this form is @tech{transformer binding} to a @tech{rename transformer} as produced
expanded by replacing @scheme[id] with the one provided to by @scheme[make-rename-transformer] or as an instance of a structure
@scheme[make-rename-transformer]. type with the @scheme[prop:rename-transformer] property, then this
form is expanded by replacing @scheme[id] with the target identifier
(e.g., the one provided to @scheme[make-rename-transformer]). If a
transformer binding has both @scheme[prop:set!-transformer] ad
@scheme[prop:rename-transformer] properties, the latter takes
precedence.
Otherwise, evaluates @scheme[expr] and installs the result into the Otherwise, evaluates @scheme[expr] and installs the result into the
location for @scheme[id], which must be bound as a local variable or location for @scheme[id], which must be bound as a local variable or
@ -2344,3 +2300,7 @@ than a precise prose description:
[(nest ([form forms ...] . more) body0 body ...) [(nest ([form forms ...] . more) body0 body ...)
(form forms ... (nest more body0 body ...))])) (form forms ... (nest more body0 body ...))]))
]} ]}
@close-eval[require-eval]
@close-eval[meta-in-eval]

View File

@ -72,12 +72,16 @@ Like @scheme[current-milliseconds], but the result never decreases
(until the machine is turned off).} (until the machine is turned off).}
@defproc[(current-process-milliseconds) exact-integer?]{ @defproc[(current-process-milliseconds [thread (or/c thread? #f)])
exact-integer?]{
Returns the amount of processor time in @tech{fixnum} milliseconds Returns an amount of processor time in @tech{fixnum} milliseconds
that has been consumed by the Scheme process on the underlying that has been consumed by the Scheme process on the underlying
operating system. (Under @|AllUnix|, this includes both user and operating system. (Under @|AllUnix|, this includes both user and
system time.) The precision of the result is platform-specific, and system time.) If @scheme[thread] is @scheme[#f], the reported time
is for all Scheme threads, otherwise the result is specific to the
time while @scheme[thread] ran.
The precision of the result is platform-specific, and
since the result is a @tech{fixnum}, the value increases only over a since the result is a @tech{fixnum}, the value increases only over a
limited (though reasonably long) time.} limited (though reasonably long) time.}

File diff suppressed because it is too large Load Diff

View File

@ -90,7 +90,8 @@ typically used to typeset results.}
When @scheme[to-paragraph] and variants encounter a @scheme[var-id] When @scheme[to-paragraph] and variants encounter a @scheme[var-id]
structure, it is typeset as @scheme[sym] in the variable font, like structure, it is typeset as @scheme[sym] in the variable font, like
@scheme[schemevarfont].} @scheme[schemevarfont]---unless the @scheme[var-id] appears under
quote or quasiquote, in which case @scheme[sym] is typeset as a symbol.}
@defstruct[shaped-parens ([val any/c] @defstruct[shaped-parens ([val any/c]
@ -149,4 +150,5 @@ Provided @scheme[for-syntax]; returns @scheme[#t] if @scheme[v] is an
Provided @scheme[for-syntax]; like @scheme[element-id-transformer] for Provided @scheme[for-syntax]; like @scheme[element-id-transformer] for
a transformer that produces @scheme[sym] typeset as a variable (like a transformer that produces @scheme[sym] typeset as a variable (like
@scheme[schemevarfont]).} @scheme[schemevarfont])---unless it appears under quote or quasiquote,
in which case @scheme[sym] is typeset as a symbol.}

View File

@ -426,7 +426,8 @@ The @scheme[style] can be any of the following:
@item{@scheme['valignment] to a list of symbols and @item{@scheme['valignment] to a list of symbols and
@scheme[#f]s (one for each column); each symbol can be @scheme[#f]s (one for each column); each symbol can be
@scheme['top], @scheme['baseline], or @scheme['bottom].} @scheme['top], @scheme['baseline], @scheme['center],
or @scheme['bottom].}
@item{@scheme['row-styles] to a list of association lists, @item{@scheme['row-styles] to a list of association lists,
one for each row in the table. Each of these nested one for each row in the table. Each of these nested

View File

@ -1,120 +1,211 @@
#lang scheme/base
(module utils scheme/base (require scribble/struct
(require scribble/struct scribble/manual
scribble/manual (prefix-in scheme: scribble/scheme)
(prefix-in scheme: scribble/scheme) (prefix-in scribble: scribble/reader))
(prefix-in scribble: scribble/reader))
(define-syntax bounce-for-label (define-syntax bounce-for-label
(syntax-rules (all-except) (syntax-rules (all-except)
[(_ (all-except mod (id ...) (id2 ...))) [(_ (all-except mod (id ...) (id2 ...)))
(begin (begin (require (for-label (except-in mod id ...)))
(require (for-label (except-in mod id ...))) (provide (for-label (except-out (all-from-out mod) id2 ...))))]
(provide (for-label (except-out (all-from-out mod) id2 ...))))] [(_ mod) (begin (require (for-label mod))
[(_ mod) (begin (provide (for-label (all-from-out mod))))]
(require (for-label mod)) [(_ mod ...) (begin (bounce-for-label mod) ...)]))
(provide (for-label (all-from-out mod))))]
[(_ mod ...) (begin (bounce-for-label mod) ...)]))
(bounce-for-label (all-except scheme (link) ()) (bounce-for-label (all-except scheme (link) ())
scribble/struct scribble/struct
scribble/base-render scribble/base-render
scribble/decode scribble/decode
scribble/manual scribble/manual
scribble/scheme scribble/scheme
scribble/eval scribble/eval
scribble/bnf) scribble/bnf)
(provide scribble-examples litchar/lines) (provide scribble-examples litchar/lines)
(define (litchar/lines . strs) (define (as-flow e)
(let ([strs (regexp-split #rx"\n" (apply string-append strs))]) (make-flow (list (if (block? e) e (make-paragraph (list e))))))
(if (= 1 (length strs))
(litchar (car strs))
(make-table
#f
(map (lambda (s)
(list (make-flow (list (make-paragraph
(if (string=? s "")
'(nbsp) ; needed for IE
(list (litchar s))))))))
strs)))))
(define (as-flow e) (define (litchar/lines . strs)
(make-flow (list (if (block? e) (let ([strs (regexp-split #rx"\n" (apply string-append strs))])
e (if (= 1 (length strs))
(make-paragraph (list e)))))) (litchar (car strs))
(make-table
#f
(map (lambda (s) ; the nbsp is needed for IE
(list (as-flow (if (string=? s "") 'nbsp (litchar s)))))
strs)))))
(define spacer (hspace 2)) (define spacer (hspace 2))
(define ((norm-spacing base) p) (define ((norm-spacing base) p)
(cond (cond [(and (syntax->list p) (not (null? (syntax-e p))))
[(and (syntax->list p) (let loop ([e (syntax->list p)]
(not (null? (syntax-e p)))) [line (syntax-line (car (syntax-e p)))]
(let loop ([e (syntax->list p)] [pos base]
[line (syntax-line (car (syntax-e p)))] [second #f]
[pos base] [accum null])
[second #f] (if (null? e)
[accum null]) (datum->syntax
(cond p (reverse accum)
[(null? e) (list (syntax-source p) (syntax-line p) base (add1 base)
(datum->syntax (- pos base))
p p)
(reverse accum) (let* ([v ((norm-spacing (if (= line (syntax-line (car e)))
(list (syntax-source p) pos
(syntax-line p) (or second pos)))
base (car e))]
(add1 base) [next-pos (+ (syntax-column v) (syntax-span v) 1)])
(- pos base)) (loop (cdr e)
p)] (syntax-line v)
[else next-pos
(let* ([v ((norm-spacing (if (= line (syntax-line (car e))) (or second next-pos)
pos (cons v accum)))))]
(or second pos))) [else (datum->syntax
(car e))] p (syntax-e p)
[next-pos (+ (syntax-column v) (syntax-span v) 1)]) (list (syntax-source p) (syntax-line p) base (add1 base) 1)
(loop (cdr e) p)]))
(syntax-line v)
next-pos
(or second next-pos)
(cons v accum)))]))]
[else
(datum->syntax
p
(syntax-e p)
(list (syntax-source p)
(syntax-line p)
base
(add1 base)
1)
p)]))
(define (scribble-examples . lines) (define (scribble-examples . lines)
(define reads-as (make-paragraph (list spacer "reads as" spacer))) (define reads-as (make-paragraph (list spacer "reads as" spacer)))
(let* ([lines (apply string-append lines)] (let* ([lines (apply string-append lines)]
[p (open-input-string lines)]) [p (open-input-string lines)])
(port-count-lines! p) (port-count-lines! p)
(let loop ([r '()] [newlines? #f]) (let loop ([r '()] [newlines? #f])
(regexp-match? #px#"^[[:space:]]*" p) (regexp-match? #px#"^[[:space:]]*" p)
(let* ([p1 (file-position p)] (let* ([p1 (file-position p)]
[stx (scribble:read-syntax #f p)] [stx (scribble:read-syntax #f p)]
[p2 (file-position p)]) [p2 (file-position p)])
(if (not (eof-object? stx)) (if (not (eof-object? stx))
(let ([str (substring lines p1 p2)]) (let ([str (substring lines p1 p2)])
(loop (cons (list str stx) r) (loop (cons (list str stx) r)
(or newlines? (regexp-match? #rx#"\n" str)))) (or newlines? (regexp-match? #rx#"\n" str))))
(let* ([r (reverse r)] (let* ([r (reverse r)]
[r (if newlines? [r (if newlines?
(cdr (apply append (map (lambda (x) (list #f x)) r))) (cdr (apply append (map (lambda (x) (list #f x)) r)))
r)]) r)])
(make-table (make-table
#f #f
(map (lambda (x) (map (lambda (x)
(let ([@expr (if x (litchar/lines (car x)) "")] (let ([@expr (if x (litchar/lines (car x)) "")]
[sexpr (if x [sexpr (if x
(scheme:to-paragraph (scheme:to-paragraph
((norm-spacing 0) (cadr x))) ((norm-spacing 0) (cadr x)))
"")] "")]
[reads-as (if x reads-as "")]) [reads-as (if x reads-as "")])
(map as-flow (list spacer @expr reads-as sexpr)))) (map as-flow (list spacer @expr reads-as sexpr))))
r))))))))) r))))))))
;; stuff for the preprocessor examples
(require scheme/list (for-syntax scheme/base scheme/list))
(define max-textsample-width 45)
(define (textsample-verbatim-boxes line in-text out-text more)
(define (split str) (regexp-split #rx"\n" str))
(define strs1 (split in-text))
(define strs2 (split out-text))
(define strsm (map (compose split cdr) more))
(define (str->elts str)
(let ([spaces (regexp-match-positions #rx"(?:^| ) +" str)])
(if spaces
(list* (substring str 0 (caar spaces))
(hspace (- (cdar spaces) (caar spaces)))
(str->elts (substring str (cdar spaces))))
(list (make-element 'tt (list str))))))
(define (make-line str)
(if (equal? str "")
;;FIXME: this works in html, but in latex it creates a redundant newline
(list (as-flow (make-element 'newline '())))
(list (as-flow (make-element 'tt (str->elts str))))))
(define (small-attr attr)
(make-with-attributes attr '([style . "font-size: 82%;"])))
(define (make-box strs)
(make-table (small-attr 'boxed) (map make-line strs)))
(define filenames (map car more))
(define indent (let ([d (- max-textsample-width
(for*/fold ([m 0])
([s (in-list (cons strs1 strsm))]
[s (in-list s)])
(max m (string-length s))))])
(if (negative? d)
(error 'textsample-verbatim-boxes
"left box too wide for sample at line ~s" line)
(make-element 'tt (list (hspace d))))))
;; Note: the font-size property is reset for every table, so we need it
;; everywhere there's text, and they don't accumulate for nested tables
(values
(make-table (make-with-attributes
'([alignment right left] [valignment top top])
'())
(cons (list (as-flow (make-table (small-attr #f)
(list (list (as-flow indent)))))
(as-flow (make-box strs1)))
(map (lambda (file strs)
(let* ([file (make-element 'tt (list file ":" 'nbsp))]
[file (list (make-element 'italic (list file)))])
(list (as-flow (make-element '(bg-color 232 232 255) file))
(as-flow (make-box strs)))))
filenames strsm)))
(make-box strs2)))
(define (textsample line in-text out-text more)
(define-values (box1 box2)
(textsample-verbatim-boxes line in-text out-text more))
(make-table '([alignment left left left] [valignment center center center])
(list (map as-flow (list box1 (make-paragraph '(nbsp rarr nbsp)) box2)))))
(define-for-syntax tests-ids #f)
(provide initialize-tests)
(define-syntax (initialize-tests stx)
(set! tests-ids (map (lambda (x) (datum->syntax stx x stx))
'(tests add-to-tests)))
(with-syntax ([(tests add-to-tests) tests-ids])
#'(begin (provide tests)
(define-values (tests add-to-tests)
(let ([l '()])
(values (lambda () (reverse l))
(lambda (x) (set! l (cons x l)))))))))
(provide example)
(define-syntax (example stx)
(define sep-rx #px"^---[*]{3}---(?: +(.*))?$")
(define file-rx #rx"^[a-z0-9_.+-]+$")
(define-values (body hidden?)
(syntax-case stx ()
[(_ #:hidden x ...) (values #'(x ...) #t)]
[(_ x ...) (values #'(x ...) #f)]))
(let loop ([xs body] [text '(#f)] [texts '()])
(syntax-case xs ()
[("\n" sep "\n" . xs)
(and (string? (syntax-e #'sep)) (regexp-match? sep-rx (syntax-e #'sep)))
(let ([m (cond [(regexp-match sep-rx (syntax-e #'sep)) => cadr]
[else #f])])
(if (and m (not (regexp-match? file-rx m)))
(raise-syntax-error #f "bad filename specified" stx #'sep)
(loop #'xs
(list (and m (datum->syntax #'sep m #'sep #'sep)))
(cons (reverse text) texts))))]
[(x . xs) (loop #'xs (cons #'x text) texts)]
[() (let ([texts (reverse (cons (reverse text) texts))]
[line (syntax-line stx)])
(define-values (files i/o) (partition car texts))
(unless ((length i/o) . = . 2)
(raise-syntax-error
'example "need at least an input and an output block" stx))
(with-syntax ([line line]
[((in ...) (out ...)) (map cdr i/o)]
[((file text ...) ...) files]
[add-to-tests (cadr tests-ids)])
(quasisyntax/loc stx
(let* ([in-text (string-append in ...)]
[out-text (string-append out ...)]
[more (list (cons file (string-append text ...)) ...)])
(add-to-tests (list line in-text out-text more))
#,(if hidden? #'""
#'(textsample line in-text out-text more))))))]
[_ (raise-syntax-error #f "no separator found in example text")])))

View File

@ -6,6 +6,7 @@
(require scheme/tcp (require scheme/tcp
scheme/unit scheme/unit
scheme/class scheme/class
scheme/string
mred/mred-sig mred/mred-sig
framework) framework)
@ -133,12 +134,34 @@
;; `body-lines' is a list of strings and byte strings ;; `body-lines' is a list of strings and byte strings
;; `enclosures' is a list of `enclosure' structs ;; `enclosures' is a list of `enclosure' structs
(define (enclose header body-lines enclosures) (define (enclose header body-lines enclosures)
(define qp-body-lines?
(ormap (lambda (l)
(or ((string-length l) . > . 1000)
(regexp-match? #rx"[^\0-\177]" l)))
body-lines))
(define (encode-body-lines)
(if qp-body-lines?
(map
bytes->string/utf-8
(regexp-split #rx"\r\n"
(qp-encode (string->bytes/utf-8
(string-join body-lines "\r\n")))))
body-lines))
(define (add-body-encoding-headers header)
(insert-field
"Content-Type"
"text/plain; charset=UTF-8"
(insert-field
"Content-Transfer-Encoding"
(if qp-body-lines? "quoted-printable" "7bit")
header)))
(if (null? enclosures) (if (null? enclosures)
(values (insert-field (values (insert-field
"Content-Type" "MIME-Version"
"text/plain; charset=UTF-8" "1.0"
header) (add-body-encoding-headers
body-lines) header))
(encode-body-lines))
(let* ([enclosure-datas (let* ([enclosure-datas
(map (lambda (e) ((enclosure-data-thunk e))) enclosures)] (map (lambda (e) ((enclosure-data-thunk e))) enclosures)]
[boundary [boundary
@ -175,27 +198,22 @@
"This is a multi-part message in MIME format." "This is a multi-part message in MIME format."
(format "--~a" boundary)) (format "--~a" boundary))
(header->lines (header->lines
(insert-field (add-body-encoding-headers
"Content-Type" empty-header))
"text/plain; charset=UTF-8" (encode-body-lines)
(insert-field (apply
"Content-Transfer-Encoding" append
"7bit" (map
empty-header))) (lambda (enc data)
body-lines (cons
(apply (format "--~a" boundary)
append (append
(map (header->lines
(lambda (enc data) (enclosure-subheader enc))
(cons data)))
(format "--~a" boundary) enclosures enclosure-datas))
(append (list
(header->lines (format "--~a--" boundary))))))))
(enclosure-subheader enc))
data)))
enclosures enclosure-datas))
(list
(format "--~a--" boundary))))))))
(define (get-enclosure-type-and-encoding filename mailer-frame auto?) (define (get-enclosure-type-and-encoding filename mailer-frame auto?)
(let ([types '("application/postscript" (let ([types '("application/postscript"

View File

@ -39,16 +39,18 @@
"selector.ss" "selector.ss"
"util.ss" "util.ss"
(only-in "fold.ss" reduce-right) (only-in "fold.ss" reduce-right)
(rename-in "fold.ss" [map s:map] [for-each s:for-each])) (rename-in "fold.ss" [map s:map] [for-each s:for-each])
(only-in scheme/list count append*))
(provide length+ (provide length+
concatenate (rename-out [concatenate concatenate!]) (rename-out [append* concatenate] [append* concatenate!])
(rename-out [append append!]) (rename-out [append append!])
(rename-out [reverse reverse!]) (rename-out [reverse reverse!])
append-reverse (rename-out [append-reverse append-reverse!]) append-reverse (rename-out [append-reverse append-reverse!])
zip unzip1 unzip2 unzip3 unzip4 unzip5 zip unzip1 unzip2 unzip3 unzip4 unzip5
count) count)
#; ; reprovided from scheme/list
;; count ;; count
;;;;;;;; ;;;;;;;;
(define (count pred list1 . lists) (define (count pred list1 . lists)
@ -169,6 +171,7 @@
(set-cdr! rev-head tail) (set-cdr! rev-head tail)
(lp next-rev rev-head))))) (lp next-rev rev-head)))))
#; ; reprovide scheme/list's `append*' function
(define (concatenate lists) (reduce-right append '() lists)) (define (concatenate lists) (reduce-right append '() lists))
#; ; lists are immutable #; ; lists are immutable
(define (concatenate! lists) (reduce-right my-append! '() lists)) (define (concatenate! lists) (reduce-right my-append! '() lists))

View File

@ -1,8 +1,14 @@
#lang scheme/base #lang scheme/base
(provide s:read s:write) (define (write-with-shared-structure val [port (current-output-port)] [optarg #f])
(parameterize ([print-graph #t]) (write val port)))
(define (read-with-shared-structure [port (current-input-port)] [optarg #f])
(parameterize ([read-accept-graph #t])
(read port)))
(provide write-with-shared-structure
(rename-out [write-with-shared-structure write/ss])
read-with-shared-structure
(rename-out [read-with-shared-structure read/ss]))
(define (s:write . args)
(parameterize ([print-graph #t]) (apply write args)))
(define (s:read . args)
(parameterize ([read-accept-graph #t]) (apply read args)))

View File

@ -52,7 +52,7 @@
(lambda () (lambda ()
(let* ([source-name (get-source-name editor)] (let* ([source-name (get-source-name editor)]
[port (open-input-text-editor editor 0 'end (xml-snip-filter editor) source-name)] [port (open-input-text-editor editor 0 'end (xml-snip-filter editor) source-name)]
[xml (read-xml port)] [xml (parameterize ([permissive? #t]) (read-xml port))]
[xexpr (parameterize ([permissive? #t]) (xml->xexpr (document-element xml)))] [xexpr (parameterize ([permissive? #t]) (xml->xexpr (document-element xml)))]
[clean-xexpr (if eliminate-whitespace-in-empty-tags? [clean-xexpr (if eliminate-whitespace-in-empty-tags?
(eliminate-whitespace-in-empty-tags xexpr) (eliminate-whitespace-in-empty-tags xexpr)

View File

@ -191,7 +191,8 @@
(cs-status-expanding-expression "Vérificateur de syntaxe : expansion d'une expression") (cs-status-expanding-expression "Vérificateur de syntaxe : expansion d'une expression")
(cs-status-loading-docs-index "Vérificateur de syntaxe : chargement de l'index de la documentation") (cs-status-loading-docs-index "Vérificateur de syntaxe : chargement de l'index de la documentation")
(cs-mouse-over-import "l'identificateur ~s est importé de ~s") (cs-mouse-over-import "l'identificateur ~s est importé de ~s")
(cs-view-docs "Regarder la documentation pour ~a") (cs-view-docs "Documentation pour ~a")
(cs-view-docs-from "~a dans ~a") ;; a completed version of the line above (cs-view-docs) is put into the first ~a and a list of modules (separated by commas) is put into the second ~a. Use check syntax and right-click on a documented variable (eg, 'require') to see this in use
(cs-lexical-variable "variables lexicales") (cs-lexical-variable "variables lexicales")
(cs-imported-variable "variables importées") (cs-imported-variable "variables importées")
@ -200,7 +201,7 @@
(collect-button-label "Ramassage") ; de miettes (collect-button-label "Ramassage") ; de miettes
(read-only "Lecture seulement") (read-only "Lecture seulement")
(auto-extend-selection "Autosélection") ; "Sélection auto-étendable" ? (auto-extend-selection "Autosélection") ; "Sélection auto-étendable" ?
(overwrite "Correction") ; vs Insertion ? surimpression ? (overwrite "Écrasement") ; vs Insertion ? surimpression ?
(running "en cours") (running "en cours")
(not-running "en attente") ; "en attente" ; pause ? (not-running "en attente") ; "en attente" ; pause ?
@ -242,6 +243,11 @@
(erase-log-directory-contents "Effacer le contenu du répertoire d'enregistrement : ~a ?") (erase-log-directory-contents "Effacer le contenu du répertoire d'enregistrement : ~a ?")
(error-erasing-log-directory "Erreur durant l'effacement du contenu du répertoire d'enregistrement.\n\n~a\n") (error-erasing-log-directory "Erreur durant l'effacement du contenu du répertoire d'enregistrement.\n\n~a\n")
;; menu items connected to the logger -- also in a button in the planet status line in the drs frame
(show-log "Montrer le journa&l") ; "journaux" ne contient pas de "l"...
(hide-log "Cacher le journa&l")
(logging-all "Tous") ;; in the logging window in drscheme, shows all logs simultaneously
;; modes ;; modes
(mode-submenu-label "Modes") (mode-submenu-label "Modes")
(scheme-mode "Mode scheme") (scheme-mode "Mode scheme")
@ -676,6 +682,9 @@
(complete-word "Compléter le mot") ; the complete word menu item in the edit menu (complete-word "Compléter le mot") ; the complete word menu item in the edit menu
(no-completions "... pas de complétion connue") ; shows up in the completions menu when there are no completions (in italics) (no-completions "... pas de complétion connue") ; shows up in the completions menu when there are no completions (in italics)
(overwrite-mode "Mode d'écrasement")
(enable-overwrite-mode-keybindings "Raccourci clavier pour le mode d'écrasement")
(preferences-info "Configurer vos préférences.") (preferences-info "Configurer vos préférences.")
(preferences-menu-item "Préférences...") (preferences-menu-item "Préférences...")
@ -707,18 +716,21 @@
(wrap-text-item "Replier le texte") (wrap-text-item "Replier le texte")
;; windows menu
(windows-menu-label "Fe&nêtres") (windows-menu-label "Fe&nêtres")
(minimize "Minimiser") ;; minimize and zoom are only used under mac os x (minimize "Minimiser") ;; minimize and zoom are only used under mac os x
(zoom "Agrandir") ; Zoomer? (zoom "Agrandir") ; Zoomer?
(bring-frame-to-front "Amener une fenêtre au premier plan") ;;; title of dialog (bring-frame-to-front "Amener une fenêtre au premier plan") ;;; title of dialog
(bring-frame-to-front... "Amener une fenêtre au premier plan...") ;;; corresponding title of menu item (bring-frame-to-front... "Amener une fenêtre au premier plan...") ;;; corresponding title of menu item
(most-recent-window "Fenêtre la plus récente") (most-recent-window "Fenêtre la plus récente")
(next-tab "Onglet suivant")
(prev-tab "Onglet précédent")
(view-menu-label "&Montrer") (view-menu-label "&Montrer")
(show-overview "Montrer le contour") (show-overview "Montrer le contour du &programme")
(hide-overview "Cacher le contour") (hide-overview "Cacher le contour du &programme")
(show-module-browser "Montrer le navigateur de modules") (show-module-browser "Montrer le navigateur de &modules")
(hide-module-browser "Cacher le navigateur de modules") (hide-module-browser "Cacher le navigateur de &modules")
(help-menu-label "&Aide") (help-menu-label "&Aide")
(about-info "Auteurs et détails concernant ce logiciel.") (about-info "Auteurs et détails concernant ce logiciel.")
@ -783,7 +795,7 @@
;;; file modified warning ;;; file modified warning
(file-has-been-modified (file-has-been-modified
"Ce fichier a été modifié depuis sa dernière sauvegarde. Voulez-vous écraser les modifications ?") "Ce fichier a été modifié depuis sa dernière sauvegarde. Voulez-vous écraser les modifications ?")
(overwrite-file-button-label "Ecraser") (overwrite-file-button-label "Écraser")
(definitions-modified (definitions-modified
"Le texte de la fenêtre de définition a été modifié directement sur le disque dur. Sauvegardez ou retournez à la version sur le disque.") "Le texte de la fenêtre de définition a été modifié directement sur le disque dur. Sauvegardez ou retournez à la version sur le disque.")
@ -842,7 +854,7 @@
(close-tab "Fermer l'onglet") (close-tab "Fermer l'onglet")
(close-tab-amp "Fermer l'onglet") ;; like close-tab, but with an ampersand on the same letter as the one in close-menu-item (close-tab-amp "Fermer l'onglet") ;; like close-tab, but with an ampersand on the same letter as the one in close-menu-item
;;; edit-menu ;;; edit menu
(split-menu-item-label "Di&viser") (split-menu-item-label "Di&viser")
(collapse-menu-item-label "&Rassembler") (collapse-menu-item-label "&Rassembler")
@ -859,10 +871,10 @@
(force-quit-menu-item-help-string "Utilise custodian-shutdown-all pour terminer toute l'évaluation courante") (force-quit-menu-item-help-string "Utilise custodian-shutdown-all pour terminer toute l'évaluation courante")
(limit-memory-menu-item-label "Limiter la mémoire...") (limit-memory-menu-item-label "Limiter la mémoire...")
(limit-memory-msg-1 "La limite prendra effet à la prochaine exécution du programme.") (limit-memory-msg-1 "La limite prendra effet à la prochaine exécution du programme.")
(limit-memory-msg-2 "Elle doit être d'au moins 1 megaoctet.") (limit-memory-msg-2 "Elle doit être d'au moins un megaoctet.")
(limit-memory-unlimited "Illimitée") (limit-memory-unlimited "Illimitée")
(limit-memory-limited "Limitée") (limit-memory-limited "Limitée à")
(limit-memory-megabytes "Megaoctets") (limit-memory-megabytes "megaoctets")
(clear-error-highlight-menu-item-label "Effacer le surlignage d'erreur") (clear-error-highlight-menu-item-label "Effacer le surlignage d'erreur")
(clear-error-highlight-item-help-string "Efface le surlignage rose après une erreur") (clear-error-highlight-item-help-string "Efface le surlignage rose après une erreur")
(reindent-menu-item-label "&Réindenter") (reindent-menu-item-label "&Réindenter")
@ -996,6 +1008,7 @@
(decimal-notation-for-rationals "Utiliser la notation décimale pour les nombres rationnels") (decimal-notation-for-rationals "Utiliser la notation décimale pour les nombres rationnels")
(enforce-primitives-group-box-label "Définitions initiales") (enforce-primitives-group-box-label "Définitions initiales")
(enforce-primitives-check-box-label "Interdire la redéfinition des définition initiales") (enforce-primitives-check-box-label "Interdire la redéfinition des définition initiales")
(automatically-compile? "Compiler automatiquement les fichiers source ?")
; used in the bottom left of the drscheme frame as the label ; used in the bottom left of the drscheme frame as the label
; used the popup menu from the just above; greyed out and only ; used the popup menu from the just above; greyed out and only
@ -1033,6 +1046,7 @@
(no-language-chosen "Aucun langage sélectionné") (no-language-chosen "Aucun langage sélectionné")
(module-language-one-line-summary "Exécuter crée une fenêtre d'interaction dans le contexte du module, incluant le langage du module lui-même") (module-language-one-line-summary "Exécuter crée une fenêtre d'interaction dans le contexte du module, incluant le langage du module lui-même")
(module-language-auto-text "Ligne #lang automatique") ;; shows up in the details section of the module language
;;; from the `not a language language' used initially in drscheme. ;;; from the `not a language language' used initially in drscheme.
(must-choose-language "DrScheme ne peut pas traiter un programme avant que vous aillez sélectionné un langage.") (must-choose-language "DrScheme ne peut pas traiter un programme avant que vous aillez sélectionné un langage.")
@ -1423,5 +1437,18 @@
(bug-track-forget "Oublier") (bug-track-forget "Oublier")
(bug-track-forget-all "Oublier tous") (bug-track-forget-all "Oublier tous")
;; planet status messages in the bottom of the drscheme window; the ~a is filled with the name of the package
(planet-downloading "PLaneT: téléchargement de ~a...")
(planet-installing "PLaneT: installation de ~a...")
(planet-finished "PLaneT: ~a à jour.")
(planet-no-status "PLaneT") ;; this can happen when there is status shown in a different and then the user switches to a tab where planet hasn't been used
;; string normalization. To see this, paste some text with a ligature into DrScheme
;; the first three strings are in the dialog that appears. The last one is in the preferences dialog
(normalize "Normaliser")
(leave-alone "Ne pas changer")
(normalize-string-info "La chaîne de caractères à coller contient des ligatures ou des caractères non-normalisés. Normaliser la chaîne ?")
(normalize-string-preference "Normaliser les chaînes de caractères durant le collage")
(ask-about-normalizing-strings "Demander à propos de la normalisation des chaînes de caractères")
); "aâàbcçdeéêèëfghiîïjklmnoôpqrstuûùüvwxyz" ); "aâàbcçdeéêèëfghiîïjklmnoôpqrstuûùüvwxyz"

Some files were not shown because too many files have changed in this diff Show More