type.scm 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Mike Sperber
  3. (define-record-type base-type :base-type
  4. (really-make-base-type name uid)
  5. base-type?
  6. (name base-type-name)
  7. (uid base-type-uid)) ; an integer
  8. (define-record-discloser :base-type
  9. (lambda (base-type)
  10. (list (base-type-name base-type)
  11. (base-type-uid base-type))))
  12. (define *next-base-type-uid* 0)
  13. (define (next-base-type-uid)
  14. (let ((x *next-base-type-uid*))
  15. (set! *next-base-type-uid* (+ x 1))
  16. x))
  17. (define base-type-table (make-table))
  18. (define (make-base-type name)
  19. (let ((type (really-make-base-type name (next-base-type-uid))))
  20. (table-set! base-type-table name type)
  21. type))
  22. (define (lookup-type id)
  23. (cond ((table-ref base-type-table id)
  24. => identity)
  25. (else #f)))
  26. (define type/integer (make-base-type 'integer))
  27. (define type/unsigned-integer (make-base-type 'unsigned-integer))
  28. (define type/float (make-base-type 'float))
  29. (define type/null (make-base-type 'null)) ; no value
  30. (define type/unit (make-base-type 'unit)) ; single value
  31. (define type/boolean (make-base-type 'boolean))
  32. (define type/undetermined (make-base-type '?))
  33. (define type/input-port (make-base-type 'input-port))
  34. (define type/output-port (make-base-type 'output-port))
  35. (define type/address (make-base-type 'address))
  36. (define type/char (make-base-type 'char))
  37. (define (make-atomic-type name)
  38. (really-make-base-type name (next-base-type-uid)))
  39. (define type/unknown type/undetermined) ; an alias
  40. (define (type-name type)
  41. (if (base-type? type)
  42. (base-type-name type)
  43. (error "type has no name ~S" type)))
  44. (define (make-base-type-table)
  45. (let ((elts (make-vector *next-base-type-uid* #f)))
  46. (values (lambda (type)
  47. (vector-ref elts (base-type-uid type)))
  48. (lambda (type value)
  49. (vector-set! elts (base-type-uid type) value)))))
  50. ;--------------------------------------------------
  51. ; This won't terminate on recursive types.
  52. (define (type-eq? type1 type2)
  53. (let ((type1 (maybe-follow-uvar type1))
  54. (type2 (maybe-follow-uvar type2)))
  55. (or (eq? type1 type2)
  56. (and (other-type? type1)
  57. (other-type? type2)
  58. (eq? (other-type-kind type1)
  59. (other-type-kind type2))
  60. (let loop ((l1 (other-type-subtypes type1))
  61. (l2 (other-type-subtypes type2)))
  62. (cond ((null? l1) (null? l2))
  63. ((null? l2) #f)
  64. ((type-eq? (car l1) (car l2))
  65. (loop (cdr l1) (cdr l2)))
  66. (else #f)))))))
  67. ;--------------------------------------------------
  68. ; Arrow and pointer types (and perhaps others later)
  69. ; All done together to simplify the type walking
  70. (define-record-type other-type :other-type
  71. (really-make-other-type kind subtypes finalized?)
  72. other-type?
  73. (kind other-type-kind)
  74. (subtypes other-type-subtypes set-other-type-subtypes!) ; set when finalized
  75. (finalized? other-type-finalized? set-other-type-finalized?!))
  76. (define (make-other-type kind subtypes)
  77. (really-make-other-type kind subtypes #f))
  78. (define-record-discloser :other-type
  79. (lambda (type)
  80. (case (other-type-kind type)
  81. ((arrow)
  82. (list 'arrow-type
  83. (arrow-type-args type)
  84. (arrow-type-result type)))
  85. (else
  86. (cons (other-type-kind type)
  87. (other-type-subtypes type))))))
  88. (define (make-other-type-predicate kind)
  89. (lambda (x)
  90. (and (other-type? x)
  91. (eq? kind (other-type-kind x)))))
  92. ; Arrow
  93. (define (make-arrow-type args result)
  94. (make-other-type 'arrow (cons result args)))
  95. (define arrow-type? (make-other-type-predicate 'arrow))
  96. (define (arrow-type-args type)
  97. (cdr (other-type-subtypes type)))
  98. (define (arrow-type-result type)
  99. (car (other-type-subtypes type)))
  100. ; Pointer
  101. (define (make-pointer-type type)
  102. (make-other-type 'pointer (list type)))
  103. (define pointer-type? (make-other-type-predicate 'pointer))
  104. (define (pointer-type-to pointer-type)
  105. (car (other-type-subtypes pointer-type)))
  106. (define type/string (make-pointer-type type/char))
  107. ; Tuple (used for arguments and returning multiple values)
  108. (define (make-tuple-type types)
  109. (if (and (not (null? types))
  110. (null? (cdr types)))
  111. (car types)
  112. (make-other-type 'tuple types)))
  113. (define tuple-type? (make-other-type-predicate 'tuple))
  114. (define (tuple-type-types type)
  115. (other-type-subtypes type))
  116. ;--------------------------------------------------
  117. (define (finalize-type type)
  118. (let ((type (maybe-follow-uvar type)))
  119. (cond ((and (other-type? type)
  120. (not (other-type-finalized? type)))
  121. (let ((subs (other-type-subtypes type)))
  122. (set-other-type-finalized?! type #t)
  123. (set-other-type-subtypes! type (map finalize-type subs))))
  124. ((and (uvar? type)
  125. (uvar-tuple-okay? type)) ; unused return value
  126. (bind-uvar! type type/unit)))
  127. type))
  128. ;--------------------------------------------------
  129. (define (expand-type-spec spec)
  130. (cond ((pair? spec)
  131. (case (car spec)
  132. ((=>)
  133. (make-arrow-type (map expand-type-spec (cadr spec))
  134. (make-tuple-type (map expand-type-spec
  135. (cddr spec)))))
  136. ((^)
  137. (make-pointer-type (expand-type-spec (cadr spec))))
  138. ((tuple)
  139. (make-tuple-type (map expand-type-spec (cdr spec))))
  140. (else
  141. (error "unknown type syntax ~S" spec))))
  142. ((not (symbol? spec))
  143. (error "unknown type syntax ~S" spec))
  144. ((lookup-type spec)
  145. => identity)
  146. ((lookup-record-type spec)
  147. => make-pointer-type)
  148. (else
  149. (error "unknown type name ~S" spec))))
  150. ;--------------------------------------------------
  151. (define (display-type type port)
  152. (define (do-list list)
  153. (write-char #\( port)
  154. (cond ((not (null? list))
  155. (do-type (car list))
  156. (for-each (lambda (type)
  157. (write-char #\space port)
  158. (do-type type))
  159. (cdr list))))
  160. (write-char #\) port))
  161. (define (do-type type)
  162. (let ((type (maybe-follow-uvar type)))
  163. (cond ((base-type? type)
  164. (display (base-type-name type) port))
  165. ((record-type? type)
  166. (display (record-type-name type) port))
  167. ((arrow-type? type)
  168. (write-char #\( port)
  169. (do-list (arrow-type-args type))
  170. (display " -> " port)
  171. (do-type (arrow-type-result type))
  172. (write-char #\) port))
  173. ((pointer-type? type)
  174. (write-char #\* port)
  175. (do-type (pointer-type-to type)))
  176. ((uvar? type)
  177. (write-char #\T port)
  178. (display (uvar-id type) port))
  179. ((type-scheme? type)
  180. (display "(for-all " port)
  181. (do-list (type-scheme-free-uvars type))
  182. (display " " port)
  183. (do-type (type-scheme-type type))
  184. (display ")" port))
  185. ((tuple-type? type)
  186. (display "(tuple " port)
  187. (do-list (tuple-type-types type))
  188. (display ")" port))
  189. (else
  190. (bug "don't know how to display type ~S" type)))))
  191. (do-type type))