123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- ;;; 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/type-scheme.scm
- ;;;
- ;;; Type schemes
- (define-module (ps-compiler prescheme type-scheme)
- #:use-module (srfi srfi-9)
- #:use-module (prescheme record-discloser)
- #:use-module (ps-compiler prescheme type)
- #:use-module (ps-compiler prescheme type-var)
- #:export (type-scheme?
- schemify-type
- instantiate-type-scheme
- copy-type
- type-scheme-type
- type-scheme-free-uvars ;; for error messages
- ;;type-scheme-lattice-uvars
- ))
- (define-record-type :type-scheme
- (make-type-scheme type free-uvars)
- type-scheme?
- (type type-scheme-type) ;; a type
- (free-uvars type-scheme-free-uvars)) ;; uvars that are free
- (define-record-discloser :type-scheme
- (lambda (type-scheme)
- (list 'type-scheme
- (map uvar-id (type-scheme-free-uvars type-scheme))
- (type-scheme-type type-scheme))))
- ;; If TYPE has any variables bound at DEPTH this returns a type scheme making
- ;; those variables polymorphic; otherwise TYPE is returned.
- ;; Would like to do limited finalizing of uvars, but can't.
- ;; Consider (lambda (g x) (tuple (g 3) (g x) x))
- ;; (a -> b) -> c -> [d, e, f] with
- ;; a > int8, d > b, a > c, e > b, f > c
- ;; No polymorphism, and no simplification without restricting someone
- ;; But consider NOT a ->b, bool > a, b > bool
- ;; It could just as well be bool -> bool.
- ;; Simplification okay on variables that are not used inside other types?
- (define *free-uvars* '())
- (define (schemify-type type depth)
- (set! *free-uvars* '())
- (let* ((type (find-free-uvars type depth))
- (free-uvars *free-uvars*))
- (set! *free-uvars* '()) ;; drop pointers
- (for-each (lambda (uvar)
- (set-uvar-place! uvar #f))
- free-uvars)
- (if (not (null? free-uvars))
- (make-type-scheme type free-uvars)
- type)))
- (define (find-free-uvars type depth)
- (let label ((type type))
- (cond ((other-type? type)
- (make-other-type (other-type-kind type)
- (map label
- (other-type-subtypes type))))
- ((not (uvar? type))
- type)
- ((uvar-binding type)
- => label)
- ((and (not (uvar-place type))
- (<= depth (uvar-depth type)))
- (set-uvar-place! type type)
- (set! *free-uvars* (cons type *free-uvars*))
- type)
- (else
- type))))
- ;; Instantiate SCHEME at DEPTH.
- ;;
- ;; New sequence:
- ;; (instantiate-type-scheme scheme depth)
- ;; ... elide bindings in new copy ...
- ;; (clean-type-scheme scheme)
- (define (instantiate-type-scheme scheme depth . maybe-thunk)
- (instantiate-type-scheme! scheme depth)
- (let ((type (copy-type (type-scheme-type scheme))))
- (if (not (null? maybe-thunk))
- ((car maybe-thunk)))
- (clean-type-scheme! scheme)
- type))
- (define (instantiate-type-scheme! scheme depth)
- (let ((uid (unique-id)))
- (for-each (lambda (uvar)
- (set-uvar-place!
- uvar
- (make-uvar (uvar-prefix uvar) depth uid)))
- (type-scheme-free-uvars scheme))))
- (define (clean-type-scheme! scheme)
- (for-each (lambda (uvar)
- (set-uvar-place! uvar #f))
- (type-scheme-free-uvars scheme)))
- (define (copy-type type)
- (cond ((other-type? type)
- (make-other-type (other-type-kind type)
- (map copy-type
- (other-type-subtypes type))))
- ((not (uvar? type))
- type)
- ((uvar-place type)
- => identity)
- ((uvar-binding type)
- => copy-type)
- (else
- type)))
|