add #:when to match
This commit is contained in:
parent
1d7cd499c1
commit
f9616959e9
|
@ -717,4 +717,15 @@
|
||||||
(failure-cont)
|
(failure-cont)
|
||||||
0)]
|
0)]
|
||||||
[_ 1]))
|
[_ 1]))
|
||||||
|
|
||||||
|
(comp 0
|
||||||
|
(match (cons 1 2)
|
||||||
|
[(cons a b) #:when (= a b) 1]
|
||||||
|
[_ 0]))
|
||||||
|
|
||||||
|
(comp 1
|
||||||
|
(match (cons 1 1)
|
||||||
|
[(cons a b) #:when (= a b) 1]
|
||||||
|
[_ 0]))
|
||||||
|
|
||||||
))
|
))
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
|
|
||||||
(require "patterns.rkt" "compiler.rkt"
|
(require "patterns.rkt" "compiler.rkt"
|
||||||
syntax/stx syntax/parse
|
syntax/stx syntax/parse racket/syntax
|
||||||
(for-template racket/base (only-in "runtime.rkt" match:error)))
|
(for-template racket/base (only-in "runtime.rkt" match:error fail)))
|
||||||
|
|
||||||
(provide go go/one)
|
(provide go go/one)
|
||||||
|
|
||||||
|
@ -20,62 +20,53 @@
|
||||||
|
|
||||||
;; this parses the clauses using parse, then compiles them
|
;; this parses the clauses using parse, then compiles them
|
||||||
;; go : syntax syntax syntax -> syntax
|
;; go : syntax syntax syntax -> syntax
|
||||||
(define (go parse stx exprs clauses)
|
(define (go parse stx es clauses)
|
||||||
(syntax-case clauses ()
|
(syntax-parse clauses
|
||||||
[([pats . rhs] ...)
|
[([pats . rhs] ...)
|
||||||
(parameterize ([orig-stx stx])
|
(parameterize ([orig-stx stx])
|
||||||
(unless (syntax->list exprs)
|
(unless (syntax->list es)
|
||||||
(raise-syntax-error
|
(raise-syntax-error 'match* "expected a sequence of expressions to match" es)))
|
||||||
'match*
|
(define len (length (syntax->list es)))
|
||||||
"expected a sequence of expressions to match"
|
(define srcloc-list (list #`(quote #,(syntax-source stx))
|
||||||
exprs)))
|
|
||||||
(let ([len (length (syntax->list exprs))]
|
|
||||||
[srcloc-list (list
|
|
||||||
#`(quote #,(syntax-source stx))
|
|
||||||
#`(quote #,(syntax-line stx))
|
#`(quote #,(syntax-line stx))
|
||||||
#`(quote #,(syntax-column stx))
|
#`(quote #,(syntax-column stx))
|
||||||
#`(quote #,(syntax-position stx))
|
#`(quote #,(syntax-position stx))
|
||||||
#`(quote #,(syntax-span stx)))])
|
#`(quote #,(syntax-span stx))))
|
||||||
(with-syntax ([(xs ...) (generate-temporaries exprs)]
|
(define/with-syntax (xs ...) (generate-temporaries es))
|
||||||
[(exprs ...) exprs]
|
(define/with-syntax (exprs ...) es)
|
||||||
[(fail) (generate-temporaries #'(fail))])
|
(define/with-syntax outer-fail (generate-temporary #'fail))
|
||||||
(with-syntax ([body
|
(define/with-syntax orig-expr (if (= 1 len) (stx-car #'(xs ...)) #'(list xs ...)))
|
||||||
(compile*
|
(define/with-syntax raise-error (quasisyntax/loc stx (match:error orig-expr (list (srcloc #,@srcloc-list)))))
|
||||||
(syntax->list #'(xs ...))
|
(define parsed-clauses
|
||||||
(for/list ([clause (syntax->list clauses)]
|
(for/list ([clause (syntax->list clauses)]
|
||||||
[pats (syntax->list #'(pats ...))]
|
[pats (syntax->list #'(pats ...))]
|
||||||
[rhs (syntax->list #'(rhs ...))])
|
[rhs (syntax->list #'(rhs ...))])
|
||||||
(unless (syntax->list pats)
|
(unless (syntax->list pats)
|
||||||
|
(raise-syntax-error 'match* "expected a sequence of patterns" pats))
|
||||||
|
(define lp (length (syntax->list pats)))
|
||||||
|
(unless (= len lp)
|
||||||
(raise-syntax-error
|
(raise-syntax-error
|
||||||
'match*
|
'match (format "wrong number of match clauses, expected ~a and got ~a" len lp) pats))
|
||||||
"expected a sequence of patterns"
|
(define (mk unm rhs)
|
||||||
pats))
|
(make-Row (for/list ([p (syntax->list pats)]) (parse p))
|
||||||
(let ([lp (length (syntax->list pats))])
|
#`(let () . #,rhs) unm null))
|
||||||
(when (null? (syntax->list rhs))
|
(syntax-parse rhs
|
||||||
|
[()
|
||||||
(raise-syntax-error
|
(raise-syntax-error
|
||||||
'match
|
'match
|
||||||
"expected at least one expression on the right-hand side"
|
"expected at least one expression on the right-hand side"
|
||||||
clause))
|
clause)]
|
||||||
(unless (= len lp)
|
[(#:when e)
|
||||||
(raise-syntax-error
|
(raise-syntax-error
|
||||||
'match
|
'match
|
||||||
(format
|
"expected at least one expression on the right-hand side after #:when clause"
|
||||||
"wrong number of match clauses, expected ~a and got ~a"
|
clause)]
|
||||||
len lp)
|
[(#:when e rest ...) (mk #f #'((if e (let () rest ...) (fail))))]
|
||||||
pats))
|
[(((~datum =>) unm) . rhs) (mk #'unm #'rhs)]
|
||||||
(let ([mk (lambda (unm rhs)
|
[_ (mk #f rhs)])))
|
||||||
(make-Row (for/list ([p (syntax->list pats)])
|
(define/with-syntax body
|
||||||
(parse p))
|
(compile* (syntax->list #'(xs ...)) parsed-clauses #'outer-fail))
|
||||||
#`(let-values () . #,rhs) unm null))])
|
|
||||||
(syntax-case* rhs (=>)
|
|
||||||
(lambda (x y) (eq? (syntax-e x) (syntax-e y)))
|
|
||||||
[((=> unm) . rhs) (mk #'unm #'rhs)]
|
|
||||||
[_ (mk #f rhs)]))))
|
|
||||||
#'fail)]
|
|
||||||
[orig-expr
|
|
||||||
(if (= 1 len) (stx-car #'(xs ...)) #'(list xs ...))])
|
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(let ([xs exprs] ...)
|
(let ([xs exprs] ...)
|
||||||
(let ([fail (lambda ()
|
(define (outer-fail) raise-error)
|
||||||
#,(quasisyntax/loc stx (match:error orig-expr (list (srcloc #,@srcloc-list)))))])
|
body))]))
|
||||||
body))))))]))
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user