jar-defrecord.scm 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber, Robert Ransom
  3. ; This knows about the implementation of records and creates the various
  4. ; accessors, mutators, etc. directly instead of calling the procedures
  5. ; from the record structure. This is done to allow the optional auto-inlining
  6. ; optimizer to inline the accessors, mutators, etc.
  7. ; LOOPHOLE is used to get a little compile-time type checking (in addition to
  8. ; the usual complete run-time checking).
  9. (define-syntax define-record-type
  10. (syntax-rules ()
  11. ((define-record-type ?type ; compatibility with SRFI 9
  12. (?constructor ?arg ...) . ?more)
  13. (define-record-type ?type ?type
  14. (?constructor ?arg ...) . ?more))
  15. ((define-record-type ?id ?type
  16. (?constructor ?arg ...)
  17. (?field . ?field-stuff)
  18. ...)
  19. (begin (define ?type (make-record-type '?id '(?field ...)))
  20. (define-constructor ?constructor ?type
  21. ((?arg :value) ...)
  22. (?field ...))
  23. (define-accessors ?type () (?field . ?field-stuff) ...)))
  24. ((define-record-type ?id ?type
  25. (?constructor ?arg ...)
  26. ?pred
  27. ?more ...)
  28. (begin (define-record-type ?id ?type
  29. (?constructor ?arg ...)
  30. ?more ...)
  31. (define ?pred
  32. (lambda (x)
  33. (and (record? x)
  34. (record-type<=? (record-ref x 0) ?type))))))))
  35. (define-syntax define-synchronized-record-type
  36. (syntax-rules ()
  37. ((define-synchronized-record-type ?id ?type
  38. (?constructor ?arg ...)
  39. ?pred
  40. (?field . ?field-stuff)
  41. ...)
  42. (define-synchronized-record-type ?id ?type
  43. (?constructor ?arg ...)
  44. (?field ...)
  45. ?pred
  46. (?field . ?field-stuff)
  47. ...))
  48. ((define-synchronized-record-type ?id ?type
  49. (?constructor ?arg ...)
  50. (?sync-field ...)
  51. ?pred
  52. (?field . ?field-stuff)
  53. ...)
  54. (begin (define ?type (make-record-type '?id '(?field ...)))
  55. (define-constructor ?constructor ?type
  56. ((?arg :value) ...)
  57. (?field ...))
  58. (define ?pred
  59. (lambda (x)
  60. (and (record? x)
  61. (eq? ?type (record-ref x 0)))))
  62. (define-accessors ?type (?sync-field ...)
  63. (?field . ?field-stuff) ...)))))
  64. ; (define-constructor <id> <type> ((<arg> <arg-type>)*) (<field-name>*))
  65. ;
  66. ; Checks to see that there is a <field-name> corresponding to every <arg>.
  67. (define-syntax define-constructor
  68. (lambda (e r c)
  69. (let ((%record (r 'record))
  70. (%begin (r 'begin))
  71. (%lambda (r 'lambda))
  72. (%loophole (r 'loophole))
  73. (%proc (r 'proc))
  74. (%unspecific (r 'unspecific))
  75. (name (cadr e))
  76. (type (caddr e))
  77. (args (map r (map car (cadddr e))))
  78. (arg-types (map cadr (cadddr e)))
  79. (fields (map r (caddr (cddr e)))))
  80. (define (mem? name list)
  81. (cond ((null? list) #f)
  82. ((c name (car list)) #t)
  83. (else
  84. (mem? name (cdr list)))))
  85. (define (every? pred list)
  86. (cond ((null? list) #t)
  87. ((pred (car list))
  88. (every? pred (cdr list)))
  89. (else #f)))
  90. (if (every? (lambda (arg)
  91. (mem? arg fields))
  92. args)
  93. `(define ,name
  94. (,%loophole (,%proc ,arg-types ,type)
  95. (,%lambda ,args
  96. (,%record ,type . ,(map (lambda (field)
  97. (if (mem? field args)
  98. field
  99. (list %unspecific)))
  100. fields)))))
  101. e)))
  102. (record begin lambda loophole proc unspecific))
  103. (define-syntax define-accessors
  104. (lambda (e r c)
  105. (let ((%define-accessor (r 'define-accessor))
  106. (%begin (r 'begin))
  107. (type (cadr e))
  108. (sync-fields (caddr e))
  109. (field-specs (cdddr e)))
  110. (define (mem? name list)
  111. (cond ((null? list) #f)
  112. ((c name (car list)) #t)
  113. (else
  114. (mem? name (cdr list)))))
  115. (do ((i 1 (+ i 1))
  116. (field-specs field-specs (cdr field-specs))
  117. (ds '()
  118. (cons `(,%define-accessor
  119. ,(mem? (caar field-specs)
  120. sync-fields)
  121. ,type ,i ,@(cdar field-specs))
  122. ds)))
  123. ((null? field-specs)
  124. `(,%begin ,@ds)))))
  125. (define-accessor begin))
  126. (define-syntax define-accessor
  127. (syntax-rules ()
  128. ((define-accessor ?sync? ?type ?index ?accessor)
  129. (define ?accessor
  130. (loophole (proc (?type) :value)
  131. (lambda (r)
  132. ((ref-proc ?sync?) (loophole :record r) ?type ?index)))))
  133. ((define-accessor ?sync? ?type ?index ?accessor ?modifier)
  134. (begin (define-accessor ?sync? ?type ?index ?accessor)
  135. (define ?modifier
  136. (loophole (proc (?type :value) :unspecific)
  137. (lambda (r new)
  138. ((set-proc ?sync?)
  139. (loophole :record r) ?type ?index new))))))
  140. ((define-accessor ?sync? ?type ?index)
  141. (begin))))
  142. (define-syntax ref-proc
  143. (syntax-rules ()
  144. ((ref-proc #t)
  145. provisional-checked-record-ref)
  146. ((ref-proc #f)
  147. checked-record-ref)))
  148. (define-syntax set-proc
  149. (syntax-rules ()
  150. ((set-proc #t)
  151. provisional-checked-record-set!)
  152. ((set-proc #f)
  153. checked-record-set!)))