git.fiddlerwoaroof.com
util/instance-manager.scm
4e987026
 
 ;;; This file has some random utilities dealing with instances.
 
 ;;; Right now, this is a linear search off the class.
 
 (define (lookup-instance alg-def class-def)
   (let ((res (lookup-instance-1 alg-def (class-instances class-def))))
     (if (and (eq? res '#f) (algdata-real-tuple? alg-def))
 	(lookup-possible-tuple-instances alg-def class-def)
 	res)))
 
 (define (lookup-instance-1 alg-def instances)
   (cond ((null? instances)
 	 '#f)
 	((eq? (instance-algdata (car instances)) alg-def)
 	 (if (instance-ok? (car instances))
 	     (car instances)
 	     '#f))
 	(else
 	 (lookup-instance-1 alg-def (cdr instances)))))
 
 (define (lookup-possible-tuple-instances alg-def class-def)
   (cond ((eq? class-def (core-symbol "Eq"))
 	 (get-tuple-eq-instance alg-def))
 	((eq? class-def (core-symbol "Ord"))
 	 (get-tuple-ord-instance alg-def))
 	((eq? class-def (core-symbol "Ix"))
 	 (get-tuple-ix-instance alg-def))
 	((eq? class-def (core-symbol "Text"))
 	 (get-tuple-text-instance alg-def))
 	((eq? class-def (core-symbol "Binary"))
 	 (get-tuple-binary-instance alg-def))
 	(else '#f)))
 
 (define *saved-eq-instances* '())
 (define *saved-ord-instances* '())
 (define *saved-ix-instances* '())
 (define *saved-text-instances* '())
 (define *saved-binary-instances* '())
 
 (define (get-tuple-eq-instance tpl)
   (let ((res (assq tpl *saved-eq-instances*)))
     (if (not (eq? res '#f))
 	(tuple-2-2 res)
 	(let ((inst (make-tuple-instance
 		     tpl (core-symbol "Eq") (core-symbol "tupleEqDict"))))
 	  (push (tuple tpl inst) *saved-eq-instances*)
 	  inst))))
 
 (define (get-tuple-ord-instance tpl)
   (let ((res (assq tpl *saved-ord-instances*)))
     (if (not (eq? res '#f))
 	(tuple-2-2 res)
 	(let ((inst (make-tuple-instance
 		     tpl (core-symbol "Ord") (core-symbol "tupleOrdDict"))))
 	  (push (tuple tpl inst) *saved-ord-instances*)
 	  inst))))
 
 (define (get-tuple-ix-instance tpl)
   (let ((res (assq tpl *saved-ix-instances*)))
     (if (not (eq? res '#f))
 	(tuple-2-2 res)
 	(let ((inst (make-tuple-instance
 		     tpl (core-symbol "Ix") (core-symbol "tupleIxDict"))))
 	  (push (tuple tpl inst) *saved-ix-instances*)
 	  inst))))
 
 (define (get-tuple-text-instance tpl)
   (let ((res (assq tpl *saved-text-instances*)))
     (if (not (eq? res '#f))
 	(tuple-2-2 res)
 	(let ((inst (make-tuple-instance
 		     tpl (core-symbol "Text") (core-symbol "tupleTextDict"))))
 	  (push (tuple tpl inst) *saved-text-instances*)
 	  inst))))
 
 (define (get-tuple-binary-instance tpl)
   (let ((res (assq tpl *saved-binary-instances*)))
     (if (not (eq? res '#f))
 	(tuple-2-2 res)
 	(let ((inst (make-tuple-instance
 		     tpl (core-symbol "Binary")
 		     (core-symbol "tupleBinaryDict"))))
 	  (push (tuple tpl inst) *saved-binary-instances*)
 	  inst))))
 
 (define (make-tuple-instance algdata class dict)
   (let* ((size (tuple-size algdata))
 	 (tyvars (gen-symbols size))
 	 (context (map (lambda (tyvar)
 			  (**context (**class/def class) tyvar))
 			tyvars))
 	 (sig (**tycon/def algdata (map (lambda (x) (**tyvar x)) tyvars)))
 	 (gcontext (gtype-context (ast->gtype context sig))))
     (make instance 
 	  (algdata algdata)
 	  (tyvars tyvars)
 	  (class class)
 	  (context context)
 	  (gcontext gcontext)
 	  (methods '())
 	  (dictionary dict)
 	  (ok? '#t)
 	  (special? '#t))))
 
 ;;; I know these are somewhere else too ...
 
 (define (tuple-size alg)
   (con-arity (car (algdata-constrs alg))))
 
 (define (gen-symbols n)
   (gen-symbols-1 n '(|a| |b| |c| |d| |e| |f| |g| |h| |i| |j| |k| |l| |m|
 		     |n| |o| |p| |q| |r| |s| |t| |u| |v| |w| |x| |y| |z|)))
 
 (define (gen-symbols-1 n vars)
   (if (eqv? n 0)
       '()
       (if (null? vars)
 	  (cons (string->symbol (format '#f "x~A" n))
 		(gen-symbols-1 (1- n) '()))
 	  (cons (car vars) (gen-symbols-1 (1- n) (cdr vars))))))
 
 ;;; This handles the dynamic linking of instances into classes
 
 (define (link-instances modules)
   (dolist (m modules)
     ;; clear out any instances sitting around from old compiles
     (dolist (class (module-class-defs m))
       (setf (class-instances class) '())))
   (dolist (m modules)
     (dolist (inst (module-instance-defs m))
        (link-instance inst)))
   )
 
 (define (link-instance inst)  ; links an instance into the associated class
   (push inst (class-instances (instance-class inst))))
 
 ;;; This creates a new instance object and installs it.
 
 (predefine (make-new-var name))  ; in tdecl/tdecl-utils.scm
 
 (define (new-instance class algdata tyvars)
  (let* ((dict-name
 	 (string-append "dict-"
 			(symbol->string (print-name class)) "-"
 			(symbol->string (print-name algdata))))
 	(inst (make instance (algdata algdata)
 			     (tyvars tyvars)
 		             (class class)
 			     (gcontext '())
 			     (context '())
 			     (dictionary (make-new-var dict-name)))))
    (link-instance inst)
    inst))