node-type.scm 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. ; Copyright (c) 1993-2008 by Richard Kelsey. See file COPYING.
  2. ; Types and nodes together
  3. ; Instantiate TYPE and replace the types in NODE with their corresponding
  4. ; value. LOCATION is where NODE will be applied, and is used to get the actual
  5. ; types of the arguments.
  6. (define (instantiate-type&value type node location)
  7. (let ((has (instantiate-type-scheme type
  8. -1
  9. (lambda () (fix-types node))))
  10. (wants (call->proc-type (node-parent location))))
  11. (identity (unify! has wants 'simplifying))))
  12. ; (format #t "~%Reconstructing ")
  13. ; (pp-cps call)
  14. ; (format #t " has ~S~% wants ~S~%"
  15. ; (instantiate has)
  16. ; (instantiate wants))
  17. ; (breakpoint "reconstructing ~S" call)
  18. ; (unify! has wants 'simplifying)
  19. ; This is used to replace all references in NODE to polymorphic type variables
  20. ; with the current value of the type variable.
  21. ; Youch! Very inefficient - may make many copies of the same type.
  22. (define (fix-types node)
  23. (let label ((node node))
  24. (case (node-variant node)
  25. ((lambda)
  26. (for-each fix-variable (lambda-variables node))
  27. (label (lambda-body node)))
  28. ((call)
  29. (walk-vector label (call-args node)))
  30. ((literal)
  31. (let ((value (literal-value node)))
  32. (if (or (uvar? value)
  33. (other-type? value))
  34. (set-literal-value! node (copy-type value))))))))
  35. (define (fix-variable var)
  36. (set-variable-type! var (copy-type (variable-type var))))
  37. (define (call->proc-type call)
  38. (let ((end (if (or (calls-this-primop? call 'call)
  39. (calls-this-primop? call 'tail-call))
  40. 2 ; no protocol to ignore
  41. 3))) ; protocol to ignore
  42. (make-arrow-type (do ((i (- (vector-length (call-args call)) 1) (- i 1))
  43. (ts '() (cons (maybe-instantiate
  44. (node-type (call-arg call i)))
  45. ts)))
  46. ((< i end)
  47. ts))
  48. (let ((cont (call-arg call 0)))
  49. (if (reference-node? cont)
  50. (variable-type (reference-variable cont))
  51. (make-tuple-type (map variable-type
  52. (lambda-variables cont))))))))
  53. (define (maybe-instantiate type)
  54. (if (type-scheme? type)
  55. (instantiate-type-scheme type -1)
  56. type))
  57. (define (make-monomorphic! var)
  58. (let ((type (type-scheme-type (variable-type var))))
  59. (for-each (lambda (ref)
  60. (if (not (called-node? ref))
  61. (error
  62. "polymorphic procedure ~S used as value, cannot be made monomorphic"
  63. (variable-name var))
  64. (unify! type
  65. (call->proc-type (node-parent ref))
  66. 'make-monomorphic!)))
  67. (variable-refs var))
  68. (set-variable-type! var type)))