commit 9bfa089c45fb6d7e991f4630931813830bb99a67
parent 45003e6e4215e0302bff81fe8540e6030358a6e8
Author: Georges Dupéron <georges.duperon@gmail.com>
Date: Sun, 22 Jan 2017 18:28:59 +0100
Bugfix: with-pvars must be called after binding the pvar, not before.
Diffstat:
4 files changed, 67 insertions(+), 12 deletions(-)
diff --git a/README.md b/README.md
@@ -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.
+\ No newline at end of file
diff --git a/parse/private/runtime.rkt b/parse/private/runtime.rkt
@@ -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
diff --git a/scribblings/stxparse-info.scrbl b/scribblings/stxparse-info.scrbl
@@ -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.}
-\ No newline at end of file
+ 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))]}
+\ No newline at end of file
diff --git a/test/test-current-pvars.rkt b/test/test-current-pvars.rkt
@@ -16,4 +16,26 @@
'([y x] [z w y x]))
(check-equal? (list-pvars)
- '())
-\ No newline at end of file
+ '())
+
+;; 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))
+\ No newline at end of file