PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/kits/scc/record.sc

http://github.com/pablomarx/Thomas
Scala | 184 lines | 163 code | 21 blank | 0 comment | 2 complexity | 1ad867d5166b9dd81b4fd3cf8bc1cb6d MD5 | raw file
  1. ; -*-Scheme-*-
  2. ;
  3. ; $Id: scc_record.sc,v 1.2 1992/09/23 15:32:13 birkholz Exp $
  4. ; $MIT-Header: /scheme/users/cph/src/runtime/RCS/record.scm,v 1.12 1991/11/26 06:50:09 cph Exp $
  5. ;
  6. ; Copyright (c) 1989-91 Massachusetts Institute of Technology
  7. ;
  8. ; This material was developed by the Scheme project at the Massachusetts
  9. ; Institute of Technology, Department of Electrical Engineering and
  10. ; Computer Science. Permission to copy this software, to redistribute
  11. ; it, and to use it for any purpose is granted, subject to the following
  12. ; restrictions and understandings.
  13. ;
  14. ; 1. Any copy made of this software must include this copyright notice
  15. ; in full.
  16. ;
  17. ; 2. Users of this software agree to make their best efforts (a) to
  18. ; return to the MIT Scheme project any improvements or extensions that
  19. ; they make, so that these may be included in future releases; and (b)
  20. ; to inform MIT of noteworthy uses of this software.
  21. ;
  22. ; 3. All materials developed as a consequence of the use of this
  23. ; software shall duly acknowledge such use, in accordance with the usual
  24. ; standards of acknowledging credit in academic research.
  25. ;
  26. ; 4. MIT has made no warrantee or representation that the operation of
  27. ; this software will be error-free, and MIT is under no obligation to
  28. ; provide any services, by way of maintenance, update, or otherwise.
  29. ;
  30. ; 5. In conjunction with products arising from the use of this material,
  31. ; there shall be no use of the name of the Massachusetts Institute of
  32. ; Technology nor of any adaptation thereof in any advertising,
  33. ; promotional, or sales literature without prior written consent from
  34. ; MIT in each case.
  35. ; This file requires the following non-IEEE primitives:
  36. ; error:wrong-type-argument and error:bad-range-argument each signal Scheme
  37. ; conditions indicating an argument of the wrong type or invalid value
  38. ; (respectively).
  39. ;;;; Implementations of these procedures for Scheme->C
  40. (define (error:wrong-type-argument record-type expected-type procedure)
  41. (error 'record-package "~s ~s~%"
  42. (string-append (symbol->string procedure)
  43. ": wrong argument type. Expected "
  44. expected-type
  45. ", got ")
  46. record-type))
  47. (define (error:bad-range-argument field-name procedure-name)
  48. (error 'record-package "~s ~s~%"
  49. (string-append (symbol->string procedure-name)
  50. ": unknown field name")
  51. field-name))
  52. ;;;; Records
  53. ;;; adapted from JAR's implementation
  54. ;;; conforms to R4RS proposal
  55. (define record-type-marker
  56. (string->symbol "#[(runtime record)record-type-marker]"))
  57. (define (make-record-type type-name field-names)
  58. (vector record-type-marker type-name (map (lambda (x) x) field-names)))
  59. (define (record-type? object)
  60. (and (vector? object)
  61. (= (vector-length object) 3)
  62. (eq? (vector-ref object 0) record-type-marker)))
  63. (define (record-type-name record-type)
  64. (if (not (record-type? record-type))
  65. (error:wrong-type-argument record-type "record type" 'RECORD-TYPE-NAME))
  66. (vector-ref record-type 1))
  67. (define (record-type-field-names record-type)
  68. (if (not (record-type? record-type))
  69. (error:wrong-type-argument record-type "record type"
  70. 'RECORD-TYPE-FIELD-NAMES))
  71. (map (lambda (x) x) (vector-ref record-type 2)))
  72. (define (record-type-record-length record-type)
  73. (+ (length (vector-ref record-type 2)) 1))
  74. (define (record-type-field-index record-type field-name procedure-name)
  75. (let loop ((field-names (vector-ref record-type 2)) (index 1))
  76. (if (null? field-names)
  77. (error:bad-range-argument field-name procedure-name))
  78. (if (eq? field-name (car field-names))
  79. index
  80. (loop (cdr field-names) (+ index 1)))))
  81. (define (record-type-error record record-type procedure)
  82. (error:wrong-type-argument
  83. record
  84. (string-append "record of type "
  85. (let ((type-name (vector-ref record-type 1)))
  86. (cond ((string? type-name) type-name)
  87. ((symbol? type-name) type-name)
  88. (else "<<unknown data type for name>>"))))
  89. procedure))
  90. (define (record-constructor record-type . field-names)
  91. (if (not (record-type? record-type))
  92. (error:wrong-type-argument record-type "record type"
  93. 'RECORD-CONSTRUCTOR))
  94. (let ((field-names
  95. (if (null? field-names)
  96. (vector-ref record-type 2)
  97. (car field-names))))
  98. (let ((record-length (record-type-record-length record-type))
  99. (number-of-inits (length field-names))
  100. (indexes
  101. (map (lambda (field-name)
  102. (record-type-field-index record-type
  103. field-name
  104. 'RECORD-CONSTRUCTOR))
  105. field-names)))
  106. (lambda field-values
  107. (if (not (= (length field-values) number-of-inits))
  108. (error "wrong number of arguments to record constructor"
  109. field-values record-type field-names))
  110. (let ((record (make-vector record-length)))
  111. (vector-set! record 0 record-type)
  112. (for-each (lambda (index value) (vector-set! record index value))
  113. indexes
  114. field-values)
  115. record)))))
  116. (define (record? object)
  117. (and (vector? object)
  118. (> (vector-length object) 0)
  119. (record-type? (vector-ref object 0))))
  120. (define (record-type-descriptor record)
  121. (if (not (record? record))
  122. (error:wrong-type-argument record "record" 'RECORD-TYPE-DESCRIPTOR))
  123. (vector-ref record 0))
  124. (define (record-copy record)
  125. (list->vector (vector->list record)))
  126. (define (record-predicate record-type)
  127. (if (not (record-type? record-type))
  128. (error:wrong-type-argument record-type "record type" 'RECORD-PREDICATE))
  129. (let ((record-length (record-type-record-length record-type)))
  130. (lambda (object)
  131. (and (vector? object)
  132. (= (vector-length object) record-length)
  133. (eq? (vector-ref object 0) record-type)))))
  134. (define (record-accessor record-type field-name)
  135. (if (not (record-type? record-type))
  136. (error:wrong-type-argument record-type "record type" 'RECORD-ACCESSOR))
  137. (let ((record-length (record-type-record-length record-type))
  138. (procedure-name `(RECORD-ACCESSOR ,record-type ',field-name))
  139. (index
  140. (record-type-field-index record-type field-name 'RECORD-ACCESSOR)))
  141. (lambda (record)
  142. (if (not (and (vector? record)
  143. (= (vector-length record) record-length)
  144. (eq? (vector-ref record 0) record-type)))
  145. (record-type-error record record-type procedure-name))
  146. (vector-ref record index))))
  147. (define (record-modifier record-type field-name)
  148. (if (not (record-type? record-type))
  149. (error:wrong-type-argument record-type "record type" 'RECORD-UPDATER))
  150. (let ((record-length (record-type-record-length record-type))
  151. (procedure-name `(RECORD-UPDATER ,record-type ',field-name))
  152. (index
  153. (record-type-field-index record-type field-name 'RECORD-UPDATER)))
  154. (lambda (record field-value)
  155. (if (not (and (vector? record)
  156. (= (vector-length record) record-length)
  157. (eq? (vector-ref record 0) record-type)))
  158. (record-type-error record record-type procedure-name))
  159. (vector-set! record index field-value))))
  160. (define record-updater
  161. record-modifier)