#lang scheme/base
(require scheme/contract (for-syntax scheme/base))
(provide (all-defined-out))
(define (syntax-map f stx)
(map f (syntax->list stx)))
(define (to-syntax datum
#:stx [stx #f]
#:src [src stx]
#:ctxt [ctxt stx]
#:prop [prop stx]
#:cert [cert stx])
(datum->syntax ctxt datum src prop cert))
(define (to-datum v)
(if (syntax? v)
(syntax->datum v)
v))
(define-syntax (with-syntax* stx)
(syntax-case stx ()
[(ws* (clause . rest) . body)
(syntax/loc stx
(with-syntax (clause) (ws* rest . body)))]
[(ws* () . body)
(syntax/loc stx
(with-syntax () . body))]))
(define current-syntax (make-parameter #f))
(define (syntax-error stx msg . args)
(cond
[(current-syntax) =>
(lambda (stx*)
(raise-syntax-error #f (apply format msg args) stx* stx))]
[else (raise-syntax-error #f (apply format msg args) stx)]))
(define (syntax-datum/c datum)
(let* ([datum/c (coerce-contract datum datum)])
(flat-named-contract (build-compound-type-name 'syntax-datum/c datum/c)
(lambda (v)
(and (syntax? v)
((flat-contract-predicate datum/c)
(syntax->datum v)))))))
(define (syntax-listof/c elem)
(let* ([elem/c (coerce-contract elem elem)])
(flat-named-contract (build-compound-type-name 'syntax-listof/c elem/c)
(lambda (v)
(and (syntax? v)
((flat-contract-predicate (listof elem/c))
(syntax->list v)))))))
(define (syntax-list/c . elems)
(let* ([elem/cs (map (lambda (elem) (coerce-contract elem elem)) elems)])
(flat-named-contract (apply build-compound-type-name 'syntax-list/c elem/cs)
(lambda (v)
(and (syntax? v)
((flat-contract-predicate (apply list/c elem/cs))
(syntax->list v)))))))