#lang racket/base (require (for-template racket/base) racket/list racket/contract) (provide/contract [transformer? (parameter/c boolean?)] [recertify (syntax? syntax? . -> . syntax?)] [current-code-labeling (parameter/c (syntax? . -> . syntax?))] [generate-formal ((symbol?) ((or/c false/c syntax?)) . ->* . (values syntax? syntax?))] [formals-list (syntax? . -> . (listof syntax?))] [make-define-case ((syntax? . -> . syntax?) . -> . (syntax? . -> . syntax?))] [make-module-case ((syntax? . -> . syntax?) . -> . (syntax? . -> . syntax?))] [make-lang-module-begin ((bytes? . -> . (-> symbol?)) (syntax? . -> . syntax?) . -> . (syntax? . -> . syntax?))] [bound-identifier-member? (syntax? (listof syntax?) . -> . boolean?)]) (define transformer? (make-parameter #f)) (define (recertify old-expr expr) (syntax-recertify expr old-expr (current-code-inspector) #f)) (define current-code-labeling (make-parameter (lambda (stx) (datum->syntax stx 'error)))) (define (generate-formal sym-name [stx-base #f]) (let ([name (datum->syntax stx-base (gensym sym-name))]) (with-syntax ([(#%plain-lambda (formal) ref-to-formal) (if (syntax-transforming?) (local-expand #`(#%plain-lambda (#,name) #,name) 'expression empty) #`(#%plain-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) (let-values ([(nve) (inner #'ve)]) (quasisyntax/loc stx (define-values (v ...) #,nve)))] [(define-syntaxes (v ...) ve) stx] [(define-values-for-syntax (v ...) ve) stx] [(#%require spec ...) stx] [expr (inner #'expr)]))) (define ((make-module-case inner) stx) (recertify stx (syntax-case* stx (#%provide) free-identifier=? [(#%provide spec ...) stx] [_ (inner stx)]))) (define ((make-lang-module-begin make-labeling transform) stx) (recertify stx (syntax-case stx () [(mb forms ...) (with-syntax ([(pmb body ...) (local-expand (quasisyntax/loc stx (#%module-begin (require web-server/lang/lang-api) forms ...)) 'module-begin empty)]) (define base-labeling (make-labeling (string->bytes/utf-8 (format "~a" (syntax->datum stx))))) (define new-defs (parameterize ([current-code-labeling (lambda (stx) (datum->syntax stx (base-labeling)))]) (map transform (syntax->list #'(body ...))))) (quasisyntax/loc stx (pmb #,@new-defs)))]))) (define (bound-identifier-member? id ids) (ormap (lambda (an-id) (bound-identifier=? id an-id)) ids))