chiark / gitweb /
src/*.lisp: Add missing exports.
[sod] / src / module-impl.lisp
index 3ca44114954aa857625ced8e144e4ea0cb6c7e24..44aa0b8e7e0007d37eba578d1ec4af76abdcfc10 100644 (file)
@@ -56,8 +56,10 @@ (defmethod finalize-module ((module module))
 ;;;--------------------------------------------------------------------------
 ;;; Module objects.
 
-(defparameter *module-map* (make-hash-table :test #'equal)
+(defvar-unbound *module-map*
   "Hash table mapping true names to module objects.")
+(define-clear-the-decks reset-module-map
+  (setf *module-map* (make-hash-table :test #'equal)))
 
 (defun build-module
     (name thunk &key (truename (probe-file name)) location)
@@ -71,9 +73,11 @@ (defun build-module
     (let ((existing (gethash truename *module-map*)))
       (cond ((null existing))
            ((eq (module-state existing) t)
+            (when (plusp (module-errors existing))
+              (error "Module `~A' contains errors" name))
             (return-from build-module existing))
            (t
-            (error "Module ~A already being imported at ~A"
+            (error "Module `~A' already being imported at ~A"
                    name (module-state existing))))))
 
   ;; Construct the new module.
@@ -99,10 +103,14 @@ (defun call-with-module-environment (thunk &optional (module *module*))
   (progv
       (mapcar #'car *module-bindings-alist*)
       (module-variables module)
-    (unwind-protect (funcall thunk)
-      (setf (module-variables module)
-           (mapcar (compose #'car #'symbol-value)
-                   *module-bindings-alist*)))))
+    (handler-bind ((error (lambda (cond)
+                           (declare (ignore cond))
+                           (incf (slot-value module 'errors))
+                           :decline)))
+      (unwind-protect (funcall thunk)
+       (setf (module-variables module)
+             (mapcar (compose #'car #'symbol-value)
+                     *module-bindings-alist*))))))
 
 (defun call-with-temporary-module (thunk)
   "Invoke THUNK in the context of a temporary module, returning its values.
@@ -144,16 +152,6 @@ (defmethod module-import ((class sod-class))
 ;;;--------------------------------------------------------------------------
 ;;; Code fragments.
 
-(export '(c-fragment c-fragment-text))
-(defclass c-fragment ()
-  ((location :initarg :location :type file-location :reader file-location)
-   (text :initarg :text :type string :reader c-fragment-text))
-  (:documentation
-   "Represents a fragment of C code to be written to an output file.
-
-   A C fragment is aware of its original location, and will bear proper #line
-   markers when written out."))
-
 (defun output-c-excursion (stream location func)
   "Invoke FUNC surrounding it by writing #line markers to STREAM.
 
@@ -230,10 +228,10 @@ (defparameter *module-dirs* nil
    See `find-file' for the grubby details.")
 
 (export 'find-file)
-(defun find-file (scanner name what thunk)
+(defun find-file (home name what thunk)
   "Find a file called NAME on the module search path, and call THUNK on it.
 
-   The file is searched for relative to the SCANNER's current file, and also
+   The file is searched for relative to the HOME file or directory, and also
    in the directories mentioned in the `*module-dirs*' list.  If the file is
    found, then THUNK is invoked with two arguments: the name we used to find
    it (which might be relative to the starting directory) and the truename
@@ -247,8 +245,7 @@ (defun find-file (scanner name what thunk)
    THUNK is not invoked with any additional handlers defined."
 
   (handler-case
-      (dolist (dir (cons (pathname (scanner-filename scanner)) *module-dirs*)
-              (values nil nil))
+      (dolist (dir (cons home *module-dirs*) (values nil nil))
        (let* ((path (merge-pathnames name dir))
               (probe (probe-file path)))
          (when probe