/collects/syntax/parse/private/sc.rkt
http://github.com/gmarceau/PLT · Racket · 176 lines · 151 code · 18 blank · 7 comment · 8 complexity · f5a32749a01068fb30535a3ea84c6f5c MD5 · raw file
- #lang racket/base
- (require (for-syntax racket/base
- syntax/stx
- racket/syntax
- "rep-data.rkt"
- "rep.rkt")
- "parse.rkt"
- "keywords.rkt"
- "runtime.rkt"
- "runtime-report.rkt")
- (provide define-syntax-class
- define-splicing-syntax-class
- syntax-parse
- syntax-parser
- (except-out (all-from-out "keywords.rkt")
- ~reflect
- ~splicing-reflect
- ~eh-var)
- attribute
- this-syntax
- define/syntax-parse
- ;;----
- syntax-parser/template
- parser/rhs)
- (begin-for-syntax
- (define (defstxclass stx header rhss splicing?)
- (parameterize ((current-syntax-context stx))
- (let-values ([(name formals arity)
- (let ([p (check-stxclass-header header stx)])
- (values (car p) (cadr p) (caddr p)))])
- (let* ([the-rhs (parse-rhs rhss #f splicing? #:context stx)]
- [opt-rhs+def
- (and (andmap identifier? (syntax->list formals))
- (optimize-rhs the-rhs (syntax->list formals)))]
- [the-rhs (if opt-rhs+def (car opt-rhs+def) the-rhs)])
- (with-syntax ([name name]
- [formals formals]
- [rhss rhss]
- [parser (generate-temporary (format-symbol "parse-~a" name))]
- [arity arity]
- [attrs (rhs-attrs the-rhs)]
- [(opt-def ...)
- (if opt-rhs+def
- (list (cadr opt-rhs+def))
- '())]
- [options (rhs-options the-rhs)]
- [integrate-expr
- (syntax-case (rhs-integrate the-rhs) ()
- [#s(integrate predicate description)
- #'(integrate (quote-syntax predicate)
- 'description)]
- [#f
- #''#f])])
- #`(begin (define-syntax name
- (stxclass 'name 'arity
- 'attrs
- (quote-syntax parser)
- '#,splicing?
- options
- integrate-expr))
- opt-def ...
- (define-values (parser)
- ;; If opt-rhs, do not reparse:
- ;; need to keep same generated predicate name
- #,(if opt-rhs+def
- (begin
- ;; (printf "Integrable syntax class: ~s\n" (syntax->datum #'name))
- #`(parser/rhs/parsed
- name formals attrs #,the-rhs
- #,(and (rhs-description the-rhs) #t)
- #,splicing? #,stx))
- #`(parser/rhs
- name formals attrs rhss #,splicing? #,stx))))))))))
- (define-syntax (define-syntax-class stx)
- (syntax-case stx ()
- [(dsc header . rhss)
- (defstxclass stx #'header #'rhss #f)]))
- (define-syntax (define-splicing-syntax-class stx)
- (syntax-case stx ()
- [(dssc header . rhss)
- (defstxclass stx #'header #'rhss #t)]))
- ;; ----
- (define-syntax (parser/rhs stx)
- (syntax-case stx ()
- [(parser/rhs name formals attrs rhss splicing? ctx)
- (with-disappeared-uses
- (let ([rhs
- (parameterize ((current-syntax-context #'ctx))
- (parse-rhs #'rhss (syntax->datum #'attrs) (syntax-e #'splicing?)
- #:context #'ctx))])
- #`(parser/rhs/parsed name formals attrs
- #,rhs #,(and (rhs-description rhs) #t)
- splicing? ctx)))]))
- (define-syntax (parser/rhs/parsed stx)
- (syntax-case stx ()
- [(prp name formals attrs rhs rhs-has-description? splicing? ctx)
- #`(let ([get-description
- (lambda formals
- (if 'rhs-has-description?
- #,(rhs-description (syntax-e #'rhs))
- (symbol->string 'name)))])
- (parse:rhs rhs attrs formals splicing?
- (if 'rhs-has-description?
- #,(rhs-description (syntax-e #'rhs))
- (symbol->string 'name))))]))
- ;; ====
- (define-syntax (syntax-parse stx)
- (syntax-case stx ()
- [(syntax-parse stx-expr . clauses)
- (quasisyntax/loc stx
- (let ([x (datum->syntax #f stx-expr)])
- (parse:clauses x clauses body-sequence #,((make-syntax-introducer) stx))))]))
- (define-syntax (syntax-parser stx)
- (syntax-case stx ()
- [(syntax-parser . clauses)
- (quasisyntax/loc stx
- (lambda (x)
- (let ([x (datum->syntax #f x)])
- (parse:clauses x clauses body-sequence #,((make-syntax-introducer) stx)))))]))
- (define-syntax (syntax-parser/template stx)
- (syntax-case stx ()
- [(syntax-parser/template ctx . clauses)
- (quasisyntax/loc stx
- (lambda (x)
- (let ([x (datum->syntax #f x)])
- (parse:clauses x clauses one-template ctx))))]))
- ;; ====
- (define-syntax (define/syntax-parse stx)
- (syntax-case stx ()
- [(define/syntax-parse pattern . rest)
- (let-values ([(rest pattern defs)
- (parse-pattern+sides #'pattern
- #'rest
- #:splicing? #f
- #:decls (new-declenv null)
- #:context stx)])
- (let ([expr
- (syntax-case rest ()
- [( expr ) #'expr]
- [_ (raise-syntax-error #f "bad syntax" stx)])]
- [attrs (pattern-attrs pattern)])
- (with-syntax ([(a ...) attrs]
- [(#s(attr name _ _) ...) attrs]
- [pattern pattern]
- [(def ...) defs]
- [expr expr])
- #'(defattrs/unpack (a ...)
- (let* ([x expr]
- [cx x]
- [pr (ps-empty x x)]
- [es null]
- [fh0 (syntax-patterns-fail x)])
- def ...
- (#%expression
- (with ([fail-handler fh0]
- [cut-prompt fh0])
- (parse:S x cx pattern pr es
- (list (attribute name) ...)))))))))]))