node-type.scm 2.5 KB

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