got started on the ->i parser
This commit is contained in:
parent
3c70b9d2ab
commit
561ac12a91
114
collects/racket/contract/private/arr-i-parse.rkt
Normal file
114
collects/racket/contract/private/arr-i-parse.rkt
Normal file
|
@ -0,0 +1,114 @@
|
|||
#lang racket/base
|
||||
#|
|
||||
|
||||
The ->i contract first parses its input into an istx struct
|
||||
and then operates on it to generate the expanded form
|
||||
|
||||
|#
|
||||
|
||||
;; doms : (listof arg?)
|
||||
;; pre : (or/c stx[expr] #f)
|
||||
;; rngs : (listof res?)
|
||||
;; rest : (or/c #f rst?)
|
||||
;; post : (or/c stx[expr] #f)
|
||||
(define-struct istx (doms pre rngs rest post))
|
||||
|
||||
;; var : identifier?
|
||||
;; vars : (or/c #f (listof identifier?))
|
||||
;; ctc : syntax[expr]
|
||||
(define-struct res (var vars ctc))
|
||||
|
||||
;; kwd : (or/c #f syntax[kwd])
|
||||
;; var : identifier?
|
||||
;; vars : (or/c #f (listof identifier?))
|
||||
;; optional? : boolean?
|
||||
;; ctc : syntax[expr]
|
||||
(define-struct arg (kwd var vars optional? ctc))
|
||||
|
||||
;; var : identifier?
|
||||
;; vars : (or/c #f (listof identifier?))
|
||||
;; ctc : syntax[expr]
|
||||
(define-struct rst (var vars ctc))
|
||||
|
||||
(define (parse-->i stx)
|
||||
(let-values ([(raw-mandatory-doms raw-optional-doms id/rest-id pre-cond range post-cond)
|
||||
(pull-out-pieces stx)])
|
||||
(make-istx (append (map parse-dom raw-mandatory-doms)
|
||||
(map parse-dom raw-optional-doms))
|
||||
pre-cond
|
||||
range
|
||||
rest
|
||||
post)))
|
||||
|
||||
;; pull-out-pieces : stx -> (values raw-mandatory-doms raw-optional-doms id/rest-id pre-cond range post-cond)
|
||||
(define (pull-out-pieces stx)
|
||||
(let*-values ([(raw-mandatory-doms leftover)
|
||||
(syntax-case stx ()
|
||||
[((raw-mandatory-doms ...) . leftover)
|
||||
(values (syntax->list #'(raw-mandatory-doms ...))
|
||||
#'leftover)]
|
||||
[(a . leftover)
|
||||
(raise-syntax-error #f "expected a sequence of mandatory domain elements" stx #'a)]
|
||||
[_
|
||||
(raise-syntax-error #f "expected a sequence of mandatory domain elements" stx)])]
|
||||
[(raw-optional-doms leftover)
|
||||
(syntax-case leftover ()
|
||||
[(kwd . leftover2)
|
||||
(keyword? (syntax-e #'kwd))
|
||||
(values '() leftover)]
|
||||
[(dep-range)
|
||||
(values '() leftover)]
|
||||
[(dep-range #:post-cond expr)
|
||||
(values '() leftover)]
|
||||
[((opts ...) . rest)
|
||||
(values #'(opts ...) #'rest)]
|
||||
[_ (values '() leftover)])]
|
||||
[(id/rest-id leftover)
|
||||
(syntax-case leftover ()
|
||||
[(#:rest id rest-expr . leftover)
|
||||
(and (identifier? #'id)
|
||||
(not (keyword? (syntax-e #'rest-expr))))
|
||||
(values #'(id rest-expr) #'leftover)]
|
||||
[(#:rest id (id2 ...) rest-expr . leftover)
|
||||
(and (identifier? #'id)
|
||||
(andmap identifier? (syntax->list #'(id2 ...)))
|
||||
(not (keyword? (syntax-e #'rest-expr))))
|
||||
(values #'(id rest-expr) #'leftover)]
|
||||
[(#:rest id rest-expr . leftover)
|
||||
(begin
|
||||
(unless (identifier? #'id)
|
||||
(raise-syntax-error #f "expected an identifier" stx #'id))
|
||||
(when (keyword? (syntax-e #'rest-expr))
|
||||
(raise-syntax-error #f "expected an expression, not a keyword" stx #'rest-expr)))]
|
||||
[_ (values #f leftover)])]
|
||||
[(pre-cond leftover)
|
||||
(syntax-case leftover ()
|
||||
[(#:pre-cond pre-cond . leftover)
|
||||
(values #'pre-cond #'leftover)]
|
||||
[_ (values #f leftover)])]
|
||||
[(range leftover)
|
||||
(syntax-case leftover ()
|
||||
[(range . leftover) (values #'range #'leftover)]
|
||||
[_
|
||||
(raise-syntax-error #f "expected a range expression, but found nothing" stx)])]
|
||||
[(post-cond leftover)
|
||||
(syntax-case leftover ()
|
||||
[(#:post-cond post-cond . leftover)
|
||||
(begin
|
||||
(syntax-case range (any)
|
||||
[any (raise-syntax-error #f "cannot have a #:post-cond with any as the range" stx #'post-cond)]
|
||||
[_ (void)])
|
||||
(values #'post-cond #'leftover))]
|
||||
[_ (values #f leftover)])])
|
||||
(syntax-case leftover ()
|
||||
[()
|
||||
(values raw-mandatory-doms raw-optional-doms id/rest-id pre-cond range post-cond)]
|
||||
[_
|
||||
(raise-syntax-error #f "bad syntax" stx)])))
|
||||
|
||||
(provide
|
||||
parse-->i
|
||||
(struct-out istx)
|
||||
(struct-out res)
|
||||
(struct-out arg)
|
||||
(struct-out rst))
|
Loading…
Reference in New Issue
Block a user