syntax-object.scm 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. (library (syntax-object)
  2. ;;(require "utilities.scm")
  3. ;;(require "sets.scm")
  4. (export syx syx? syx-type syx-data syx-metadata
  5. annotate annotate? annotate-syn annotate-set
  6. syx-atomic? syx-id? syx-id syx-special?
  7. syx-scope-set
  8. syn-force
  9. syn-car syn-cdr syn-map
  10. syn->datum)
  11. (import (chezscheme)
  12. (only (chezscheme csv7) record-field-accessor)
  13. (utils) (sets))
  14. ;; This implements a representation of syntax objects
  15. ;;
  16. ;; <syntax> ::= (syx atomic <atomic> ?)
  17. ;; | (syx id|special <symbol> ?)
  18. ;; | ()
  19. ;; | (<syntax> . <syntax>)
  20. ;; | (annotate <syntax> <set>)
  21. ;; (struct syx ((type) (data) (metadata)) #:transparent)
  22. ;; (define-record syx (type data metadata))
  23. (define %syx (make-record-type "syx" '(type data metadata)))
  24. (define syx (record-constructor %syx))
  25. (define syx? (record-predicate %syx))
  26. (define syx-type (record-field-accessor %syx 'type))
  27. (define syx-data (record-field-accessor %syx 'data))
  28. (define syx-metadata (record-field-accessor %syx 'metadata))
  29. ;; (struct annotate ((syn) (set)) #:transparent)
  30. ;; (define-record annotate (syn set))
  31. (define %annotate (make-record-type "annotate" '(syn set)))
  32. (define annotate (record-constructor %annotate))
  33. (define annotate? (record-predicate %annotate))
  34. (define annotate-syn (record-field-accessor %annotate 'syn))
  35. (define annotate-set (record-field-accessor %annotate 'set))
  36. ;;; Simple predicates and projections
  37. ;;
  38. (define (syx-atomic? syn)
  39. (and (syx? syn) (eq? 'atomic (syx-type syn))))
  40. (define (syx-id? syn)
  41. (and (syx? syn) (eq? 'id (syx-type syn))))
  42. (define (syx-id syn)
  43. (unless (syx-id? syn)
  44. (error 'syx-id "invalid input"))
  45. (syx-data syn))
  46. (define (syx-special? syn)
  47. (and (syx? syn) (eq? 'special (syx-type syn))))
  48. (define (syx-scope-set syn)
  49. (cond ((assoc 'set (syx-metadata syn)) => cdr)
  50. (else empty-set)))
  51. ;;; Pushing annotations down lazy syntax
  52. ;;
  53. (define (syx-apply e set)
  54. (case (syx-type e)
  55. ((atomic) e)
  56. ((id) (syx (syx-type e)
  57. (syx-data e)
  58. (assoc-replace (syx-metadata e)
  59. 'set
  60. (set-union set (syx-scope-set e)))))
  61. ((special) e)
  62. (else (error 'syx-apply "unknown type" (syx-type e)))))
  63. (define (syn-apply syn set)
  64. (cond ((syx? syn) (syx-apply syn set))
  65. ((null? syn) syn)
  66. ((pair? syn) (cons (syn-apply (car syn) set)
  67. (syn-apply (cdr syn) set)))
  68. ((annotate? syn)
  69. (syn-apply (annotate-syn syn)
  70. (set-union set (annotate-set syn))))
  71. (else (error 'syn-apply "unknown type" syn))))
  72. (define (syn-force s)
  73. (if (annotate? s)
  74. (let ((syn (annotate-syn s))
  75. (set (annotate-set s)))
  76. (syn-apply syn set))
  77. s))
  78. (define (syn-car e) (car (syn-force e)))
  79. (define (syn-cdr e) (cdr (syn-force e)))
  80. (define (syn-map f l)
  81. (let ((e (syn-force l)))
  82. (if (null? l)
  83. '()
  84. (cons (f (car l))
  85. (syn-map f (cdr l))))))
  86. ;;; Present it without lots of noise for debugging
  87. ;;
  88. (define (syn->datum syn)
  89. (cond ((syx? syn) (syx-data syn))
  90. ((null? syn) syn)
  91. ((pair? syn) (cons (syn->datum (car syn))
  92. (syn->datum (cdr syn))))
  93. ((annotate? syn) (syn->datum (annotate-syn syn)))
  94. ((symbol? syn) syn) ;; raw symbols are allowed inside quote
  95. (else (error 'syn->datum "unknown type" syn))))
  96. )