(module record-case mzscheme
(provide record-case record-case*)
(require-for-syntax "private/check-syntax.ss")
(define-syntax record-case
(lambda (stx)
(with-syntax (((_ . args) stx))
(syntax-case stx (else)
((_ exp
(symbol0 formals0 exp00 exp01 ...)
(symbol1 formals1 exp10 exp11 ...)
...
(else exp0 exp1 ...))
(and (check-symbols (syntax (symbol0 symbol1 ...)))
(check-formals (syntax (formals0 formals1 ...))))
(syntax (record-case* . args)))
((_ exp
(symbol0 formals0 exp00 exp01 ...)
(symbol1 formals1 exp10 exp11 ...) ...)
(and (check-symbols (syntax (symbol0 symbol1 ...)))
(check-formals (syntax (formals0 formals1 ...))))
(syntax (record-case* . args)))))))
(define-syntax record-case*
(syntax-rules ()
((record-case* e clause ...)
(let ((x e))
(letrec-syntax
((record-case/accum
(syntax-rules (else)
((record-case/accum accum)
(case (car x) . accum))
((record-case/accum (accum (... ...)) (else . body))
(record-case/accum (accum (... ...) (else . body))))
((record-case/accum accum (symbol formals . body) . clauses)
(record-case/accum (((symbol)
(list-bind formals (cdr x) (let () . body)))
. accum) . clauses))))
(list-bind
(syntax-rules ()
((list-bind () list body) body)
((list-bind (x . rest) list body)
(let ((x (car list))
(y (cdr list)))
(list-bind rest y body)))
((list-bind x list body)
(let ((x list))
body)))))
(record-case/accum () clause ...))))))
)