An actual running implementation, which makes code that compiles.
[sod] / src / module-impl.lisp
index 5343ad0..89e1ffb 100644 (file)
     (when truename
       (setf (gethash truename *module-map*) *module*))
     (unwind-protect
-        (call-with-module-environment (lambda ()
-                                        (module-import *builtin-module*)
-                                        (funcall thunk)
-                                        (finalize-module *module*)))
+        (with-module-environment ()
+          (module-import *builtin-module*)
+          (funcall thunk)
+          (finalize-module *module*))
       (when (and truename (not (eq (module-state *module*) t)))
        (remhash truename *module-map*)))))
 
+(defun call-with-module-environment (thunk &optional (module *module*))
+  "Invoke THUNK with bindings for the module variables in scope.
+
+   This is the guts of `with-module-environment', which you should probably
+   use instead."
+  (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*)))))
+
 (defun call-with-temporary-module (thunk)
   "Invoke THUNK in the context of a temporary module, returning its values.
 
   (let ((*module* (make-instance 'module
                                 :name "<temp>"
                                 :state nil)))
-    (call-with-module-environment
-     (lambda ()
-       (module-import *builtin-module*)
-       (funcall thunk)))))
+    (with-module-environment ()
+      (module-import *builtin-module*)
+      (funcall thunk))))
 
 ;;;--------------------------------------------------------------------------
 ;;; Type definitions.
             (fresh-line stream)
             (format stream "~&#line ~D ~S~%"
                     (1+ (position-aware-stream-line stream))
-                    (namestring (stream-pathname stream)))))
+                    (let ((path (stream-pathname stream)))
+                      (if path (namestring path) "<sod-output>")))))
          (t
           (funcall thunk)))))