Use unstable/lazy-require to dynamically-load the compile-time of match.

This commit is contained in:
Sam Tobin-Hochstadt 2012-07-14 18:25:11 -04:00
parent b987be068e
commit 8358420fcc
6 changed files with 74 additions and 63 deletions

View File

@ -5,8 +5,11 @@
(only-in racket/list append* remove-duplicates) (only-in racket/list append* remove-duplicates)
unstable/sequence unstable/sequence
syntax/parse syntax/parse
"patterns.rkt" unstable/lazy-require))
"gen-match.rkt"))
(begin-for-syntax
(lazy-require [racket/match/patterns (bound-vars)]
[racket/match/gen-match (go parse-id go/one)]))
(provide define-forms) (provide define-forms)

View File

@ -1,10 +1,26 @@
#lang racket/base #lang racket/base
(require (for-syntax racket/base (require (for-syntax racket/base "stxtime.rkt"))
"patterns.rkt"))
(provide define-match-expander) (provide define-match-expander)
(begin-for-syntax
(define make-match-expander
(let ()
(define-struct match-expander (match-xform legacy-xform macro-xform)
#:property prop:set!-transformer
(λ (me stx)
(define xf (match-expander-macro-xform me))
(if (set!-transformer? xf)
((set!-transformer-procedure xf) stx)
(syntax-case stx (set!)
[(set! . _)
(raise-syntax-error #f "cannot mutate syntax identifier" stx)]
[_ (xf stx)])))
#:property prop:match-expander (struct-field-index match-xform)
#:property prop:legacy-match-expander (struct-field-index legacy-xform))
(values make-match-expander))))
(define-syntax (define-match-expander stx) (define-syntax (define-match-expander stx)
(define (lookup v alist) (define (lookup v alist)
(cond [(assoc v alist) => cadr] (cond [(assoc v alist) => cadr]

View File

@ -6,11 +6,15 @@
(only-in "match-expander.rkt" (only-in "match-expander.rkt"
define-match-expander) define-match-expander)
"define-forms.rkt" "define-forms.rkt"
"struct.rkt" "struct.rkt"
(for-syntax "parse.rkt" (for-syntax unstable/lazy-require
(only-in "patterns.rkt" (only-in "stxtime.rkt"
match-...-nesting match-...-nesting
prop:match-expander prop:legacy-match-expander))) prop:match-expander
prop:legacy-match-expander)))
(begin-for-syntax
(lazy-require [racket/match/parse (parse)]))
(provide (for-syntax match-...-nesting (provide (for-syntax match-...-nesting
prop:match-expander prop:legacy-match-expander) prop:match-expander prop:legacy-match-expander)
@ -22,4 +26,5 @@
(define-forms parse (define-forms parse
match match* match-lambda match-lambda* match-lambda** match-let match-let* match match* match-lambda match-lambda* match-lambda** match-let match-let*
match-let-values match-let*-values match-let-values match-let*-values
match-define match-define-values match-letrec match/values match/derived match*/derived) match-define match-define-values match-letrec match/values
match/derived match*/derived)

View File

@ -2,9 +2,12 @@
(require syntax/boundmap (require syntax/boundmap
racket/contract racket/contract
"stxtime.rkt"
(for-syntax racket/base)) (for-syntax racket/base))
(provide (except-out (all-defined-out) (provide (except-out (combine-out
(all-defined-out)
(all-from-out "stxtime.rkt"))
struct-key-ht struct-key-ht
get-key get-key
(struct-out Row))) (struct-out Row)))
@ -176,8 +179,6 @@
[(Exact? p) null] [(Exact? p) null]
[else (error 'match "bad pattern: ~a" p)])) [else (error 'match "bad pattern: ~a" p)]))
(define match-...-nesting (make-parameter 0))
(define current-renaming (make-parameter (make-free-identifier-mapping))) (define current-renaming (make-parameter (make-free-identifier-mapping)))
(define (copy-mapping ht) (define (copy-mapping ht)
@ -208,45 +209,3 @@
[vars-seen (listof (cons/c identifier? [vars-seen (listof (cons/c identifier?
identifier?))]))) identifier?))])))
(struct acc-prop (n acc))
(define (make-struct-type-property/accessor name [guard #f] [supers null])
(define-values (p pred? acc)
(make-struct-type-property name
(λ (pval sinfo)
(cond [(exact-nonnegative-integer? pval)
(acc-prop pval (cadddr sinfo))]
[else (if (procedure? guard)
(guard pval sinfo)
pval)]))
supers))
(values p pred? (lambda (v)
(define v* (acc v))
(if (acc-prop? v*)
((acc-prop-acc v*) v (acc-prop-n v*))
v*))))
(define-values (prop:match-expander match-expander? match-expander-proc)
(make-struct-type-property/accessor 'prop:match-expander))
(define-values (prop:legacy-match-expander legacy-match-expander? legacy-match-expander-proc)
(make-struct-type-property/accessor 'prop:legacy-match-expander ))
(define make-match-expander
(let ()
(define-struct match-expander (match-xform legacy-xform macro-xform)
#:property prop:set!-transformer (lambda (me stx)
(define xf (match-expander-macro-xform me))
(if (set!-transformer? xf)
((set!-transformer-procedure xf) stx)
(syntax-case stx (set!)
[(set! . _)
(raise-syntax-error #f "cannot mutate syntax identifier" stx)]
[_ (xf stx)])))
#:property prop:match-expander (struct-field-index match-xform)
#:property prop:legacy-match-expander (struct-field-index legacy-xform))
(values make-match-expander)))
(provide match-expander? legacy-match-expander?
match-expander-proc legacy-match-expander-proc
prop:match-expander prop:legacy-match-expander)

View File

@ -2,7 +2,7 @@
(require racket/match/match-expander (require racket/match/match-expander
(for-syntax racket/base (for-syntax racket/base
racket/struct-info racket/struct-info
syntax/boundmap syntax/id-table
racket/list)) racket/list))
(define-match-expander (define-match-expander
@ -17,7 +17,7 @@
[v (if (identifier? #'struct-name) [v (if (identifier? #'struct-name)
(syntax-local-value #'struct-name fail) (syntax-local-value #'struct-name fail)
(fail))] (fail))]
[field-acc->pattern (make-free-identifier-mapping)]) [field-acc->pattern (make-free-id-table)])
(unless (struct-info? v) (fail)) (unless (struct-info? v) (fail))
; Check each pattern and capture the field-accessor name ; Check each pattern and capture the field-accessor name
(for-each (lambda (an) (for-each (lambda (an)
@ -34,9 +34,9 @@
(syntax-e #'struct-name) (syntax-e #'struct-name)
(syntax-e #'field))) (syntax-e #'field)))
#'field)]) #'field)])
(when (free-identifier-mapping-get field-acc->pattern field-acc (lambda () #f)) (when (free-id-table-ref field-acc->pattern field-acc #f)
(raise-syntax-error 'struct* "Field name appears twice" stx #'field)) (raise-syntax-error 'struct* "Field name appears twice" stx #'field))
(free-identifier-mapping-put! field-acc->pattern field-acc #'pat))] (free-id-table-set! field-acc->pattern field-acc #'pat))]
[_ [_
(raise-syntax-error (raise-syntax-error
'struct* "expected a field pattern of the form (<field-id> <pat>)" 'struct* "expected a field pattern of the form (<field-id> <pat>)"
@ -54,14 +54,13 @@
[pats-in-order [pats-in-order
(for/list ([field-acc (in-list acc)]) (for/list ([field-acc (in-list acc)])
(begin0 (begin0
(free-identifier-mapping-get (free-id-table-ref
field-acc->pattern field-acc field-acc->pattern field-acc
(lambda () (syntax/loc stx _))) (syntax/loc stx _))
; Use up pattern ; Use up pattern
(free-identifier-mapping-put! (free-id-table-remove! field-acc->pattern field-acc)))])
field-acc->pattern field-acc #f)))])
; Check that all patterns were used ; Check that all patterns were used
(free-identifier-mapping-for-each (free-id-table-for-each
field-acc->pattern field-acc->pattern
(lambda (field-acc pat) (lambda (field-acc pat)
(when pat (when pat

View File

@ -0,0 +1,29 @@
#lang racket/base
(provide (all-defined-out))
(define match-...-nesting (make-parameter 0))
(struct acc-prop (n acc))
(define (make-struct-type-property/accessor name [guard #f] [supers null])
(define-values (p pred? acc)
(make-struct-type-property name
(λ (pval sinfo)
(cond [(exact-nonnegative-integer? pval)
(acc-prop pval (cadddr sinfo))]
[else (if (procedure? guard)
(guard pval sinfo)
pval)]))
supers))
(values p pred? (lambda (v)
(define v* (acc v))
(if (acc-prop? v*)
((acc-prop-acc v*) v (acc-prop-n v*))
v*))))
(define-values (prop:match-expander match-expander? match-expander-proc)
(make-struct-type-property/accessor 'prop:match-expander))
(define-values (prop:legacy-match-expander legacy-match-expander? legacy-match-expander-proc)
(make-struct-type-property/accessor 'prop:legacy-match-expander ))