12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
- ;;;
- ;;; Port Author: Andrew Whatson
- ;;;
- ;;; Original Authors: Richard Kelsey
- ;;;
- ;;; scheme48-1.9.2/ps-compiler/prescheme/node-type.scm
- ;;;
- ;;; Types and nodes together
- (define-module (ps-compiler prescheme node-type)
- #:use-module (prescheme scheme48)
- #:use-module (ps-compiler node node)
- #:use-module (ps-compiler node node-util)
- #:use-module (ps-compiler node variable)
- #:use-module (ps-compiler prescheme inference)
- #:use-module (ps-compiler prescheme type)
- #:use-module (ps-compiler prescheme type-scheme)
- #:use-module (ps-compiler prescheme type-var)
- #:use-module (ps-compiler util util)
- #:export (instantiate-type&value
- make-monomorphic!))
- ;;; 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)))
|