git.fiddlerwoaroof.com
import-export/import-export.scm
4e987026
 ;;; This is the main driver for the import / export routine
 
 (define (import-export modules)
   (walk-modules modules
         (lambda () (add-module-to-symbol-table *module*)))
   (walk-modules modules
       (lambda () (init-module-structure)))
   (import-export/fixpoint modules '#t)
   (walk-modules modules (lambda () (check-missing-names)))
   (when (memq 'import (dynamic *printers*))
     (show-export-tables modules))
  modules)
 
 (define (import-export/interface modules)
   (walk-modules modules
         (lambda () (add-module-to-symbol-table *module*)))
   (walk-modules modules
       (lambda () (init-module-structure)))
   (walk-modules modules
       (lambda () (create-top-definitions)
 	         (attach-fixities))))
 
 (define (import-export/fixpoint modules initial-cycle?)
   (setf *new-exports-found?* '#f)
   (walk-modules modules
    (lambda ()
      (setf (module-fresh-exports *module*) '())
      (when initial-cycle?
        (create-top-definitions)
        (attach-fixities)
        (import-non-local))
      (locally-import)
      (locally-export)))
   (when *new-exports-found?*
       (import-export/fixpoint modules '#f)))
 
 ;;; This does the non-local importing from previously defined modules
 
 (define (import-non-local)
   (setf (module-imports *module*)
 	(process-non-local-imports (module-imports *module*))))
 
 (define (process-non-local-imports imports)
   (if (null? imports)
       '()
       (let* ((import (car imports)))
         (with-slots import-decl (module mode specs renamings) import
 	  (cond ((eq? *unit* (module-unit module))
 		 (cons import (process-non-local-imports (cdr imports))))
 		((eq? mode 'all)
 		 (import-all-entities module specs renamings import)
 		 (process-non-local-imports (cdr imports)))
 		(else
 		 (import-named-entities module specs renamings import)
 		 (process-non-local-imports (cdr imports))))))))
 
 (define (import-all-entities module hiding renamings import-decl)
   (table-for-each
    (lambda (name group)
      (declare (ignore name))
      (cond ((in-hiding-list? group hiding)
 	    (setf hiding (remove-entity group hiding)))
 	   (else
 	    (import-group (rename-group group renamings) module))))
    (module-export-table module))
   (when (not (null? hiding))
     (remember-context import-decl
       (dolist (h hiding)
 	(signal-unused-hiding (entity-name h) (module-name module)))))
   (find-unused-renamings renamings import-decl))
 
 (define (import-named-entities mod specs renamings import-decl)
   (dolist (entity specs)
     (let ((group (locate-entity/export-table entity mod '#t)))
       (when (not (eq? group 'error))
 	(setf group (rename-group group renamings))
 	(import-group group mod))))
   (find-unused-renamings renamings import-decl))
 
 ;;; This takes a module and processes the import declarations, moving as
 ;;; many entities from the freshly exported components of other modules into
 ;;; the current module.
 
 (define (locally-import)
   (dolist (import (module-imports *module*))
     (with-slots import-decl (module mode specs renamings) import
       (if (eq? mode 'all)
 	  (import-fresh-entities import module specs renamings)
 	  (setf (import-decl-specs import)
 		(import-entities specs module renamings))))))
 
 (define (import-fresh-entities import module hiding renamings)
   (dolist (group (module-fresh-exports module))
     (cond ((in-hiding-list? group hiding)
 	    (setf hiding (remove-entity group hiding)))
 	   (else
 	    (import-group (rename-group group renamings) module))))
   (setf (import-decl-specs import) hiding))
 
 (define (import-entities entities module renamings)
   (if (null? entities)
       '()
       (let ((group (locate-entity/export-table (car entities) module '#f)))
 	(cond ((eq? group 'not-found)
 	       (cons (car entities)
 		     (import-entities (cdr entities) module renamings)))
 	      ((eq? group 'error)
 	       (import-entities (cdr entities) module renamings))
 	      (else
 	       (setf group (rename-group group renamings))
 	       (import-group group module)
 	       (import-entities (cdr entities) module renamings))))))
 
 ;;; This imports a group into *module*.  module is the place the group is
 ;;; taken from.
 
 (define (import-group group module)
   (when (memq module (module-exported-modules *module*))
     (export-group group))
   (dolist (n-d group)
     (insert-top-definition (tuple-2-1 n-d) (tuple-2-2 n-d))))
 
 ;;; This takes as yet unresolved exports and moves them to the export table.
 
 (define (locally-export)
   (setf (module-exports *module*)
 	(export-entities (module-exports *module*))))
 
 (define (export-entities entities)
   (if (null? entities)
       '()
       (let* ((entity (car entities))
 	     (group (locate-entity entity)))
 	(cond ((eq? group 'error)
 	       (export-entities (cdr entities)))
 	      ((eq? group 'not-found)
 	       (cons entity (export-entities (cdr entities))))
 	      (else
 	       (export-group group)
 	       (export-entities (cdr entities)))))))
 
 
 ;;; This moves a group into the export table.  If this export is new,
 ;;; a flag is set.
 
 (define (export-group group)
   (let* ((export-table (module-export-table *module*))
 	 (old-group (table-entry export-table (group-name group))))
     (when (or (eq? old-group '#f)
 	      (and (hidden-constructors? old-group)
 		   (not (hidden-constructors? group))))
       (setf (table-entry export-table (group-name group)) group)
       (dolist (n-d group)
         (setf (def-exported? (tuple-2-2 n-d)) '#t))
       (push group (module-fresh-exports *module*))
       (setf *new-exports-found?* '#t))))
 
 (define (show-export-tables modules)
   (walk-modules modules
     (lambda ()
       (format '#t "~%Exports from module ~A~%" *module-name*)
       (let ((exports '()))
 	(table-for-each (lambda (key val)
 			  (push (cons key val) exports))
 			(module-export-table *module*))
 	(setf exports (sort-list exports
 				 (lambda (x y)
 				   (string-ci<? (symbol->string (car x))
 						(symbol->string (car y))))))
 	(dolist (e exports)
           (print-exported-group (car e) (group-definition (cdr e))
 				(cdr (cdr e))))))))
 
 (define (print-exported-group name def extras)
   (if (eq? (def-module def) *module-name*)
       (format '#t " ")
       (format '#t "*"))
   (cond ((synonym? def)
 	 (format '#t "type  "))
 	((algdata? def)
 	 (format '#t "data  "))
 	((class? def)
 	 (format '#t "class "))
 	(else
 	 (format '#t "      ")))
   (format '#t "~A" name)
   (when (not (eq? name (def-name def)))
      (format '#t "[~A]" (def-name def)))
   (when extras
      (format '#t " (")
      (print-exported-group-1 extras (algdata? def)))
   (format '#t "~%"))
 
 (define (print-exported-group-1 extras alg?)
   (let* ((name (tuple-2-1 (car extras)))
 	 (ns (symbol->string name))
 	 (def (tuple-2-2 (car extras))))
     (format '#t "~A" (if alg? (remove-con-prefix ns) ns))
     (when (not (eq? name (def-name def)))
       (let ((name1 (symbol->string (def-name def))))
 	  (format '#t "[~A]" (if alg? (remove-con-prefix name1) name1))))
     (if (null? (cdr extras))
 	(format '#t ")")
 	(begin
 	  (format '#t ",")
 	  (print-exported-group-1 (cdr extras) alg?)))))