diff --git a/collects/scheme/match/compiler.ss b/collects/scheme/match/compiler.ss index 6c63bd8341..aca476793a 100644 --- a/collects/scheme/match/compiler.ss +++ b/collects/scheme/match/compiler.ss @@ -403,35 +403,38 @@ (if (stx-null? clauses) body (quasisyntax (let* #,clauses #,body)))) - (if (null? vars) + (cond + ;; if there are no rows, then just call the esc continuation + [(null? rows) #`(#,esc)] ;; if we have no variables, there are no more patterns to match ;; so we just pick the first RHS + [(null? vars) (let ([fns (let loop ([blocks (reverse rows)] [esc esc] [acc null]) (if (null? blocks) - ;; if we're done, return the blocks - (reverse acc) - (with-syntax - (;; f is the name this block will have - [(f) (generate-temporaries #'(f))] - ;; compile the block, with jumps to the previous esc - [c (with-syntax ([rhs #`(syntax-parameterize - ([fail (make-rename-transformer - (quote-syntax #,esc))]) - #,(Row-rhs (car blocks)))]) - (if (Row-unmatch (car blocks)) - #`(let/ec k - (let ([#,(Row-unmatch (car blocks)) - (lambda () (k (#,esc)))]) - rhs)) - #'rhs))]) - ;; then compile the rest, with our name as the esc - (loop (cdr blocks) #'f (cons #'[f (lambda () c)] acc)))))]) + ;; if we're done, return the blocks + (reverse acc) + (with-syntax + (;; f is the name this block will have + [(f) (generate-temporaries #'(f))] + ;; compile the block, with jumps to the previous esc + [c (with-syntax ([rhs #`(syntax-parameterize + ([fail (make-rename-transformer + (quote-syntax #,esc))]) + #,(Row-rhs (car blocks)))]) + (if (Row-unmatch (car blocks)) + #`(let/ec k + (let ([#,(Row-unmatch (car blocks)) + (lambda () (k (#,esc)))]) + rhs)) + #'rhs))]) + ;; then compile the rest, with our name as the esc + (loop (cdr blocks) #'f (cons #'[f (lambda () c)] acc)))))]) (with-syntax ([(fns ... [_ (lambda () body)]) fns]) - (let/wrap #'(fns ...) #'body))) - + (let/wrap #'(fns ...) #'body)))] ;; otherwise, we split the matrix into blocks ;; and compile each block with a reference to its continuation + [else (let*-values ([(rows vars) (reorder-columns rows vars)] [(fns) @@ -452,7 +455,7 @@ 'typechecker:called-in-tail-position #t)] acc)))))]) (with-syntax ([(fns ... [_ (lambda () body)]) fns]) - (let/wrap #'(fns ...) #'body))))) + (let/wrap #'(fns ...) #'body)))])) ;; (require mzlib/trace) ;; (trace compile* compile-one) diff --git a/collects/scheme/match/parse-helper.ss b/collects/scheme/match/parse-helper.ss index fa51b1269f..4c43210164 100644 --- a/collects/scheme/match/parse-helper.ss +++ b/collects/scheme/match/parse-helper.ss @@ -32,11 +32,13 @@ (parse (syntax/loc stx (quote b))))] [(quote vec) (vector? (syntax-e #'vec)) - (make-Vector (for/list ([e (vector->list (syntax-e #'vec))]) + (make-Vector (for/list ([e (syntax-e #'vec)]) (parse (quasisyntax/loc stx (quote #,e)))))] - [(quote vec) - (vector? (syntax-e #'vec)) - (make-Box (parse (quasisyntax/loc stx (quote #,(syntax-e #'vec)))))] + [(quote bx) + (box? (syntax-e #'bx)) + (make-Box (parse (quasisyntax/loc + stx + (quote #,(unbox (syntax-e #'bx))))))] [(quote v) (or (parse-literal (syntax-e #'v)) (raise-syntax-error 'match "non-literal in quote pattern" stx #'v))] diff --git a/collects/tests/match/examples.ss b/collects/tests/match/examples.ss index d89dd0e249..23af910c9d 100644 --- a/collects/tests/match/examples.ss +++ b/collects/tests/match/examples.ss @@ -516,10 +516,24 @@ [(mcons a b) (+ a b)] [_ 'no])) + (comp 1 + (match (box 'x) ('#&x 1) (else #f))) + + (comp 2 + (match (vector 1 2) ('#(1 2) 2) (else #f))) + + (comp 'yes + (with-handlers ([exn:fail? (lambda _ 'yes)] + [values (lambda _ 'no)]) + (match 1) + 'no)) + ;; raises error (comp 'yes (with-handlers ([exn:fail:syntax? (lambda _ 'yes)]) (expand (quote-syntax (match '(1 x 2 y 3 z) [(list-no-order 1 2 3 rest ... e) rest] [_ 'no]))) 'no)) + + )) \ No newline at end of file