/racket-5-0-2-bin-i386-osx-mac-dmg/collects/syntax/parse/experimental/splicing.rkt

http://github.com/smorin/f4f.arc · Racket · 86 lines · 80 code · 5 blank · 1 comment · 9 complexity · 90ef137cbb28731b76a47971587a9aed MD5 · raw file

  1. #lang racket/base
  2. (require (for-syntax racket/base
  3. "../../parse.ss"
  4. "../private/rep-data.rkt"
  5. "../private/kws.rkt")
  6. "../private/runtime.rkt")
  7. (provide define-primitive-splicing-syntax-class)
  8. (define-syntax (define-primitive-splicing-syntax-class stx)
  9. (define-syntax-class attr
  10. (pattern name:id
  11. #:with depth #'0)
  12. (pattern [name:id depth:nat]))
  13. (syntax-parse stx
  14. [(dssp (name:id param:id ...)
  15. (~or (~once (~seq #:attributes (a:attr ...))
  16. #:name "attributes declaration")
  17. (~once (~seq #:description description)
  18. #:name "description declaration")) ...
  19. proc:expr)
  20. #'(begin
  21. (define (get-description param ...)
  22. description)
  23. (define parser
  24. (let ([permute (mk-permute '(a.name ...))])
  25. (lambda (x cx pr es fh cp success param ...)
  26. (let ([stx (datum->syntax cx x cx)])
  27. (let ([result
  28. (let/ec escape
  29. (cons 'ok
  30. (proc stx
  31. (lambda ([msg #f] [stx #f])
  32. (escape (list 'error msg stx))))))])
  33. (case (car result)
  34. ((ok)
  35. (apply success
  36. ((mk-check-result pr 'name (length '(a.name ...)) permute x cx fh cp)
  37. (cdr result))))
  38. ((error)
  39. (let ([es
  40. (list* (cons (expect:thing (get-description param ...) #f) stx)
  41. (cons (expect:message (cadr result)) (caddr result))
  42. es)])
  43. (fh (failure pr es))))))))))
  44. (define-syntax name
  45. (stxclass 'name (arity (length '(param ...)) (length '(param ...)) '() '())
  46. (sort-sattrs '(#s(attr a.name a.depth #f) ...))
  47. (quote-syntax parser)
  48. #t
  49. #s(options #t #t)
  50. #f)))]))
  51. (define (mk-permute unsorted-attrs)
  52. (let ([sorted-attrs
  53. (sort unsorted-attrs string<? #:key symbol->string #:cache-keys? #t)])
  54. (if (equal? unsorted-attrs sorted-attrs)
  55. values
  56. (let* ([pos-table
  57. (for/hasheq ([a (in-list unsorted-attrs)] [i (in-naturals)])
  58. (values a i))]
  59. [indexes
  60. (for/vector ([a (in-list sorted-attrs)])
  61. (hash-ref pos-table a))])
  62. (lambda (result)
  63. (for/list ([index (in-vector indexes)])
  64. (list-ref result index)))))))
  65. (define (mk-check-result pr name attr-count permute x cx fh cp)
  66. (lambda (result)
  67. (unless (list? result)
  68. (error name "parser returned non-list"))
  69. (let ([rlength (length result)])
  70. (unless (= rlength (+ 1 attr-count))
  71. (error name "parser returned list of wrong length; expected length ~s, got ~e"
  72. (+ 1 attr-count)
  73. result))
  74. (let ([skip (car result)])
  75. ;; Compute rest-x & rest-cx from skip
  76. (unless (exact-nonnegative-integer? skip)
  77. (error name "expected exact nonnegative integer for first element of result list, got ~e"
  78. skip))
  79. (let-values ([(rest-x rest-cx) (stx-list-drop/cx x cx skip)])
  80. (list* fh cp rest-x rest-cx (ps-add-cdr pr skip)
  81. (permute (cdr result))))))))