type-var.scm 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey
  3. ; Type variables - what a mess
  4. (define-record-type uvar :uvar
  5. (really-make-uvar prefix depth id tuple-okay?
  6. place source binding temp) ; all initialized to #F
  7. uvar?
  8. (prefix uvar-prefix) ; a name for debugging
  9. (depth uvar-depth set-uvar-depth!) ; lexical depth of the uvar
  10. (id uvar-id) ; a number
  11. ; true if this can be unified with a tuple, set when merged
  12. (tuple-okay? uvar-tuple-okay? set-uvar-tuple-okay?!)
  13. (place uvar-place set-uvar-place!) ; used in producing type schemes
  14. (source uvar-source set-uvar-source!)
  15. ; to let the user know where this came from
  16. (binding uvar-binding set-uvar-binding!); known value of this uvar
  17. (temp uvar-temp set-uvar-temp!)) ; useful field
  18. (define-record-discloser :uvar
  19. (lambda (uvar)
  20. (list 'uvar
  21. (uvar-prefix uvar)
  22. (uvar-depth uvar)
  23. (uvar-id uvar)
  24. (uvar-binding uvar))))
  25. (define (make-uvar prefix depth . maybe-id)
  26. (really-make-uvar prefix
  27. depth
  28. (if (null? maybe-id)
  29. (unique-id)
  30. (car maybe-id))
  31. #f ; tuple-okay?
  32. #f #f #f #f)) ; place source binding temp
  33. (define (make-tuple-uvar prefix depth . maybe-id)
  34. (really-make-uvar prefix
  35. depth
  36. (if (null? maybe-id)
  37. (unique-id)
  38. (car maybe-id))
  39. #t ; tuple-okay?
  40. #f #f #f #f)) ; place source binding temp
  41. ; Could this safely short-circuit the chains?
  42. (define (maybe-follow-uvar type)
  43. (cond ((and (uvar? type)
  44. (uvar-binding type))
  45. => maybe-follow-uvar)
  46. (else type)))
  47. ; Substitute VALUE for UVAR, if this will not introduce a circularity.
  48. ; or cause other problems. Returns an error-printing thunk if there is
  49. ; a problem.
  50. (define (bind-uvar! uvar value)
  51. (cond ((uvar? value)
  52. (bind-uvar-to-uvar! uvar value)
  53. #f)
  54. (else
  55. (bind-uvar-to-type! uvar value))))
  56. (define (bind-uvar-to-uvar! uvar0 uvar1)
  57. (minimize-type-depth! uvar1 (uvar-depth uvar0))
  58. (set-uvar-binding! uvar0 uvar1)
  59. (if (and (uvar-tuple-okay? uvar1)
  60. (not (uvar-tuple-okay? uvar0)))
  61. (set-uvar-tuple-okay?! uvar1 #f)))
  62. (define (bind-uvar-to-type! uvar type)
  63. (let ((errors '()))
  64. (if (uvar-in-type? uvar type)
  65. (set! errors (cons circularity-error errors)))
  66. (if (and (tuple-type? type)
  67. (not (uvar-tuple-okay? uvar)))
  68. (set! errors (cons (tuple-error type) errors)))
  69. (cond ((null? errors) ; whew!
  70. (minimize-type-depth! type (uvar-depth uvar))
  71. (set-uvar-binding! uvar type)
  72. #f)
  73. (else
  74. (lambda ()
  75. (format #t "unifying ")
  76. (display-type uvar (current-output-port))
  77. (format #t " == ")
  78. (display-type type (current-output-port))
  79. (format #t "~% would cause the following problem~A:"
  80. (if (null? (cdr errors)) "" "s"))
  81. (for-each (lambda (x) (x)) errors))))))
  82. (define (circularity-error)
  83. (format #t "~% creation of a circular type"))
  84. (define (tuple-error type)
  85. (lambda ()
  86. (if (null? (tuple-type-types type))
  87. (format #t "~% returning no values where one is expected")
  88. (format #t "~% returning ~D values where one is expected"
  89. (length (tuple-type-types type))))))
  90. ; Check that UVAR does not occur in EXP.
  91. (define (uvar-in-type? uvar exp)
  92. (let label ((exp exp))
  93. (cond ((or (base-type? exp)
  94. (record-type? exp))
  95. #f)
  96. ((uvar? exp)
  97. (if (uvar-binding exp)
  98. (label (uvar-binding exp))
  99. (eq? exp uvar)))
  100. ((other-type? exp)
  101. (every? label (other-type-subtypes exp)))
  102. (else
  103. (identity (bug "funny type ~S" exp))))))
  104. ; Make the depths of any uvars in TYPE be no greater than DEPTH.
  105. (define (minimize-type-depth! type depth)
  106. (let label ((type type))
  107. (cond ((other-type? type)
  108. (for-each label (other-type-subtypes type)))
  109. ((uvar? type)
  110. (cond ((uvar-binding type)
  111. => label)
  112. ((< depth (uvar-depth type))
  113. (set-uvar-depth! type depth)))))))
  114. ; Set the depth of all uvars in TYPE to be -1 so that it will not be made
  115. ; polymorphic at any level.
  116. (define (make-nonpolymorphic! type)
  117. (cond ((uvar? type)
  118. (set-uvar-depth! type -1))
  119. ((other-type? type)
  120. (for-each make-nonpolymorphic! (other-type-subtypes type)))
  121. ;((type-scheme? type)
  122. ; (make-nonpolymorphic! (type-scheme-type type)))
  123. ))
  124. ;------------------------------------------------------------
  125. ; Micro utilities
  126. (define *unique-id-counter* 0)
  127. (define (unique-id)
  128. (set! *unique-id-counter* (+ *unique-id-counter* 1))
  129. *unique-id-counter*)
  130. (define (reset-type-vars!)
  131. (set! *unique-id-counter* 0))