syntax.scm 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Mike Sperber
  3. ; Syntax used by the compiler
  4. ; Subrecords
  5. ;
  6. ; SUPER is the name of the existing record
  7. ; SUB is the name of the subrecord
  8. ; SLOT is the name of the slot to use in the existing sturcture
  9. ; STUFF is the usual stuff from DEFINE-RECORD-TYPE
  10. (define-syntax define-subrecord
  11. (lambda (form rename compare)
  12. (let ((super (cadr form))
  13. (sub (caddr form))
  14. (slot (cadddr form))
  15. (stuff (cddddr form)))
  16. (let ((access-names (map (lambda (spec)
  17. (if (pair? spec) (car spec) spec))
  18. (append (car stuff) (cadr stuff))))
  19. (set-names (append (filter-map (lambda (spec)
  20. (if (pair? spec) (car spec) #f))
  21. (car stuff))
  22. (map (lambda (spec)
  23. (if (pair? spec) (car spec) spec))
  24. (cadr stuff)))))
  25. `(begin (,(rename 'rk:define-record-type) ,sub . ,stuff)
  26. ,@(map (lambda (name)
  27. `(define ,(concatenate-symbol super '- name)
  28. (lambda (v)
  29. (,(concatenate-symbol sub '- name)
  30. (,slot v)))))
  31. access-names)
  32. ,@(map (lambda (name)
  33. `(define ,(concatenate-symbol 'set- super '- name '!)
  34. (lambda (v n)
  35. (,(concatenate-symbol 'set- sub '- name '!)
  36. (,slot v)
  37. n))))
  38. set-names))))))
  39. ; Subrecords, version for JAR/SRFI-9 records
  40. ; This should eventually replace the above.
  41. ;
  42. ; (define-subrecord-type id type-name super-slot
  43. ; (maker ...)
  44. ; predicate?
  45. ; (slot accessor [modifier])
  46. ; ...)
  47. ;
  48. ; SUPER-SLOT is the name of the slot to use in the existing record.
  49. (define-syntax define-subrecord-type
  50. (lambda (form rename compare)
  51. (let ((id (cadr form))
  52. (type (caddr form))
  53. (slot (cadddr form))
  54. (rest (cddddr form))
  55. (%define-record-type (rename 'define-record-type))
  56. (%define (rename 'define))
  57. (%x (rename 'v))
  58. (%v (rename 'x)))
  59. (let ((maker (car rest))
  60. (pred (cadr rest))
  61. (slots (cddr rest))
  62. (gensym (lambda (s i)
  63. (rename (string->symbol
  64. (string-append (symbol->string s)
  65. "%"
  66. (number->string i)))))))
  67. `(begin
  68. (,%define-record-type ,id ,type
  69. ,maker
  70. ,pred
  71. ,@(do ((slots slots (cdr slots))
  72. (i 0 (+ i 1))
  73. (new '() `((,(caar slots)
  74. ,(gensym 'subrecord-ref i)
  75. ,@(if (null? (cddar slots))
  76. '()
  77. `(,(gensym 'subrecord-set i))))
  78. . ,new)))
  79. ((null? slots)
  80. (reverse new))))
  81. ,@(do ((slots slots (cdr slots))
  82. (i 0 (+ i 1))
  83. (new '() `(,@(if (null? (cddar slots))
  84. '()
  85. `((,%define (,(caddar slots) ,%x ,%v)
  86. (,(gensym 'subrecord-set i)
  87. (,slot ,%x)
  88. ,%v))))
  89. (,%define (,(cadar slots) ,%x)
  90. (,(gensym 'subrecord-ref i)
  91. (,slot ,%x)))
  92. . ,new)))
  93. ((null? slots)
  94. (reverse new))))))))
  95. ;(define-syntax define-simple-record-type
  96. ; (lambda (form rename compare)
  97. ; (let ((name (cadr form))
  98. ; (slots (cddr form)))
  99. ; `(begin (define-record-type ,name ,slots ())
  100. ; (define ,(concatenate-symbol 'make- name)
  101. ; ,(concatenate-symbol name '- 'maker))))))
  102. ; Nothing actually local about it...
  103. (define-syntax define-local-syntax
  104. (lambda (form rename compare)
  105. (let ((pattern (cadr form))
  106. (body (cddr form)))
  107. `(,(rename 'define-syntax) ,(car pattern)
  108. (,(rename 'lambda) (form rename compare)
  109. (,(rename 'destructure) ((,(cdr pattern)
  110. (,(rename 'cdr) form)))
  111. . ,body))))))