219 lines
7.7 KiB
Scheme
219 lines
7.7 KiB
Scheme
(module util mzscheme
|
|
(require-for-template mzscheme)
|
|
(require (lib "kerncase.ss" "syntax")
|
|
(lib "list.ss"))
|
|
(provide (all-defined-except template))
|
|
|
|
(define transformer? (make-parameter #f))
|
|
|
|
(define (recertify old-expr expr)
|
|
(syntax-recertify expr old-expr (current-code-inspector) #f))
|
|
|
|
(define (recertify* old-expr exprs)
|
|
(map (lambda (expr)
|
|
(syntax-recertify expr old-expr (current-code-inspector) #f))
|
|
exprs))
|
|
|
|
(define (recertify/new-defs old-expr thunk)
|
|
(call-with-values
|
|
thunk
|
|
(lambda (expr new-defs)
|
|
(values (recertify old-expr expr)
|
|
(recertify* old-expr new-defs)))))
|
|
|
|
(define current-code-labeling
|
|
(make-parameter
|
|
(lambda (stx)
|
|
(datum->syntax-object stx 'error))))
|
|
|
|
(define (generate-formal sym-name)
|
|
(let ([name (datum->syntax-object #f (gensym sym-name))])
|
|
(with-syntax ([(lambda (formal) ref-to-formal)
|
|
(if (syntax-transforming?)
|
|
(local-expand #`(lambda (#,name) #,name) 'expression empty)
|
|
#`(lambda (#,name) #,name))])
|
|
(values #'formal #'ref-to-formal))))
|
|
|
|
(define (formals-list stx)
|
|
(syntax-case stx ()
|
|
[v (identifier? #'v)
|
|
(list #'v)]
|
|
[(v ...)
|
|
(syntax->list #'(v ...))]
|
|
[(v ... . rv)
|
|
(list* #'rv (syntax->list #'(v ...)))]))
|
|
|
|
(define ((make-define-case inner) stx)
|
|
(recertify
|
|
stx
|
|
(syntax-case stx (define-values define-syntaxes define-values-for-syntax)
|
|
[(define-values (v ...) ve)
|
|
(with-syntax ([ve (inner #'ve)])
|
|
(syntax/loc stx
|
|
(define-values (v ...) ve)))]
|
|
[(define-syntaxes (v ...) ve)
|
|
(parameterize ([transformer? #t])
|
|
(with-syntax ([ve (inner #'ve)])
|
|
(syntax/loc stx
|
|
(define-syntaxes (v ...) ve))))]
|
|
[(define-values-for-syntax (v ...) ve)
|
|
(parameterize ([transformer? #t])
|
|
(with-syntax ([ve (inner #'ve)])
|
|
(syntax/loc stx
|
|
(define-values-for-syntax (v ...) ve))))]
|
|
[_
|
|
(raise-syntax-error 'define-case "Dropped through:" stx)])))
|
|
|
|
(define ((make-define-case/new-defs inner) stx)
|
|
(let-values ([(nstx defs) (inner stx)])
|
|
(append defs (list nstx))))
|
|
|
|
(define ((make-module-case/new-defs inner) stx)
|
|
(recertify*
|
|
stx
|
|
(syntax-case* stx (require provide require-for-syntax require-for-template) module-identifier=?
|
|
[(require spec ...)
|
|
(list stx)]
|
|
[(provide spec ...)
|
|
(list stx)]
|
|
[(require-for-syntax spec ...)
|
|
(list stx)]
|
|
[(require-for-template spec ...)
|
|
(list stx)]
|
|
[_
|
|
(inner stx)])))
|
|
|
|
(define ((make-module-case inner) stx)
|
|
(recertify
|
|
stx
|
|
(syntax-case* stx (require provide require-for-syntax require-for-template) module-identifier=?
|
|
[(require spec ...)
|
|
stx]
|
|
[(provide spec ...)
|
|
stx]
|
|
[(require-for-syntax spec ...)
|
|
stx]
|
|
[(require-for-template spec ...)
|
|
stx]
|
|
[_
|
|
(inner stx)])))
|
|
|
|
(define ((make-lang-module-begin make-labeling transform) stx)
|
|
(recertify
|
|
stx
|
|
(syntax-case stx ()
|
|
((mb forms ...)
|
|
(with-syntax ([(pmb rfs0 body ...)
|
|
(local-expand (quasisyntax/loc stx
|
|
(#%plain-module-begin
|
|
#,(syntax-local-introduce #'(require-for-syntax mzscheme))
|
|
forms ...))
|
|
'module-begin
|
|
empty)])
|
|
(let ([base-labeling (make-labeling (string->bytes/utf-8 (format "~a" (syntax-object->datum stx))))])
|
|
(parameterize ([current-code-labeling
|
|
(lambda (stx)
|
|
(datum->syntax-object stx (base-labeling)))])
|
|
(let ([new-defs (apply append (map transform (syntax->list #'(body ...))))])
|
|
(quasisyntax/loc stx
|
|
(pmb rfs0
|
|
#,@new-defs))))))))))
|
|
|
|
(define (bound-identifier-member? id ids)
|
|
(ormap
|
|
(lambda (an-id)
|
|
(bound-identifier=? id an-id))
|
|
ids))
|
|
|
|
;; Kernel Case Template
|
|
(define (template stx)
|
|
(recertify
|
|
stx
|
|
(kernel-syntax-case
|
|
stx (transformer?)
|
|
[(begin be ...)
|
|
(with-syntax ([(be ...) (map template (syntax->list #'(be ...)))])
|
|
(syntax/loc stx
|
|
(begin be ...)))]
|
|
[(begin0 be ...)
|
|
(with-syntax ([(be ...) (map template (syntax->list #'(be ...)))])
|
|
(syntax/loc stx
|
|
(begin0 be ...)))]
|
|
[(define-values (v ...) ve)
|
|
(with-syntax ([ve (template #'ve)])
|
|
(syntax/loc stx
|
|
(define-values (v ...) ve)))]
|
|
[(define-syntaxes (v ...) ve)
|
|
(parameterize ([transformer? #t])
|
|
(with-syntax ([ve (template #'ve)])
|
|
(syntax/loc stx
|
|
(define-syntaxes (v ...) ve))))]
|
|
[(define-values-for-syntax (v ...) ve)
|
|
(parameterize ([transformer? #t])
|
|
(with-syntax ([ve (template #'ve)])
|
|
(syntax/loc stx
|
|
(define-values-for-syntax (v ...) ve))))]
|
|
[(set! v ve)
|
|
(with-syntax ([ve (template #'ve)])
|
|
(syntax/loc stx
|
|
(set! v ve)))]
|
|
[(let-values ([(v ...) ve] ...) be ...)
|
|
(with-syntax ([(ve ...) (map template (syntax->list #'(ve ...)))]
|
|
[(be ...) (map template (syntax->list #'(be ...)))])
|
|
(syntax/loc stx
|
|
(let-values ([(v ...) ve] ...) be ...)))]
|
|
[(letrec-values ([(v ...) ve] ...) be ...)
|
|
(with-syntax ([(ve ...) (map template (syntax->list #'(ve ...)))]
|
|
[(be ...) (map template (syntax->list #'(be ...)))])
|
|
(syntax/loc stx
|
|
(letrec-values ([(v ...) ve] ...) be ...)))]
|
|
[(#%plain-lambda formals be ...)
|
|
(with-syntax ([(be ...) (map template (syntax->list #'(be ...)))])
|
|
(syntax/loc stx
|
|
(#%plain-lambda formals be ...)))]
|
|
[(case-lambda [formals be ...] ...)
|
|
(with-syntax ([((be ...) ...) (map template (syntax->list #'((be ...) ...)))])
|
|
(syntax/loc stx
|
|
(case-lambda [formals be ...] ...)))]
|
|
[(if te ce ae)
|
|
(with-syntax ([te (template #'te)]
|
|
[ce (template #'ce)]
|
|
[ae (template #'ae)])
|
|
(syntax/loc stx
|
|
(if te ce ae)))]
|
|
[(if te ce)
|
|
(template (syntax/loc stx (if te ce (#%plain-app void))))]
|
|
[(quote datum)
|
|
stx]
|
|
[(quote-syntax datum)
|
|
stx]
|
|
[(letrec-syntaxes+values ([(sv ...) se] ...)
|
|
([(vv ...) ve] ...)
|
|
be ...)
|
|
(with-syntax ([(se ...) (map template (syntax->list #'(se ...)))]
|
|
[(ve ...) (map template (syntax->list #'(ve ...)))]
|
|
[(be ...) (map template (syntax->list #'(be ...)))])
|
|
(syntax/loc stx
|
|
(letrec-syntaxes+values ([(sv ...) se] ...)
|
|
([(vv ...) ve] ...)
|
|
be ...)))]
|
|
[(with-continuation-mark ke me be)
|
|
(with-syntax ([ke (template #'ke)]
|
|
[me (template #'me)]
|
|
[be (template #'be)])
|
|
(syntax/loc stx
|
|
(with-continuation-mark ke me be)))]
|
|
[(#%expression . d)
|
|
stx]
|
|
[(#%plain-app e ...)
|
|
(with-syntax ([(e ...) (map template (syntax->list #'(e ...)))])
|
|
(syntax/loc stx
|
|
(#%plain-app e ...)))]
|
|
[(#%top . v)
|
|
stx]
|
|
[(#%variable-reference . v)
|
|
stx]
|
|
[id (identifier? #'id)
|
|
stx]
|
|
[_
|
|
(raise-syntax-error 'kerncase "Dropped through:" stx)])))) |