Implemented current-pvars

This commit is contained in:
Georges Dupéron 2017-01-22 18:11:52 +01:00
parent 6a8ffed720
commit 45003e6e42
7 changed files with 114 additions and 29 deletions

View File

@ -20,16 +20,16 @@ env:
# Supply more than one RACKET_VERSION (as in the example below) to # Supply more than one RACKET_VERSION (as in the example below) to
# create a Travis-CI build matrix to test against multiple Racket # create a Travis-CI build matrix to test against multiple Racket
# versions. # versions.
- RACKET_VERSION=6.0 - RACKET_VERSION=6.0 RECENT=false
- RACKET_VERSION=6.1 - RACKET_VERSION=6.1 RECENT=false
- RACKET_VERSION=6.1.1 - RACKET_VERSION=6.1.1 RECENT=true
- RACKET_VERSION=6.2 - RACKET_VERSION=6.2 RECENT=true
- RACKET_VERSION=6.3 - RACKET_VERSION=6.3 RECENT=true
- RACKET_VERSION=6.4 - RACKET_VERSION=6.4 RECENT=true
- RACKET_VERSION=6.5 - RACKET_VERSION=6.5 RECENT=true
- RACKET_VERSION=6.6 - RACKET_VERSION=6.6 RECENT=true
- RACKET_VERSION=6.7 - RACKET_VERSION=6.7 RECENT=true
- RACKET_VERSION=HEAD - RACKET_VERSION=HEAD RECENT=true
matrix: matrix:
allow_failures: allow_failures:
@ -51,8 +51,10 @@ before_script:
# packages without it getting stuck on a confirmation prompt. # packages without it getting stuck on a confirmation prompt.
script: script:
- raco test -x -p stxparse-info - raco test -x -p stxparse-info
- raco setup --check-pkg-deps --pkgs stxparse-info
- raco pkg install --deps search-auto doc-coverage
- raco doc-coverage stxparse-info/current-pvars
- if $RECENT; then raco pkg install --deps search-auto cover cover-codecov; fi
- if $RECENT; then raco cover -b -f codecov -d $TRAVIS_BUILD_DIR/coverage .; fi
after_success: after_success:
- raco setup --check-pkg-deps --pkgs stxparse-info
- raco pkg install --deps search-auto cover cover-coveralls
- raco cover -b -f coveralls -d $TRAVIS_BUILD_DIR/coverage .

24
current-pvars.rkt Normal file
View File

