#lang scheme/base
(require (for-syntax scheme/base
"expander-internal.ss")
"../base.ss"
"expander-internal.ss")
(define-syntax (define-xml-syntax stx)
(syntax-case stx ()
[(_ (id arg ...) expansion)
#'(define-xml-syntax id
(lambda (stx)
(syntax-case stx ()
[(id arg ...)
(syntax/loc stx expansion)])))]
[(_ id xml-xform)
#'(define-xml-syntax id
xml-xform
(lambda (stx)
(raise-syntax-error
#f "must be used as an xml expression" stx)))]
[(_ id xml-xform expr-xform)
(quasisyntax/loc stx
(define-syntax id
(make-xml-expander
xml-xform
#,(if (identifier? #'expr-xform)
#'(lambda (stx)
(syntax-case stx (set!)
[(_ args (... ...)) #'(expr-xform args (... ...))]
[_ #'expr-xform]))
#'expr-xform)
(syntax-local-certifier))))]))
(define (xml-expander-syntax? stx)
(and (identifier? stx)
(xml-expander? (syntax-local-value stx (lambda () #f)))))
(define (xml-expand stx)
(syntax-case stx ()
[(id arg ...)
(let* ([expander (syntax-local-value #'id)]
[xml-xform (and expander (xml-expander-xml-xform expander))])
(if (and expander xml-xform)
(xml-xform stx)
(raise-syntax-error #f "not an xml expander" stx #'id)))]))
(provide define-xml-syntax)
(provide/contract
[xml-expander-syntax? (-> syntax? boolean?)]
[xml-expand (-> syntax? syntax?)])