Bugfix: with-pvars must be called after binding the pvar, not before.

This commit is contained in:
Georges Dupéron 2017-01-22 18:28:59 +01:00
parent 45003e6e42
commit 9bfa089c45
4 changed files with 64 additions and 10 deletions

View File

@ -1,3 +1,18 @@
stxparse-info
=============
README text here.
The module `stxparse-info/parse` is a patched version of `syntax/parse` which
tracks which syntax pattern variables are bound. This allows some libraries to
change the way syntax pattern variables work.
For example, `phc-graph/subtemplate` automatically derives temporary
identifiers when a template contains `yᵢ …`, and `xᵢ` is a pattern
variable. To know from which `varᵢ` the `yᵢ …` identifiers must be derived,
`phc-graph/subtemplate` needs to know which syntax pattern variables are
within scope.
To use this package, simply require `stxparse-info/pares` instead of
`syntax/parse` Additionally, it is possible to use the for-syntax function
`(current-pvars)` from `stxparse-info/current-pvars` to access the list of
currently-bound pattern variables, and the macro `(with-pvars (pvar ...)
. body)` can be used to add new pattern variables to the list.

View File

@ -96,14 +96,14 @@ residual.rkt.
(map parse-attr (syntax->list #'(a ...)))])
(with-syntax ([(vtmp ...) (generate-temporaries #'(name ...))]
[(stmp ...) (generate-temporaries #'(name ...))])
#'(with-pvars (name ...)
#'(letrec-syntaxes+values
([(stmp) (make-attribute-mapping (quote-syntax vtmp)
'name 'depth 'syntax?)] ...)
([(vtmp) value] ...)
(letrec-syntaxes+values
([(stmp) (make-attribute-mapping (quote-syntax vtmp)
'name 'depth 'syntax?)] ...)
([(vtmp) value] ...)
(letrec-syntaxes+values
([(name) (make-syntax-mapping 'depth (quote-syntax stmp))] ...)
()
([(name) (make-syntax-mapping 'depth (quote-syntax stmp))] ...)
()
(with-pvars (name ...)
. body)))))]))
;; (let-attributes* (([id num] ...) (expr ...)) expr) : expr

View File

@ -45,4 +45,21 @@ know which syntax pattern variables are within scope.
This can be used to implement macros which work similarly to
@racket[syntax-parse] or @racket[syntax-case], and have them record the syntax
pattern variables which they bind.}
pattern variables which they bind.
Note that the identifiers @racket[pvar ...] must already be bound to syntax
pattern variables when @racket[with-pvars] is used, e.g.
@racketblock[
(let-syntax ([v₁ (make-syntax-mapping depth (quote-syntax valvar))]
[v₂ (make-syntax-mapping depth (quote-syntax valvar))])
(with-pvars (v₁ v₂)
code))]
instead of:
@racketblock[
(with-pvars (v₁ v₂)
(let-syntax ([v₁ (make-syntax-mapping depth (quote-syntax valvar))]
[v₂ (make-syntax-mapping depth (quote-syntax valvar))])
code))]}

View File

@ -16,4 +16,26 @@
'([y x] [z w y x]))
(check-equal? (list-pvars)
'())
'())
;; Check that the identifier has the right scopes
(define-syntax (ref-nth-pvar stx)
(syntax-case stx ()
[(_ n)
(number? (syntax-e #'n))
#`#'#,(let ([pvar (list-ref (current-pvars) (syntax-e #'n))])
(datum->syntax pvar (syntax-e pvar) stx))]))
(check-equal? (syntax-parse #'1
[x
(syntax->datum (ref-nth-pvar 0))])
1)
(check-equal? (syntax-parse #'1
[x
(cons (syntax->datum (ref-nth-pvar 0))
(syntax-parse #'2
[x
(list (syntax->datum (ref-nth-pvar 0))
(syntax->datum (ref-nth-pvar 1)))]))])
'(1 2 1))