;;;--------------------------------------------------------------------------
;;; 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)
(: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."))
+ A C fragment is aware of its original location, and will bear proper
+ `#line' markers when written out."))
-(defun output-c-excursion (stream location thunk)
- "Invoke THUNK surrounding it by writing #line markers to STREAM.
+(defun output-c-excursion (stream location func)
+ "Invoke FUNC surrounding it by writing #line markers to STREAM.
The first marker describes LOCATION; the second refers to the actual
output position in STREAM. If LOCATION doesn't provide a line number then
no markers are output after all. If the output stream isn't
- position-aware then no final marker is output."
-
- (let* ((location (file-location location))
- (line (file-location-line location))
- (filename (file-location-filename location)))
- (cond (line
- (when (typep stream 'position-aware-stream)
- (format stream "~&#line ~D~@[ ~S~]~%" line filename))
- (funcall thunk)
- (when (typep stream 'position-aware-stream)
- (fresh-line stream)
- (format stream "#line ~D ~S~%"
- (1+ (position-aware-stream-line stream))
- (let ((path (stream-pathname stream)))
- (if path (namestring path) "<sod-output>")))))
- (t
- (funcall thunk)))))
+ position-aware then no final marker is output.
+
+ FUNC is passed the output stream as an argument. Complicated games may be
+ played with interposed streams. Try not to worry about it."
+
+ (flet ((doit (stream)
+ (let* ((location (file-location location))
+ (line (file-location-line location))
+ (filename (file-location-filename location)))
+ (cond (line
+ (when (typep stream 'position-aware-stream)
+ (format stream "~&#line ~D~@[ ~S~]~%" line filename))
+ (funcall func stream)
+ (when (typep stream 'position-aware-stream)
+ (fresh-line stream)
+ (format stream "#line ~D ~S~%"
+ (1+ (position-aware-stream-line stream))
+ (let ((path (stream-pathname stream)))
+ (if path (namestring path)
+ "<sod-output>")))))
+ (t
+ (funcall func stream))))))
+ (print-ugly-stuff stream #'doit)))
(defmethod print-object ((fragment c-fragment) stream)
(let ((text (c-fragment-text fragment))
(prin1 (subseq text 0 37) stream)
(write-string "..." stream))))
(output-c-excursion stream location
- (lambda () (write-string text stream))))))
+ (lambda (stream) (write-string text stream))))))
(defmethod make-load-form ((fragment c-fragment) &optional environment)
(make-load-form-saving-slots fragment :environment environment))
(export '(code-fragment-item code-fragment code-fragment-reason
code-fragment-name code-fragment-constraints))
(defclass code-fragment-item ()
- ((fragment :initarg :fragment :type c-fragment :reader code-fragment)
+ ((fragment :initarg :fragment :type (or string c-fragment)
+ :reader code-fragment)
(reason :initarg :reason :type keyword :reader code-fragment-reason)
(name :initarg :name :type t :reader code-fragment-name)
(constraints :initarg :constraints :type list