+(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.
+
+ This is mainly useful for testing things which depend on module variables.
+ This is the functionality underlying `with-temporary-module'."
+ (let ((*module* (make-instance 'module
+ :name "<temp>"
+ :state nil)))
+ (with-module-environment ()
+ (module-import *builtin-module*)
+ (funcall thunk))))
+