node-type.scm 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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/node-type.scm
  8. ;;;
  9. ;;; Types and nodes together
  10. (define-module (ps-compiler prescheme node-type)
  11. #:use-module (prescheme scheme48)
  12. #:use-module (ps-compiler node node)
  13. #:use-module (ps-compiler node node-util)
  14. #:use-module (ps-compiler node variable)
  15. #:use-module (ps-compiler prescheme inference)
  16. #:use-module (ps-compiler prescheme type)
  17. #:use-module (ps-compiler prescheme type-scheme)
  18. #:use-module (ps-compiler prescheme type-var)
  19. #:use-module (ps-compiler util util)
  20. #:export (instantiate-type&value
  21. make-monomorphic!))
  22. ;;; Instantiate TYPE and replace the types in NODE with their corresponding
  23. ;;; value. LOCATION is where NODE will be applied, and is used to get the actual
  24. ;;; types of the arguments.
  25. (define (instantiate-type&value type node location)
  26. (let ((has (instantiate-type-scheme type
  27. -1
  28. (lambda () (fix-types node))))
  29. (wants (call->proc-type (node-parent location))))
  30. (identity (unify! has wants 'simplifying))))
  31. ;; (format #t "~%Reconstructing ")
  32. ;; (pp-cps call)
  33. ;; (format #t " has ~S~% wants ~S~%"
  34. ;; (instantiate has)
  35. ;; (instantiate wants))
  36. ;; (breakpoint "reconstructing ~S" call)
  37. ;; (unify! has wants 'simplifying)
  38. ;; This is used to replace all references in NODE to polymorphic type variables
  39. ;; with the current value of the type variable.
  40. ;; Youch! Very inefficient - may make many copies of the same type.
  41. (define (fix-types node)
  42. (let label ((node node))
  43. (case (node-variant node)
  44. ((lambda)
  45. (for-each fix-variable (lambda-variables node))
  46. (label (lambda-body node)))
  47. ((call)
  48. (walk-vector label (call-args node)))
  49. ((literal)
  50. (let ((value (literal-value node)))
  51. (if (or (uvar? value)
  52. (other-type? value))
  53. (set-literal-value! node (copy-type value))))))))
  54. (define (fix-variable var)
  55. (set-variable-type! var (copy-type (variable-type var))))
  56. (define (call->proc-type call)
  57. (let ((end (if (or (calls-this-primop? call 'call)
  58. (calls-this-primop? call 'tail-call))
  59. 2 ;; no protocol to ignore
  60. 3))) ;; protocol to ignore
  61. (make-arrow-type (do ((i (- (vector-length (call-args call)) 1) (- i 1))
  62. (ts '() (cons (maybe-instantiate
  63. (node-type (call-arg call i)))
  64. ts)))
  65. ((< i end)
  66. ts))
  67. (let ((cont (call-arg call 0)))
  68. (if (reference-node? cont)
  69. (variable-type (reference-variable cont))
  70. (make-tuple-type (map variable-type
  71. (lambda-variables cont))))))))
  72. (define (maybe-instantiate type)
  73. (if (type-scheme? type)
  74. (instantiate-type-scheme type -1)
  75. type))
  76. (define (make-monomorphic! var)
  77. (let ((type (type-scheme-type (variable-type var))))
  78. (for-each (lambda (ref)
  79. (if (not (called-node? ref))
  80. (error
  81. "polymorphic procedure ~S used as value, cannot be made monomorphic"
  82. (variable-name var))
  83. (unify! type
  84. (call->proc-type (node-parent ref))
  85. 'make-monomorphic!)))
  86. (variable-refs var))
  87. (set-variable-type! var type)))