123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- ; Part of Scheme 48 1.9. See file COPYING for notices and license.
- ; Authors: Richard Kelsey
- ; Types and nodes together
- ; Instantiate TYPE and replace the types in NODE with their corresponding
- ; value. LOCATION is where NODE will be applied, and is used to get the actual
- ; types of the arguments.
- (define (instantiate-type&value type node location)
- (let ((has (instantiate-type-scheme type
- -1
- (lambda () (fix-types node))))
- (wants (call->proc-type (node-parent location))))
- (identity (unify! has wants 'simplifying))))
- ; (format #t "~%Reconstructing ")
- ; (pp-cps call)
- ; (format #t " has ~S~% wants ~S~%"
- ; (instantiate has)
- ; (instantiate wants))
- ; (breakpoint "reconstructing ~S" call)
- ; (unify! has wants 'simplifying)
- ; This is used to replace all references in NODE to polymorphic type variables
- ; with the current value of the type variable.
- ; Youch! Very inefficient - may make many copies of the same type.
- (define (fix-types node)
- (let label ((node node))
- (case (node-variant node)
- ((lambda)
- (for-each fix-variable (lambda-variables node))
- (label (lambda-body node)))
- ((call)
- (walk-vector label (call-args node)))
- ((literal)
- (let ((value (literal-value node)))
- (if (or (uvar? value)
- (other-type? value))
- (set-literal-value! node (copy-type value))))))))
- (define (fix-variable var)
- (set-variable-type! var (copy-type (variable-type var))))
- (define (call->proc-type call)
- (let ((end (if (or (calls-this-primop? call 'call)
- (calls-this-primop? call 'tail-call))
- 2 ; no protocol to ignore
- 3))) ; protocol to ignore
- (make-arrow-type (do ((i (- (vector-length (call-args call)) 1) (- i 1))
- (ts '() (cons (maybe-instantiate
- (node-type (call-arg call i)))
- ts)))
- ((< i end)
- ts))
- (let ((cont (call-arg call 0)))
- (if (reference-node? cont)
- (variable-type (reference-variable cont))
- (make-tuple-type (map variable-type
- (lambda-variables cont))))))))
- (define (maybe-instantiate type)
- (if (type-scheme? type)
- (instantiate-type-scheme type -1)
- type))
- (define (make-monomorphic! var)
- (let ((type (type-scheme-type (variable-type var))))
- (for-each (lambda (ref)
- (if (not (called-node? ref))
- (error
- "polymorphic procedure ~S used as value, cannot be made monomorphic"
- (variable-name var))
- (unify! type
- (call->proc-type (node-parent ref))
- 'make-monomorphic!)))
- (variable-refs var))
- (set-variable-type! var type)))
|