(load-relative "loadtest.ss") (Section 'module-reader) ;; ---------------------------------------- (define (from-string read str) (parameterize ([read-accept-reader #t]) (read (open-input-string str)))) (define (test-both mods str result) (for* ([mod mods] [str (in-value (format str mod))] [read (list read ;; same as `read', but using read-syntax (lambda (in) (syntax->datum (read-syntax #f in))))]) (test result from-string read str))) ;; plain version (module r0 syntax/module-reader scheme/base) (test-both '(r0) "#reader '~s (define FoO #:bAr)" '(module anonymous-module scheme/base (#%module-begin (define FoO #:bAr)))) ;; using a simple wrapper to get a case-insensitive reader (module r1 syntax/module-reader scheme/base #:wrapper1 (lambda (t) (parameterize ([read-case-sensitive #f]) (t)))) ;; using the more general wrapper to get a case-insensitive reader (module r2 syntax/module-reader scheme/base #:wrapper2 (lambda (in r) (parameterize ([read-case-sensitive #f]) (r in)))) ;; using explicit case-insensitive read/-syntax versions (module r3 syntax/module-reader scheme/base #:read (wrap read) #:read-syntax (wrap read-syntax) (define ((wrap reader) . args) (parameterize ([read-case-sensitive #f]) (apply reader args)))) ;; (test-both '(r1 r2 r3) "#reader '~s (define FoO #:bAr)" '(module anonymous-module scheme/base (#%module-begin (define foo #:bar)))) ;; add something to the result (module r4 syntax/module-reader zzz #:wrapper1 (lambda (t) (cons 'foo (t)))) ;; same, but do it properly, if a syntax or a datum is needed (module r5 syntax/module-reader zzz #:wrapper1 (lambda (t stx?) (cons (if stx? #'foo 'foo) (t)))) ;; (test-both '(r4 r5) "#reader '~s (define foo #:bar)" '(module anonymous-module zzz (#%module-begin foo (define foo #:bar)))) ;; make an empty module, after reading the contents (module r6 syntax/module-reader zzz #:wrapper1 (lambda (t) '())) ;; fake input port to get an empty module (module r7 syntax/module-reader zzz #:wrapper2 (lambda (in rd) (rd (open-input-string "")))) ;; forget about the input -- just return a fixed empty input module (module r8 syntax/module-reader whatever #:wrapper2 (lambda (in rd) (if (syntax? (rd in)) #'(module anonymous-module zzz (#%module-begin)) '(module anonymous-module zzz (#%module-begin))))) ;; the same, the easy way (module r9 syntax/module-reader #:language (lambda () 'zzz) #:wrapper1 (lambda (t) '())) ;; (test-both '(r6 r7 r8 r9) "#reader '~s (define foo #:bar)" '(module anonymous-module zzz (#%module-begin))) ;; a module that uses the scribble syntax with a specified language (module r10 syntax/module-reader -ignored- #:wrapper2 (lambda (in rd stx?) (let* ([lang (read in)] [mod (parameterize ([current-readtable (make-at-readtable)]) (rd in))] [mod (if stx? mod (datum->syntax #f mod))] [r (syntax-case mod () [(module name lang* . body) (with-syntax ([lang (datum->syntax #'lang* lang #'lang*)]) (syntax/loc mod (module name lang . body)))])]) (if stx? r (syntax->datum r)))) (require scribble/reader)) ;; same, using #:language (module r11 syntax/module-reader #:language read #:wrapper2 (lambda (in rd stx?) (parameterize ([current-readtable (make-at-readtable)]) (rd in))) (require scribble/reader)) ;; (test-both '(r10 r11) "#reader '~s scheme/base (define foo 1)" '(module anonymous-module scheme/base (#%module-begin (define foo 1)))) (test-both '(r10 r11) "#reader '~s scheme/base @define[foo]{one}" '(module anonymous-module scheme/base (#%module-begin (define foo "one")))) ;; ---------------------------------------- (report-errs)