Compare commits

..

6 Commits

Author SHA1 Message Date
Georges Dupéron
6d3b418750 Fixed documentation: expand-all-expanders-of-type should be expand-syntax-tree-with-expanders-of-type 2016-09-19 17:37:05 +02:00
Georges Dupéron
8f836d6c16 Use with-disappeared-uses to make DrRacket draw arrows from expander definitions to their uses. 2016-08-31 01:04:32 +02:00
Georges Dupéron
f0fcc2b169 Make ?-expander? allow any value, so that (~var exp (static foo-expander? "a foo expander")) can safely be used with syntax-parse. 2016-08-30 12:39:14 +02:00
Jack Firth
8e501ebeb6 Merge pull request #8 from jsmaniac/fix-use-site-scope
Remove the extra use-site scope on the body of define-?-expander.
2016-08-25 13:05:19 -07:00
Jack Firth
fa35d7b777 Merge pull request #10 from jsmaniac/allow-arbitrary-expander-parameters
Allow arbitrary expander parameters, like (some-foo-expander x y . z).
2016-08-25 11:51:27 -07:00
Georges Dupéron
6f05f1ec92 Allow arbitrary expander parameters, like (some-foo-expander x y . z). 2016-08-25 15:56:41 +02:00
6 changed files with 109 additions and 12 deletions

View File

@ -27,7 +27,8 @@
(define-for-syntax (make-?-expander transformer) (define-for-syntax (make-?-expander transformer)
(expander ?-expander-type transformer)) (expander ?-expander-type transformer))
(define-for-syntax (?-expander? v) (define-for-syntax (?-expander? v)
(expander-of-type? ?-expander-type v)) (and (expander? v)
(expander-of-type? ?-expander-type v)))
(define-syntax define-?-expander (define-syntax define-?-expander
(syntax-parser (syntax-parser
[(_ expander-name:id transformer:expr) [(_ expander-name:id transformer:expr)

View File

@ -23,6 +23,7 @@ expanders for use with other macros.
environment} environment}
@item{@code{expand-all-id-expanders} - a procedure bound at phase @item{@code{expand-all-id-expanders} - a procedure bound at phase
@; TODO: expand-all-expanders-of-type is not documented @; TODO: expand-all-expanders-of-type is not documented
level 1 that's equivalent to @racket[expand-all-expanders-of-type] with level 1 that's equivalent to
the @code{id-expander-type} as the type argument} @racket[expand-syntax-tree-with-expanders-of-type] with the
@code{id-expander-type} as the type argument}
]} ]}

View File

