/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

  1. #lang racket/base
  2. (require (for-syntax racket/base
  3. syntax/stx
  4. racket/syntax
  5. "rep-data.rkt"
  6. "rep.rkt")
  7. "parse.rkt"
  8. "keywords.rkt"
  9. "runtime.rkt"
  10. "runtime-report.rkt")
  11. (provide define-syntax-class
  12. define-splicing-syntax-class
  13. syntax-parse
  14. syntax-parser
  15. (except-out (all-from-out "keywords.rkt")
  16. ~reflect
  17. ~splicing-reflect
  18. ~eh-var)
  19. attribute
  20. this-syntax
  21. define/syntax-parse
  22. ;;----
  23. syntax-parser/template
  24. parser/rhs)
  25. (begin-for-syntax
  26. (define (defstxclass stx header rhss splicing?)
  27. (parameterize ((current-syntax-context stx))
  28. (let-values ([(name formals arity)
  29. (let ([p (check-stxclass-header header stx)])
  30. (values (car p) (cadr p) (caddr p)))])
  31. (let* ([the-rhs (parse-rhs rhss #f splicing? #:context stx)]
  32. [opt-rhs+def
  33. (and (andmap identifier? (syntax->list formals))
  34. (optimize-rhs the-rhs (syntax->list formals)))]
  35. [the-rhs (if opt-rhs+def (car opt-rhs+def) the-rhs)])
  36. (with-syntax ([name name]
  37. [formals formals]
  38. [rhss rhss]
  39. [parser (generate-temporary (format-symbol "parse-~a" name))]
  40. [arity arity]
  41. [attrs (rhs-attrs the-rhs)]
  42. [(opt-def ...)
  43. (if opt-rhs+def
  44. (list (cadr opt-rhs+def))
  45. '())]
  46. [options (rhs-options the-rhs)]
  47. [integrate-expr
  48. (syntax-case (rhs-integrate the-rhs) ()
  49. [#s(integrate predicate description)
  50. #'(integrate (quote-syntax predicate)
  51. 'description)]
  52. [#f
  53. #''#f])])
  54. #`(begin (define-syntax name
  55. (stxclass 'name 'arity
  56. 'attrs
  57. (quote-syntax parser)
  58. '#,splicing?
  59. options
  60. integrate-expr))
  61. opt-def ...
  62. (define-values (parser)
  63. ;; If opt-rhs, do not reparse:
  64. ;; need to keep same generated predicate name
  65. #,(if opt-rhs+def
  66. (begin
  67. ;; (printf "Integrable syntax class: ~s\n" (syntax->datum #'name))
  68. #`(parser/rhs/parsed
  69. name formals attrs #,the-rhs
  70. #,(and (rhs-description the-rhs) #t)
  71. #,splicing? #,stx))
  72. #`(parser/rhs
  73. name formals attrs rhss #,splicing? #,stx))))))))))
  74. (define-syntax (define-syntax-class stx)
  75. (syntax-case stx ()
  76. [(dsc header . rhss)
  77. (defstxclass stx #'header #'rhss #f)]))
  78. (define-syntax (define-splicing-syntax-class stx)
  79. (syntax-case stx ()
  80. [(dssc header . rhss)
  81. (defstxclass stx #'header #'rhss #t)]))
  82. ;; ----
  83. (define-syntax (parser/rhs stx)
  84. (syntax-case stx ()
  85. [(parser/rhs name formals attrs rhss splicing? ctx)
  86. (with-disappeared-uses
  87. (let ([rhs
  88. (parameterize ((current-syntax-context #'ctx))
  89. (parse-rhs #'rhss (syntax->datum #'attrs) (syntax-e #'splicing?)
  90. #:context #'ctx))])
  91. #`(parser/rhs/parsed name formals attrs
  92. #,rhs #,(and (rhs-description rhs) #t)
  93. splicing? ctx)))]))
  94. (define-syntax (parser/rhs/parsed stx)
  95. (syntax-case stx ()
  96. [(prp name formals attrs rhs rhs-has-description? splicing? ctx)
  97. #`(let ([get-description
  98. (lambda formals
  99. (if 'rhs-has-description?
  100. #,(rhs-description (syntax-e #'rhs))
  101. (symbol->string 'name)))])
  102. (parse:rhs rhs attrs formals splicing?
  103. (if 'rhs-has-description?
  104. #,(rhs-description (syntax-e #'rhs))
  105. (symbol->string 'name))))]))
  106. ;; ====
  107. (define-syntax (syntax-parse stx)
  108. (syntax-case stx ()
  109. [(syntax-parse stx-expr . clauses)
  110. (quasisyntax/loc stx
  111. (let ([x (datum->syntax #f stx-expr)])
  112. (parse:clauses x clauses body-sequence #,((make-syntax-introducer) stx))))]))
  113. (define-syntax (syntax-parser stx)
  114. (syntax-case stx ()
  115. [(syntax-parser . clauses)
  116. (quasisyntax/loc stx
  117. (lambda (x)
  118. (let ([x (datum->syntax #f x)])
  119. (parse:clauses x clauses body-sequence #,((make-syntax-introducer) stx)))))]))
  120. (define-syntax (syntax-parser/template stx)
  121. (syntax-case stx ()
  122. [(syntax-parser/template ctx . clauses)
  123. (quasisyntax/loc stx
  124. (lambda (x)
  125. (let ([x (datum->syntax #f x)])
  126. (parse:clauses x clauses one-template ctx))))]))
  127. ;; ====
  128. (define-syntax (define/syntax-parse stx)
  129. (syntax-case stx ()
  130. [(define/syntax-parse pattern . rest)
  131. (let-values ([(rest pattern defs)
  132. (parse-pattern+sides #'pattern
  133. #'rest
  134. #:splicing? #f
  135. #:decls (new-declenv null)
  136. #:context stx)])
  137. (let ([expr
  138. (syntax-case rest ()
  139. [( expr ) #'expr]
  140. [_ (raise-syntax-error #f "bad syntax" stx)])]
  141. [attrs (pattern-attrs pattern)])
  142. (with-syntax ([(a ...) attrs]
  143. [(#s(attr name _ _) ...) attrs]
  144. [pattern pattern]
  145. [(def ...) defs]
  146. [expr expr])
  147. #'(defattrs/unpack (a ...)
  148. (let* ([x expr]
  149. [cx x]
  150. [pr (ps-empty x x)]
  151. [es null]
  152. [fh0 (syntax-patterns-fail x)])
  153. def ...
  154. (#%expression
  155. (with ([fail-handler fh0]
  156. [cut-prompt fh0])
  157. (parse:S x cx pattern pr es
  158. (list (attribute name) ...)))))))))]))