stxclass: refactored some code, updated docs

stxclass/util: added define-pattern-variable to util/misc

svn: r13304
This commit is contained in:
Ryan Culpepper 2009-01-28 19:55:00 +00:00
parent 6afb62f510
commit 0d83a90a27
4 changed files with 291 additions and 259 deletions

View File

@ -0,0 +1,60 @@
#lang scheme/base
(require scheme/match
(for-template scheme/base))
(provide (all-defined-out))
;; A PK is (make-pk (listof Pattern) stx)
;; k is the rhs expression:
;; - open term with the attr names as free variables
;; - attr name must be bound to variable of (listof^depth value)
;; - 'fail' stxparameterized to (non-escaping!) failure procedure
(define-struct pk (ps k) #:transparent)
;; An ExtPK is one of
;; - PK
;; - (make-idpks stxclass (listof stx) (listof PK))
;; - (make-cpks (listof PK) (listof DatumPKS) (listof LiteralPKS))
;; the first field has only pair patterns
(define-struct idpks (stxclass args idpks))
(define-struct cpks (pairpks datumpks literalpks))
;; A DatumPKS is (make-datumpks datum (listof PK))
(define-struct datumpks (datum pks))
;; A LiteralPKS is (make-literalpks identifier (listof PK))
(define-struct literalpks (literal pks))
;; A FrontierContextExpr (FCE) is one of
;; - (list FrontierIndexExpr Syntax)
;; - (list* FrontierIndexExpr Syntax FrontierContextExpr)
;; A FrontierIndexExpr is
;; - `(+ ,Number Syntax ...)
(define (empty-frontier x)
(list '(+ 0) x))
(define (done-frontier x)
(list '(+ +inf.0) x))
(define (frontier:add-car fc x)
(list* '(+ 0) x fc))
(define (frontier:add-cdr fc)
(cons (fi:add1 (car fc))
(cdr fc)))
(define (fi:add1 fi)
`(+ ,(add1 (cadr fi)) ,@(cddr fi)))
(define (frontier:add-index fc expr)
(cons (fi:add-index (car fc) expr)
(cdr fc)))
(define (fi:add-index fi expr)
`(+ ,(cadr fi) ,expr ,@(cddr fi)))
;; A DynamicFrontierContext (DFC) is one of
;; - (list Syntax Number)
;; - (list* Syntax Number DynamicFrontierContext)
(define (frontier->expr fc)
#`(list #,@(reverse fc)))

View File

@ -1,4 +1,3 @@
#lang scheme/base
(require (for-template scheme/base
syntax/stx
@ -11,48 +10,12 @@
syntax/stx
syntax/boundmap
"rep.ss"
"codegen-data.ss"
"../util.ss")
(provide/contract
[parse:rhs (rhs? (listof sattr?) (listof identifier?) . -> . syntax?)]
[parse:clauses (syntax? identifier? identifier? . -> . syntax?)])
;; A PK is (make-pk (listof Pattern) stx)
;; k is the rhs expression:
;; - open term with the attr names as free variables
;; - attr name must be bound to variable of (listof^depth value)
;; - 'fail' stxparameterized to (non-escaping!) failure procedure
(define-struct pk (ps k) #:transparent)
;; A FrontierContext (FC) is one of
;; - (list FrontierIndex Syntax)
;; - (list* FrontierIndex Syntax FrontierContext)
;; A FrontierIndex is one of
;; - nat
;; - `(+ ,nat Syntax ...)
(define (empty-frontier x)
(list 0 x))
(define (done-frontier x)
(list +inf.0 x))
(define (frontier:add-car fc x)
(list* 0 x fc))
(define (frontier:add-cdr fc)
(cons (match (car fc)
[(? number? n)
(add1 n)]
[`(+ ,n . ,rest)
`(+ ,(add1 n) . ,rest)])
(cdr fc)))
(define (frontier:add-index fc expr)
(cons (match (car fc)
[(? number? n)
`(+ ,n ,expr)]
[`(+ ,n . ,rest)
`(+ ,n ,expr . ,rest)])
(cdr fc)))
(define (frontier->expr fc)
#`(list #,@(reverse fc)))
;; parse:rhs : RHS (listof SAttr) (listof identifier) -> stx
;; Takes a list of the relevant attrs; order is significant!
;; Returns either fail or a list having length same as 'relsattrs'
@ -68,14 +31,14 @@
(list (empty-frontier #'x))
pks
#'fail-rhs)
(fail #'fail-rhs #'x #:fc (empty-frontier #'x))))))]
(fail #'fail-rhs #'x #:fce (empty-frontier #'x))))))]
[(rhs:basic? rhs)
(rhs:basic-parser rhs)]))
;; fail : id id #:pattern datum #:reason datum #:fc FC -> stx
(define (fail k x #:pattern [p #'#f] #:reason [reason #f] #:fc fc)
;; fail : id id #:pattern datum #:reason datum #:fce FCE -> stx
(define (fail k x #:pattern [p #'#f] #:reason [reason #f] #:fce fce)
(with-syntax ([k k] [x x] [p p] [reason reason]
[fc-expr (frontier->expr fc)])
[fc-expr (frontier->expr fce)])
#`(let ([failcontext fc-expr])
#;(printf "failed: reason=~s, p=~s\n fc=~s\n" reason p failcontext)
(k x p 'reason failcontext))))
@ -87,6 +50,7 @@
(for*/list ([rhs patterns] [pk (rhs-pattern->pks rhs relsattrs main-var)])
pk)]))
;; rhs-pattern->pks : RHS (listof SAttr) identifier -> (listof PK)
(define (rhs-pattern->pks rhs relsattrs main-var)
(match rhs
[(struct rhs:pattern (orig-stx attrs pattern decls remap sides))
@ -100,6 +64,7 @@
remap
main-var)))))]))
(define (expr:convert-sides sides iattrs main-var k)
(match sides
['() (k iattrs)]
@ -111,7 +76,7 @@
#,k-rest
#,(fail #'enclosing-fail main-var
#:reason "side condition failed"
#:fc (done-frontier main-var))))))]
#:fce (done-frontier main-var))))))]
[(cons (struct clause:with (p e)) rest)
(let* ([new-iattrs (append (pattern-attrs p) iattrs)]
[k-rest (expr:convert-sides rest new-iattrs main-var k)])
@ -132,6 +97,7 @@
[(relid ...) relids])
#'(list main relid ...))))
;; check-literals-list : syntax -> (listof id)
(define (check-literals-list stx)
(unless (stx-list? stx)
(wrong-syntax stx "expected list of identifiers"))
@ -140,11 +106,11 @@
(wrong-syntax id "expected identifier")))
(syntax->list stx))
(define clauses-kw-table
(list (list '#:literals check-literals-list)))
;; parse:clauses : stx identifier identifier -> stx
(define (parse:clauses stx var failid)
(define clauses-kw-table
(list (list '#:literals check-literals-list)))
(define-values (chunks clauses-stx) (chunk-kw-seq/no-dups stx clauses-kw-table))
(define literals
(cond [(assq '#:literals chunks) => caddr]
@ -177,22 +143,9 @@
(list (empty-frontier var))
pks
failid)
(fail failid var #:fc (empty-frontier var)))))
(fail failid var #:fce (empty-frontier var)))))
;; An ExtPK is one of
;; - PK
;; - (make-idpks stxclass (listof stx) (listof PK))
;; - (make-cpks (listof PK) (listof DatumPKS) (listof LiteralPKS))
(define-struct idpks (stxclass args idpks))
(define-struct cpks (pairpks datumpks literalpks))
;; A DatumPKS is (make-datumpks datum (listof PK))
(define-struct datumpks (datum pks))
;; A LiteralPKS is (make-literalpks identifier (listof PK))
(define-struct literalpks (literal pks))
;; parse:pks : (listof identifier) (listof FC) (listof PK) identifier -> stx
;; parse:pks : (listof identifier) (listof FCE) (listof PK) identifier -> stx
;; Each PK has a list of |vars| patterns.
;; The list of PKs must not be empty.
(define (parse:pks vars fcs pks failid)
@ -220,203 +173,205 @@
(try failvar (expr ...))))))]))
;; parse:extpk : (listof identifier) (listof FC) ExtPK identifier -> stx
;; parse:extpk : (listof identifier) (listof FCE) ExtPK identifier -> stx
;; Pre: vars is not empty
(define (parse:extpk vars fcs extpk failid)
(match extpk
[(struct idpks (stxclass args pks))
(with-syntax ([var0 (car vars)]
[(arg ...) args]
[(arg-var ...) (generate-temporaries args)]
[(r) (generate-temporaries #'(r))])
#`(let ([arg-var arg] ...)
(let ([r #,(if stxclass
#`(#,(sc-parser-name stxclass) #,(car vars) arg-var ...)
#`(list #,(car vars)))])
(if (ok? r)
#,(parse:pks (cdr vars) (cdr fcs) (shift-pks:id pks #'r) failid)
#,(fail failid (car vars)
#:pattern (expectation-of-stxclass stxclass #'(arg-var ...))
#:fc (car fcs))))))]
(parse:pk:id vars fcs failid stxclass args pks)]
[(struct cpks (pairpks datumpkss literalpkss))
(with-syntax ([var0 (car vars)]
[(dvar0) (generate-temporaries (list (car vars)))])
(with-syntax ([(head-var tail-var) (generate-temporaries #'(head tail))]
[(pair-pattern ...)
(for*/list ([pk pairpks])
(pattern-orig-stx (car (pk-ps pk))))]
[(datum-pattern ...)
(for*/list ([datumpk datumpkss]
[pk (datumpks-pks datumpk)])
(pattern-orig-stx (car (pk-ps pk))))]
[(datum-test ...)
(for/list ([datumpk datumpkss])
(let ([datum (datumpks-datum datumpk)])
#`(equal? dvar0 (quote #,datum))))]
[(datum-rhs ...)
(map (lambda (pks)
(parse:pks (cdr vars)
(cdr fcs)
(shift-pks:datum pks)
failid))
(map datumpks-pks datumpkss))]
[(lit-test ...)
(for/list ([literalpks literalpkss])
(let ([literal (literalpks-literal literalpks)])
#`(and (identifier? var0)
(free-identifier=? var0 (quote-syntax #,literal)))))]
[(lit-rhs ...)
(map (lambda (pks)
(parse:pks (cdr vars)
(cdr fcs)
(shift-pks:literal pks)
failid))
(map literalpks-pks literalpkss))])
#`(let ([dvar0 (if (syntax? var0) (syntax-e var0) var0)])
(cond #,@(if (pair? pairpks)
#`([(pair? dvar0)
(let ([head-var (car dvar0)]
[tail-var (cdr dvar0)])
#,(parse:pks (list* #'head-var #'tail-var (cdr vars))
(list* (frontier:add-car (car fcs) #'head-var)
(frontier:add-cdr (car fcs))
(cdr fcs))
(shift-pks:pair pairpks)
failid))])
#`())
#,@(if (pair? literalpkss)
#'([lit-test lit-rhs] ...)
#'())
[datum-test datum-rhs] ...
[else
#,(fail failid (car vars)
#:pattern (expectation-of-constants
(pair? pairpks)
(for/list ([d datumpkss])
(datumpks-datum d))
(for/list ([l literalpkss])
(literalpks-literal l)))
#:fc (car fcs))]))))]
#;
[(struct pk ((cons (struct pat:splice (orig-stx attrs depth head tail))
rest-ps)
k))
(let-match ([(struct pat:id-splice (_ head-attrs _ name ssc args)) head])
(let* ([head-flat-attrs (flatten-attrs* head-attrs)]
[head-ids (map attr-name head-flat-attrs)])
(with-syntax* ([var0 (car vars)]
[(hid ...) head-ids]
[(fail-k) (generate-temporaries #'(fail-k))]
[ok-k
#`(lambda (fail-k hid ...)
#,(parse:pks (cons #'t (cdr vars))
fcs ;; FIXME: must update!
(cons tail
(shift-pks:id pks #'r))
#'fail-k))]
[sub-parse-expr
#`(#,(ssc-parser-name ssc) #,(car vars) #,@args)])
#'sub-parse-expr)))]
[(struct pk ((cons (and the-pattern (struct pat:gseq (orig-stx attrs depth heads tail)))
rest-ps)
k))
(let* ([xvar (car (generate-temporaries (list #'x)))]
[head-lengths
(for/list ([head heads]) (length (head-ps head)))]
[head-attrss
(for/list ([head heads])
(flatten-attrs* (head-attrs head)))]
[hid-initss
(for/list ([head heads] [head-attrs head-attrss])
(for/list ([head-attr head-attrs])
(cond [(head-default head)
=> (lambda (x) #`(quote-syntax #,x))]
[(head-as-list? head) #'null]
[else #'#f])))]
[combinerss
(for/list ([head heads] [head-attrs head-attrss])
(for/list ([head-attr head-attrs])
(if (head-as-list? head) #'cons #'or)))]
[finalizess
(for/list ([head heads] [head-attrs head-attrss])
(for/list ([head-attr head-attrs])
(if (head-as-list? head) #'reverse #'values)))]
[head-idss
(for/list ([head-attrs head-attrss])
(map attr-name head-attrs))]
[completed-heads
(for/list ([head heads])
(complete-heads-pattern head xvar (add1 depth) orig-stx))]
[hid-argss (map generate-temporaries head-idss)]
[hid-args (apply append hid-argss)]
[mins (map head-min heads)]
[maxs (map head-max heads)]
[as-list?s (map head-as-list? heads)]
[reps (generate-temporaries (for/list ([head heads]) 'rep))])
(with-syntax ([x xvar]
[var0 (car vars)]
[((hid ...) ...) head-idss]
[((hid-arg ...) ...) hid-argss]
[((hid-init ...) ...) hid-initss]
[((combine ...) ...) combinerss]
[((finalize ...) ...) finalizess]
[(head-length ...) head-lengths]
[(rep ...) reps]
[(maxrepconstraint ...)
;; FIXME: move to side condition to appropriate pattern
(for/list ([repvar reps] [maxrep maxs])
(if maxrep
#`(< #,repvar #,maxrep)
#`#t))]
[(occurs-binding ...)
(for/list ([head heads] [rep reps] #:when (head-occurs head))
#`[#,(head-occurs head) (positive? #,rep)])]
[(parse-loop failkv fail-tail)
(generate-temporaries #'(parse-loop failkv fail-tail))])
(with-syntax ([(rhs ...)
#`[(let ([hid-arg (combine hid hid-arg)] ...)
(if maxrepconstraint
(let ([rep (add1 rep)])
(parse-loop x #,@hid-args #,@reps enclosing-fail))
#,(fail #'enclosing-fail #'var0
#:fc (frontier:add-index (car fcs)
#'(calculate-index rep ...))
#:reason "maxiumum repetition constraint failed")))
...]]
[tail-rhs
#`(cond #,@(for/list ([repvar reps] [minrep mins] #:when minrep)
#`[(< #,repvar #,minrep)
#,(fail #'enclosing-fail (car vars)
#:fc (frontier:add-index
(car fcs)
#'(calculate-index rep ...))
#:pattern (expectation-of-constants
#f '(mininum-rep-constraint-failed) '())
#:reason "minimum repetition constraint failed")])
[else
(let ([hid (finalize hid-arg)] ... ...
occurs-binding ...
[fail-tail enclosing-fail])
#,(parse:pks (cdr vars)
(cdr fcs)
(list (make-pk rest-ps k))
#'fail-tail))])])
#`(let ()
(define (calculate-index rep ...)
(+ (* rep head-length) ...))
(define (parse-loop x hid-arg ... ... rep ... failkv)
#,(parse:pks (list #'x)
(list (frontier:add-index (car fcs)
#'(calculate-index rep ...)))
(append
(map make-pk
(map list completed-heads)
(syntax->list #'(rhs ...)))
(list (make-pk (list tail) #`tail-rhs)))
#'failkv))
(let ([hid hid-init] ... ...
[rep 0] ...)
(parse-loop var0 hid ... ... rep ... #,failid))))))]))
(parse:pk:c vars fcs failid pairpks datumpkss literalpkss)]
[(struct pk ((cons (? pat:gseq? gseq-pattern) rest-patterns) k))
(parse:pk:gseq vars fcs failid gseq-pattern rest-patterns k)]))
;; parse:pk:id : (listof id) (listof FCE) id SC stx (listof pk) -> stx
(define (parse:pk:id vars fcs failid stxclass args pks)
(define var (car vars))
(define fc (car fcs))
(with-syntax ([var0 var]
[(arg ...) args]
[(arg-var ...) (generate-temporaries args)]
[(result) (generate-temporaries #'(result))])
#`(let ([arg-var arg] ...)
(let ([result #,(if stxclass
#`(#,(sc-parser-name stxclass) var0 arg-var ...)
#`(list var0))])
(if (ok? result)
#,(parse:pks (cdr vars) (cdr fcs) (shift-pks:id pks #'result) failid)
#,(fail failid var
#:pattern (expectation-of-stxclass stxclass #'(arg-var ...))
#:fce fc))))))
;; parse:pk:c : (listof id) (listof FCE) id ??? ... -> stx
(define (parse:pk:c vars fcs failid pairpks datumpkss literalpkss)
(define var (car vars))
(define datum-var (generate-temporary 'datum))
(define (datumpks-test datumpks)
(let ([datum (datumpks-datum datumpks)])
#`(equal? #,datum-var (quote #,datum))))
(define (datumpks-rhs datumpks)
(let ([pks (datumpks-pks datumpks)])
(parse:pks (cdr vars) (cdr fcs) (shift-pks:datum pks) failid)))
(define (literalpks-test literalpks)
(let ([literal (literalpks-literal literalpks)])
#`(and (identifier? #,var)
(free-identifier=? #,var (quote-syntax #,literal)))))
(define (literalpks-rhs literalpks)
(let ([pks (literalpks-pks literalpks)])
(parse:pks (cdr vars) (cdr fcs) (shift-pks:literal pks) failid)))
(define-pattern-variable var0 var)
(define-pattern-variable dvar0 datum-var)
(define-pattern-variable head-var (generate-temporary 'head))
(define-pattern-variable tail-var (generate-temporary 'tail))
(with-syntax ([(datum-clause ...)
(for/list ([datumpks datumpkss])
#`[#,(datumpks-test datumpks) #,(datumpks-rhs datumpks)])]
[(lit-clause ...)
(for/list ([literalpks literalpkss])
#`[#,(literalpks-test literalpks) #,(literalpks-rhs literalpks)])])
#`(let ([dvar0 (if (syntax? var0) (syntax-e var0) var0)])
(cond #,@(if (pair? pairpks)
#`([(pair? dvar0)
(let ([head-var (car dvar0)]
[tail-var (cdr dvar0)])
#,(parse:pks (list* #'head-var #'tail-var (cdr vars))
(list* (frontier:add-car (car fcs) #'head-var)
(frontier:add-cdr (car fcs))
(cdr fcs))
(shift-pks:pair pairpks)
failid))])
#`())
lit-clause ...
datum-clause ...
[else
#,(fail failid (car vars)
#:pattern (expectation-of-constants
(pair? pairpks)
(for/list ([d datumpkss])
(datumpks-datum d))
(for/list ([l literalpkss])
(literalpks-literal l)))
#:fce (car fcs))]))))
;; parse:pk:gseq : (listof id) (listof FCE) id
;; pat:gseq (listof Pattern)
;; ???
;; -> stx
(define (parse:pk:gseq vars fcs failid gseq-pattern rest-patterns k)
(match-define (struct pat:gseq (orig-stx attrs depth heads tail)) gseq-pattern)
(define xvar (generate-temporary 'x))
(define head-lengths (for/list ([head heads]) (length (head-ps head))))
(define head-attrss (for/list ([head heads]) (flatten-attrs* (head-attrs head))))
(define hid-initss
(for/list ([head heads] [head-attrs head-attrss])
(for/list ([head-attr head-attrs])
(cond [(head-default head)
=> (lambda (x) #`(quote-syntax #,x))]
[(head-as-list? head) #'null]
[else #'#f]))))
(define combinerss
(for/list ([head heads] [head-attrs head-attrss])
(for/list ([head-attr head-attrs])
(if (head-as-list? head) #'cons #'or))))
(define finalizess
(for/list ([head heads] [head-attrs head-attrss])
(for/list ([head-attr head-attrs])
(if (head-as-list? head) #'reverse #'values))))
(define head-idss
(for/list ([head-attrs head-attrss])
(map attr-name head-attrs)))
(define completed-heads
(for/list ([head heads])
(complete-heads-pattern head xvar (add1 depth) orig-stx)))
(define hid-argss (map generate-temporaries head-idss))
(define hid-args (apply append hid-argss))
(define mins (map head-min heads))
(define maxs (map head-max heads))
(define as-list?s (map head-as-list? heads))
(define reps (generate-temporaries (for/list ([head heads]) 'rep)))
(with-syntax ([x xvar]
[var0 (car vars)]
[((hid ...) ...) head-idss]
[((hid-arg ...) ...) hid-argss]
[((hid-init ...) ...) hid-initss]
[((combine ...) ...) combinerss]
[((finalize ...) ...) finalizess]
[(head-length ...) head-lengths]
[(rep ...) reps]
[(maxrepconstraint ...)
;; FIXME: move to side condition to appropriate pattern
(for/list ([repvar reps] [maxrep maxs])
(if maxrep
#`(< #,repvar #,maxrep)
#`#t))]
[(occurs-binding ...)
(for/list ([head heads] [rep reps] #:when (head-occurs head))
#`[#,(head-occurs head) (positive? #,rep)])]
[(parse-loop failkv fail-tail)
(generate-temporaries #'(parse-loop failkv fail-tail))])
(define (gen-head-rhs my-hids my-hid-args combiners repvar maxrep)
(with-syntax ([(my-hid ...) my-hids]
[(my-hid-arg ...) my-hid-args]
[(combine ...) combiners]
[rep repvar]
[maxrep-constraint
(if maxrep
#`(< #,repvar #,maxrep)
#`'#t)])
#`(let ([my-hid-arg (combine my-hid my-hid-arg)] ...)
(if maxrep-constraint
(let ([rep (add1 rep)])
(parse-loop x #,@hid-args #,@reps enclosing-fail))
#,(fail #'enclosing-fail #'var0
#:fce (frontier:add-index (car fcs)
#`(calculate-index #,@reps)))))))
(define tail-rhs-expr
(with-syntax ([(minrep-clause ...)
(for/list ([repvar reps] [minrep mins] #:when minrep)
#`[(< #,repvar #,minrep)
#,(fail #'enclosing-fail (car vars)
#:fce (frontier:add-index (car fcs)
#`(calculate-index #,@reps))
#:pattern (expectation-of-constants
#f '(minimum-rep-constraint-failed) '()))])])
#`(cond minrep-clause ...
[else
(let ([hid (finalize hid-arg)] ... ...
occurs-binding ...
[fail-tail enclosing-fail])
#,(parse:pks (cdr vars)
(cdr fcs)
(list (make-pk rest-patterns k))
#'fail-tail))])))
(with-syntax ([tail-rhs tail-rhs-expr]
[(rhs ...)
(for/list ([hids head-idss]
[hid-args hid-argss]
[combiners combinerss]
[repvar reps]
[maxrep maxs])
(gen-head-rhs hids hid-args combiners repvar maxrep))])
#`(let ()
(define (calculate-index rep ...)
(+ (* rep head-length) ...))
(define (parse-loop x hid-arg ... ... rep ... failkv)
#,(parse:pks (list #'x)
(list (frontier:add-index (car fcs)
#'(calculate-index rep ...)))
(append
(map make-pk
(map list completed-heads)
(syntax->list #'(rhs ...)))
(list (make-pk (list tail) #`tail-rhs)))
#'failkv))
(let ([hid hid-init] ... ...
[rep 0] ...)
(parse-loop var0 hid ... ... rep ... #,failid))))))
;; complete-heads-patterns : Head identifier number stx -> Pattern
(define (complete-heads-pattern head rest-var depth seq-orig-stx)

View File

@ -289,14 +289,14 @@ declaration?}
@specsubform[(code:line #:description description)]{
The @scheme[description] argument must be a string literal. It is used
in error messages involving the syntax class. For example, if a term
is rejected by the syntax class, an error of the form
@scheme["expected <description>"] may be generated.
The @scheme[description] argument is an expression (with the
syntax-class's parameters in scope) that should evaluate to a
string. It is used in error messages involving the syntax class. For
example, if a term is rejected by the syntax class, an error of the
form @scheme["expected <description>"] may be generated.
If absent, the name of the syntax class is used instead.
@TODO{Allow string expressions with parameters in scope?}
}
@specsubform[#:transparent]{
@ -663,6 +663,14 @@ TODO
@defmodule[stxclass/util/misc]
@defform[(define-pattern-variable id expr)]{
Evaluates @scheme[expr] and binds it to @scheme[id] as a pattern
variable, so @scheme[id] can be used in subsequent @scheme[syntax]
patterns.
}
@defform[(with-temporaries (temp-id ...) . body)]{
Evaluates @scheme[body] with each @scheme[temp-id] bound as a pattern

View File

@ -1,8 +1,12 @@
#lang scheme/base
(require syntax/kerncase
syntax/stx)
syntax/stx
(for-syntax scheme/base
scheme/private/sc))
(provide with-temporaries
(provide define-pattern-variable
with-temporaries
generate-temporary
generate-n-temporaries
@ -14,6 +18,11 @@
check-string
check-idlist)
;; Defining pattern variables
(define-syntax-rule (define-pattern-variable name expr)
(begin (define var expr)
(define-syntax name (make-syntax-mapping '0 (quote-syntax var)))))
;; Generating temporaries