type-scheme.scm 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
  2. ;;;
  3. ;;; Port Author: Andrew Whatson
  4. ;;;
  5. ;;; Original Authors: Richard Kelsey
  6. ;;;
  7. ;;; scheme48-1.9.2/ps-compiler/prescheme/type-scheme.scm
  8. ;;;
  9. ;;; Type schemes
  10. (define-module (ps-compiler prescheme type-scheme)
  11. #:use-module (srfi srfi-9)
  12. #:use-module (prescheme record-discloser)
  13. #:use-module (ps-compiler prescheme type)
  14. #:use-module (ps-compiler prescheme type-var)
  15. #:export (type-scheme?
  16. schemify-type
  17. instantiate-type-scheme
  18. copy-type
  19. type-scheme-type
  20. type-scheme-free-uvars ;; for error messages
  21. ;;type-scheme-lattice-uvars
  22. ))
  23. (define-record-type :type-scheme
  24. (make-type-scheme type free-uvars)
  25. type-scheme?
  26. (type type-scheme-type) ;; a type
  27. (free-uvars type-scheme-free-uvars)) ;; uvars that are free
  28. (define-record-discloser :type-scheme
  29. (lambda (type-scheme)
  30. (list 'type-scheme
  31. (map uvar-id (type-scheme-free-uvars type-scheme))
  32. (type-scheme-type type-scheme))))
  33. ;; If TYPE has any variables bound at DEPTH this returns a type scheme making
  34. ;; those variables polymorphic; otherwise TYPE is returned.
  35. ;; Would like to do limited finalizing of uvars, but can't.
  36. ;; Consider (lambda (g x) (tuple (g 3) (g x) x))
  37. ;; (a -> b) -> c -> [d, e, f] with
  38. ;; a > int8, d > b, a > c, e > b, f > c
  39. ;; No polymorphism, and no simplification without restricting someone
  40. ;; But consider NOT a ->b, bool > a, b > bool
  41. ;; It could just as well be bool -> bool.
  42. ;; Simplification okay on variables that are not used inside other types?
  43. (define *free-uvars* '())
  44. (define (schemify-type type depth)
  45. (set! *free-uvars* '())
  46. (let* ((type (find-free-uvars type depth))
  47. (free-uvars *free-uvars*))
  48. (set! *free-uvars* '()) ;; drop pointers
  49. (for-each (lambda (uvar)
  50. (set-uvar-place! uvar #f))
  51. free-uvars)
  52. (if (not (null? free-uvars))
  53. (make-type-scheme type free-uvars)
  54. type)))
  55. (define (find-free-uvars type depth)
  56. (let label ((type type))
  57. (cond ((other-type? type)
  58. (make-other-type (other-type-kind type)
  59. (map label
  60. (other-type-subtypes type))))
  61. ((not (uvar? type))
  62. type)
  63. ((uvar-binding type)
  64. => label)
  65. ((and (not (uvar-place type))
  66. (<= depth (uvar-depth type)))
  67. (set-uvar-place! type type)
  68. (set! *free-uvars* (cons type *free-uvars*))
  69. type)
  70. (else
  71. type))))
  72. ;; Instantiate SCHEME at DEPTH.
  73. ;;
  74. ;; New sequence:
  75. ;; (instantiate-type-scheme scheme depth)
  76. ;; ... elide bindings in new copy ...
  77. ;; (clean-type-scheme scheme)
  78. (define (instantiate-type-scheme scheme depth . maybe-thunk)
  79. (instantiate-type-scheme! scheme depth)
  80. (let ((type (copy-type (type-scheme-type scheme))))
  81. (if (not (null? maybe-thunk))
  82. ((car maybe-thunk)))
  83. (clean-type-scheme! scheme)
  84. type))
  85. (define (instantiate-type-scheme! scheme depth)
  86. (let ((uid (unique-id)))
  87. (for-each (lambda (uvar)
  88. (set-uvar-place!
  89. uvar
  90. (make-uvar (uvar-prefix uvar) depth uid)))
  91. (type-scheme-free-uvars scheme))))
  92. (define (clean-type-scheme! scheme)
  93. (for-each (lambda (uvar)
  94. (set-uvar-place! uvar #f))
  95. (type-scheme-free-uvars scheme)))
  96. (define (copy-type type)
  97. (cond ((other-type? type)
  98. (make-other-type (other-type-kind type)
  99. (map copy-type
  100. (other-type-subtypes type))))
  101. ((not (uvar? type))
  102. type)
  103. ((uvar-place type)
  104. => identity)
  105. ((uvar-binding type)
  106. => copy-type)
  107. (else
  108. type)))