46 lines
1.2 KiB
Racket
46 lines
1.2 KiB
Racket
#lang racket/base
|
|
|
|
(require racket/class
|
|
racket/match
|
|
(for-syntax racket/base)
|
|
(for-syntax syntax/parse))
|
|
|
|
(provide match? match*? as object)
|
|
|
|
(define-syntax-rule (match? e p ...)
|
|
(match e [p #t] ... [_ #f]))
|
|
|
|
(define-match-expander as
|
|
(syntax-rules ()
|
|
[(as ([x e] ...) p ...) (and (app (lambda (y) e) x) ... p ...)]))
|
|
|
|
;; Added by asumu
|
|
;; Like match? but with match*
|
|
(define-syntax (match*? stx)
|
|
(syntax-parse stx
|
|
[(_ (e ...) (p ...) ...)
|
|
(with-syntax ([(?_ ...) (generate-temporaries #'(e ...))])
|
|
#'(match* (e ...) [(p ...) #t] ... [(?_ ...) #f]))]))
|
|
|
|
;; Added by asumu
|
|
;; Match expander for objects from racket/class
|
|
(define-match-expander object
|
|
(λ (stx)
|
|
(define-syntax-class field
|
|
#:attributes (name pat)
|
|
(pattern
|
|
((~datum field)
|
|
name
|
|
(~optional pat #:defaults ([pat #'name])))))
|
|
|
|
(syntax-parse stx
|
|
[(object f:field ...)
|
|
#'(and (? object?)
|
|
(and (? (λ (o) (field-bound? f.name o)))
|
|
(app (λ (o) (get-field f.name o))
|
|
f.pat))
|
|
...)]
|
|
[(object class f:field ...)
|
|
#'(and (? (λ (o) (is-a? o class)))
|
|
(object f ...))])))
|