@ -0,0 +1,24 @@
#lang racket/base
(require racket/stxparam
(for-syntax racket/base
racket/contract))
(provide (for-syntax (rename-out [get-current-pvars current-pvars]))
with-pvars)
(define-syntax-parameter current-pvars '())
(define-syntax (with-pvars stx)
(syntax-case stx ()
[(_ (pvar ...) . body)
(andmap identifier? (syntax->list #'(pvar ...)))
(with-syntax ([(reverse-pvar ...) (reverse (syntax->list #'(pvar ...)))])
#'(syntax-parameterize
([current-pvars (list* (quote-syntax reverse-pvar) ...
(syntax-parameter-value #'current-pvars))])
. body))]))
(begin-for-syntax
(define/contract (get-current-pvars)
(-> (listof identifier?))
(syntax-parameter-value #'current-pvars)))

View File

@ -1,8 +1,7 @@
#lang info #lang info
(define collection "stxparse-info") (define collection "stxparse-info")
(define deps '("base" (define deps '("base"
"rackunit-lib" "rackunit-lib"))
"reprovide-lang"))
(define build-deps '("scribble-lib" "racket-doc")) (define build-deps '("scribble-lib" "racket-doc"))
(define scribblings '(("scribblings/stxparse-info.scrbl" ()))) (define scribblings '(("scribblings/stxparse-info.scrbl" ())))
(define pkg-desc "Description Here") (define pkg-desc "Description Here")

View File

@ -1,2 +1,3 @@
#lang reprovide #lang racket/base
"parse.rkt" (require "parse.rkt")
(provide (all-from-out "parse.rkt"))

View File

@ -1,6 +1,7 @@
#lang racket/base #lang racket/base
(require racket/stxparam (require racket/stxparam
stxparse-info/parse/private/residual ;; keep abs. path stxparse-info/parse/private/residual ;; keep abs. path
stxparse-info/current-pvars
(for-syntax racket/base (for-syntax racket/base
racket/list racket/list
syntax/kerncase syntax/kerncase
@ -95,14 +96,15 @@ residual.rkt.
(map parse-attr (syntax->list #'(a ...)))]) (map parse-attr (syntax->list #'(a ...)))])
(with-syntax ([(vtmp ...) (generate-temporaries #'(name ...))] (with-syntax ([(vtmp ...) (generate-temporaries #'(name ...))]
[(stmp ...) (generate-temporaries #'(name ...))]) [(stmp ...) (generate-temporaries #'(name ...))])
#'(letrec-syntaxes+values #'(with-pvars (name ...)
([(stmp) (make-attribute-mapping (quote-syntax vtmp)
'name 'depth 'syntax?)] ...)
([(vtmp) value] ...)
(letrec-syntaxes+values (letrec-syntaxes+values
([(name) (make-syntax-mapping 'depth (quote-syntax stmp))] ...) ([(stmp) (make-attribute-mapping (quote-syntax vtmp)
() 'name 'depth 'syntax?)] ...)
. body))))])) ([(vtmp) value] ...)
(letrec-syntaxes+values
([(name) (make-syntax-mapping 'depth (quote-syntax stmp))] ...)
()
. body)))))]))
;; (let-attributes* (([id num] ...) (expr ...)) expr) : expr ;; (let-attributes* (([id num] ...) (expr ...)) expr) : expr
;; Special case: empty attrs need not match number of value exprs. ;; Special case: empty attrs need not match number of value exprs.

View File

@ -1,10 +1,48 @@
#lang scribble/manual #lang scribble/manual
@require[@for-label[stxparse-info @require[@for-label[stxparse-info/parse
stxparse-info/current-pvars
racket/base]] racket/base]]
@title{stxparse-info} @title{stxparse-info : tracking bound syntax pattern variables with
@author{georges} @racketmodname[syntax/parse]}
@author[@author+email["Georges Dupéron" "georges.duperon@gmail.com"]]
@defmodule[stxparse-info] @defmodule[stxparse-info/parse]
Package Description Here The module @racketmodname[stxparse-info/parse] is a patched version of
@racketmodname[syntax/parse] which tracks which syntax pattern variables are
bound. This allows some libraries to change the way syntax pattern variables
work.
For example, @racketmodname[phc-graph/subtemplate] automatically derives
temporary identifiers when a template contains @racket[yᵢ …], and @racket[xᵢ]
is a pattern variable. To know from which @racket[varᵢ] the @racket[yᵢ …]
identifiers must be derived, @racketmodname[phc-graph/subtemplate] needs to
know which syntax pattern variables are within scope.
@section{Reading and updating the list of currently-bound pattern variables}
@defmodule[stxparse-info/current-pvars]
@defproc[#:kind "procedure at phase 1"
(current-pvars) (listof identifier?)]{
This for-syntax procedure returns the list of syntax pattern variables which
are known to be bound. The most recently bound variables are at the beginning
of the list.}
@defform[(with-pvars (pvar ...) . body)
#:contracts ([pvar identifier?])]{
Prepends the given @racket[pvar ...] to the list of pattern variables which
are known to be bound. The @racket[pvar ...] are prepended in reverse order,
so within the body of
@racketblock[(with-pvars (v₁ v₂ v₃) . body)]
a call to the for-syntax function @racket[(current-pvars)] returns;
@racketblock[(list* (quote-syntax v₃) (quote-syntax v₂) (quote-syntax v₁)
old-current-pvars)]
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.}

View File

@ -0,0 +1,19 @@
#lang racket
(require stxparse-info/parse
stxparse-info/current-pvars
racket/stxparam
rackunit)
(define-syntax (list-pvars stx)
#`'#,(current-pvars))
(check-equal? (list-pvars)
'())
(check-equal? (syntax-parse #'(1 2 3 a b c)
[(x y:nat ... {~parse w (list-pvars)} z ...)
(syntax->datum #`[w #,(list-pvars)])])
'([y x] [z w y x]))
(check-equal? (list-pvars)
'())