@ -4,16 +4,14 @@
syntax/parse syntax/parse
syntax/stx syntax/stx
predicates predicates
fancy-app) fancy-app
racket/syntax)
(provide (struct-out expander) (provide (struct-out expander)
(contract-out (contract-out
[expander-of-type? (-> expander-type? expander? boolean?)] [expander-of-type? (-> expander-type? expander? boolean?)]
[expand-syntax-tree-with-expanders-of-type (-> expander-type? syntax? syntax?)])) [expand-syntax-tree-with-expanders-of-type (-> expander-type? syntax? syntax?)]))
(define (maybe-syntax-local-value stx)
(syntax-local-value stx (λ () #f)))
(struct expander (type transformer)) (struct expander (type transformer))
(define (expander-of-type? type expander) (define (expander-of-type? type expander)
@ -22,12 +20,12 @@
(define (expander-stx? v) (define (expander-stx? v)
(and (syntax? v) (and (syntax? v)
(syntax-parse v (syntax-parse v
[(id:id _ ...) (expander? (maybe-syntax-local-value #'id))] [(id:id . _) (syntax-local-value/record #'id expander?)]
[_ #f]))) [_ #f])))
(define (expander-stx->expander expander-stx) (define (expander-stx->expander expander-stx)
(syntax-parse expander-stx (syntax-parse expander-stx
[(id:id _ ...) (maybe-syntax-local-value #'id)])) [(id:id . _) (syntax-local-value/record #'id expander?)]))
(define (expander-stx-of-type? type v) (define (expander-stx-of-type? type v)
(and (expander-stx? v) (and (expander-stx? v)
@ -47,6 +45,7 @@
(define (expand-syntax-tree-with-expanders-of-type type stx) (define (expand-syntax-tree-with-expanders-of-type type stx)
(define not-expander-stx-of-type? (not? (expander-stx-of-type? type _))) (define not-expander-stx-of-type? (not? (expander-stx-of-type? type _)))
(expand-syntax-tree not-expander-stx-of-type? (with-disappeared-uses
call-expander-transformer (expand-syntax-tree not-expander-stx-of-type?
stx)) call-expander-transformer
stx)))

13
test/test-arrows.rkt Normal file
View File

@ -0,0 +1,13 @@
#lang racket
(require generic-syntax-expanders rackunit)
(define-expander-type foo)
(define-foo-expander foo1 (λ _ #''ok))
(define-syntax (bar stx)
(syntax-case stx ()
[(_ body)
(expand-all-foo-expanders #'body)]))
;; When hovering "foo1" in the code below with the mouse, an arrow should
;; be shown in DrRacket from the foo1 in (define-foo-expander foo1 …) above.
;; This is not automatically checked, as it would be difficult/brittle to check
;; for the syntax property. Patches welcome.
(check-equal? (bar (foo1)) 'ok)

View File

@ -0,0 +1,22 @@
#lang racket
(require generic-syntax-expanders
(for-syntax syntax/parse)
rackunit)
(define-expander-type foo)
(define-foo-expander some-foo-expander
(syntax-parser
[(_ a:id b:id c:id . d:id) #'(d c b a)]))
(define-syntax (test-foo-expander stx)
(syntax-parse stx
[(_ e:expr)
#`'#,(expand-all-foo-expanders #'e)]))
(test-equal?
"Check that some-foo-expander accepts being called
when it is the first item of a dotted list"
(test-foo-expander (some-foo-expander x y z . t))
'(t z y x))

View File

@ -0,0 +1,61 @@
#lang racket
(require generic-syntax-expanders
(for-syntax syntax/parse
rackunit))
(require (for-syntax generic-syntax-expanders))
(define-expander-type foo)
(define-expander-type other)
(define-foo-expander foo-exp (λ (stx) #''foo-exp-is-a-foo-expander))
(define-other-expander other-exp (λ (stx) #''other-exp-is-not-a-foo-expander))
(define-syntax not-an-expander 'syntax-local-value-is-not-an-expander)
(begin-for-syntax
(test-not-exn
"Check that foo-expander? can be passed any value, not just an expander?"
(λ ()
(foo-expander? 123)
(void)))
(test-false
"Check that (static foo-expander?) rejects syntax that is not an identifier?"
(syntax-parse #'(definitely not-a-foo-expander)
[(~var exp (static foo-expander? "a foo expander")) #t]
[_ #f]))
(test-false
"Check that (static foo-expander?) rejects an id without syntax-local-value"
(syntax-parse #'no-syntax-local-value
[(~var exp (static foo-expander? "a foo expander")) #t]
[_ #f]))
(test-begin
(test-false
"Check that foo-expander? rejects an id which is not an expander?"
(foo-expander? (syntax-local-value #'not-an-expander)))
(test-false
"Check that foo-expander? rejects an id which is not an expander?"
(syntax-parse #'not-an-expander
[(~var exp (static foo-expander? "a foo expander")) #t]
[_ #f])))
(test-begin
(test-false
(string-append "Check that foo-expander? rejects an id which is an"
" expander? but not a foo-expander?")
(foo-expander? (syntax-local-value #'other-exp)))
(test-false
(string-append "Check that foo-expander? rejects an id which is an"
" expander? but not a foo-expander?")
(syntax-parse #'other-exp
[(~var exp (static foo-expander? "a foo expander")) #t]
[_ #f])))
(test-begin
(test-true
"Check that foo-expander? accepts an id which is a foo-expander?"
(foo-expander? (syntax-local-value #'foo-exp)))
(test-true
"Check that foo-expander? accepts an id which is a foo-expander?"
(syntax-parse #'foo-exp
[(~var exp (static foo-expander? "a foo expander")) #t]
[_ #f]))))