stxclass: added more contracts
svn: r13371
This commit is contained in:
parent
ebd77ba75b
commit
e092884415
|
@ -36,13 +36,44 @@
|
||||||
[(rhs:basic? rhs)
|
[(rhs:basic? rhs)
|
||||||
(rhs:basic-parser rhs)]))
|
(rhs:basic-parser rhs)]))
|
||||||
|
|
||||||
;; fail : id id #:pattern datum #:reason datum #:fce FCE -> stx
|
;; parse:clauses : stx identifier identifier -> stx
|
||||||
(define (fail k x #:pattern [p #'#f] #:reason [reason #f] #:fce fce)
|
(define (parse:clauses stx var failid)
|
||||||
(with-syntax ([k k] [x x] [p p] [reason reason]
|
(define clauses-kw-table
|
||||||
[fc-expr (frontier->expr fce)])
|
(list (list '#:literals check-literals-list)))
|
||||||
#`(let ([failcontext fc-expr])
|
(define-values (chunks clauses-stx) (chunk-kw-seq/no-dups stx clauses-kw-table))
|
||||||
#;(printf "failed: reason=~s, p=~s\n fc=~s\n" reason p failcontext)
|
(define literals
|
||||||
(k x p 'reason failcontext))))
|
(cond [(assq '#:literals chunks) => caddr]
|
||||||
|
[else null]))
|
||||||
|
(define (clause->pk clause)
|
||||||
|
(syntax-case clause ()
|
||||||
|
[(p . rest)
|
||||||
|
(let-values ([(rest decls _ sides)
|
||||||
|
(parse-pattern-directives #'rest
|
||||||
|
#:sc? #f
|
||||||
|
#:literals literals)])
|
||||||
|
(syntax-case rest ()
|
||||||
|
[(b)
|
||||||
|
(let* ([pattern (parse-pattern #'p decls 0)])
|
||||||
|
(make-pk (list pattern)
|
||||||
|
(expr:convert-sides sides
|
||||||
|
(pattern-attrs pattern)
|
||||||
|
var
|
||||||
|
(lambda (iattrs)
|
||||||
|
(wrap-pattern-body/attrs iattrs
|
||||||
|
0
|
||||||
|
#'b)))))]
|
||||||
|
[_
|
||||||
|
(wrong-syntax clause "expected single body expression")]))]))
|
||||||
|
(unless (stx-list? clauses-stx)
|
||||||
|
(wrong-syntax clauses-stx "expected sequence of clauses"))
|
||||||
|
(let ([pks (map clause->pk (stx->list clauses-stx))])
|
||||||
|
(if (pair? pks)
|
||||||
|
(parse:pks (list var)
|
||||||
|
(list (empty-frontier var))
|
||||||
|
pks
|
||||||
|
failid)
|
||||||
|
(fail failid var #:fce (empty-frontier var)))))
|
||||||
|
|
||||||
|
|
||||||
;; rhs->pks : RHS (listof SAttr) identifier -> (listof PK)
|
;; rhs->pks : RHS (listof SAttr) identifier -> (listof PK)
|
||||||
(define (rhs->pks rhs relsattrs main-var)
|
(define (rhs->pks rhs relsattrs main-var)
|
||||||
|
@ -65,7 +96,7 @@
|
||||||
remap
|
remap
|
||||||
main-var)))))]))
|
main-var)))))]))
|
||||||
|
|
||||||
|
;; expr:convert-sides : (listof SideClause) (listof IAttr) id stx -> stx
|
||||||
(define (expr:convert-sides sides iattrs main-var k)
|
(define (expr:convert-sides sides iattrs main-var k)
|
||||||
(match sides
|
(match sides
|
||||||
['() (k iattrs)]
|
['() (k iattrs)]
|
||||||
|
@ -107,44 +138,16 @@
|
||||||
(wrong-syntax id "expected identifier")))
|
(wrong-syntax id "expected identifier")))
|
||||||
(syntax->list stx))
|
(syntax->list stx))
|
||||||
|
|
||||||
|
;; 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 fce)])
|
||||||
|
#`(let ([failcontext fc-expr])
|
||||||
|
#;(printf "failed: reason=~s, p=~s\n fc=~s\n" reason p failcontext)
|
||||||
|
(k x p 'reason failcontext))))
|
||||||
|
|
||||||
;; parse:clauses : stx identifier identifier -> stx
|
|
||||||
(define (parse:clauses stx var failid)
|
;; Parsing
|
||||||
(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]
|
|
||||||
[else null]))
|
|
||||||
(define (clause->pk clause)
|
|
||||||
(syntax-case clause ()
|
|
||||||
[(p . rest)
|
|
||||||
(let-values ([(rest decls _ sides)
|
|
||||||
(parse-pattern-directives #'rest
|
|
||||||
#:sc? #f
|
|
||||||
#:literals literals)])
|
|
||||||
(syntax-case rest ()
|
|
||||||
[(b)
|
|
||||||
(let* ([pattern (parse-pattern #'p decls 0)])
|
|
||||||
(make-pk (list pattern)
|
|
||||||
(expr:convert-sides sides
|
|
||||||
(pattern-attrs pattern)
|
|
||||||
var
|
|
||||||
(lambda (iattrs)
|
|
||||||
(wrap-pattern-body/attrs iattrs
|
|
||||||
0
|
|
||||||
#'b)))))]
|
|
||||||
[_
|
|
||||||
(wrong-syntax clause "expected single body expression")]))]))
|
|
||||||
(unless (stx-list? clauses-stx)
|
|
||||||
(wrong-syntax clauses-stx "expected sequence of clauses"))
|
|
||||||
(let ([pks (map clause->pk (stx->list clauses-stx))])
|
|
||||||
(if (pair? pks)
|
|
||||||
(parse:pks (list var)
|
|
||||||
(list (empty-frontier var))
|
|
||||||
pks
|
|
||||||
failid)
|
|
||||||
(fail failid var #:fce (empty-frontier var)))))
|
|
||||||
|
|
||||||
;; parse:pks : (listof identifier) (listof FCE) (listof PK) identifier -> stx
|
;; parse:pks : (listof identifier) (listof FCE) (listof PK) identifier -> stx
|
||||||
;; Each PK has a list of |vars| patterns.
|
;; Each PK has a list of |vars| patterns.
|
||||||
|
|
|
@ -100,7 +100,25 @@
|
||||||
(define (sattr? a)
|
(define (sattr? a)
|
||||||
(and (attr? a) (symbol? (attr-name a))))
|
(and (attr? a) (symbol? (attr-name a))))
|
||||||
|
|
||||||
|
;; Contracts
|
||||||
|
|
||||||
|
;; DeclEnv = [id -> (list* id id (listof stx)) or #t or #f
|
||||||
|
;; #t means literal, #f means undeclared, list means stxclass (w/ args)
|
||||||
|
(define DeclEnv/c
|
||||||
|
(-> identifier?
|
||||||
|
(or/c boolean? (cons/c identifier? (cons/c identifier? (listof syntax?))))))
|
||||||
|
|
||||||
|
(define RemapEnv/c
|
||||||
|
(-> identifier? symbol?))
|
||||||
|
|
||||||
|
(define SideClause/c (or/c clause:with? clause:when?))
|
||||||
|
|
||||||
|
|
||||||
(provide/contract
|
(provide/contract
|
||||||
|
[DeclEnv/c contract?]
|
||||||
|
[RemapEnv/c contract?]
|
||||||
|
[SideClause/c contract?]
|
||||||
|
|
||||||
[make-empty-sc (-> identifier? sc?)]
|
[make-empty-sc (-> identifier? sc?)]
|
||||||
[allow-unbound-stxclasses (parameter/c boolean?)]
|
[allow-unbound-stxclasses (parameter/c boolean?)]
|
||||||
[iattr? (any/c . -> . boolean?)]
|
[iattr? (any/c . -> . boolean?)]
|
||||||
|
@ -324,5 +342,3 @@
|
||||||
(cond [(null? iattrs) #f]
|
(cond [(null? iattrs) #f]
|
||||||
[(bound-identifier=? name (attr-name (car iattrs))) (car iattrs)]
|
[(bound-identifier=? name (attr-name (car iattrs))) (car iattrs)]
|
||||||
[else (lookup-iattr name (cdr iattrs))]))
|
[else (lookup-iattr name (cdr iattrs))]))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#lang scheme
|
#lang scheme
|
||||||
(require (for-template "kws.ss")
|
(require (for-template "kws.ss")
|
||||||
(for-template scheme/base)
|
(for-template scheme/base)
|
||||||
|
@ -7,9 +6,15 @@
|
||||||
syntax/stx
|
syntax/stx
|
||||||
"../util.ss"
|
"../util.ss"
|
||||||
"rep-data.ss")
|
"rep-data.ss")
|
||||||
(provide parse-pattern
|
|
||||||
parse-pattern-directives)
|
|
||||||
(provide/contract
|
(provide/contract
|
||||||
|
[parse-pattern
|
||||||
|
(->* [any/c #|syntax?|# DeclEnv/c exact-nonnegative-integer?]
|
||||||
|
[boolean?]
|
||||||
|
pattern?)]
|
||||||
|
[parse-pattern-directives
|
||||||
|
(->* [stx-list?]
|
||||||
|
[#:sc? boolean? #:literals (listof identifier?)]
|
||||||
|
(values stx-list? DeclEnv/c RemapEnv/c (listof SideClause/c)))]
|
||||||
[parse-rhs (syntax? boolean? syntax? . -> . rhs?)]
|
[parse-rhs (syntax? boolean? syntax? . -> . rhs?)]
|
||||||
[parse-splice-rhs (syntax? boolean? syntax? . -> . rhs?)])
|
[parse-splice-rhs (syntax? boolean? syntax? . -> . rhs?)])
|
||||||
|
|
||||||
|
@ -282,8 +287,7 @@
|
||||||
|
|
||||||
;; parse-pattern-directives : stxs(PatternDirective) #:literals (listof id)
|
;; parse-pattern-directives : stxs(PatternDirective) #:literals (listof id)
|
||||||
;; -> stx DeclEnv env (listof SideClause)
|
;; -> stx DeclEnv env (listof SideClause)
|
||||||
;; DeclEnv = bound-id-mapping[id => (list* id id (listof stx)) or #t]
|
;; if decls maps a name to #t, it indicates literal
|
||||||
;; if decls maps a name to #f, it indicates literal
|
|
||||||
(define (parse-pattern-directives stx
|
(define (parse-pattern-directives stx
|
||||||
#:sc? [sc? #f]
|
#:sc? [sc? #f]
|
||||||
#:literals [literals null])
|
#:literals [literals null])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user