,@body))
+(defmacro time-seconds (&body body)
+ (let ((t1 (gensym)))
+ `(let ((,t1 (get-internal-real-time)))
+ (values
+ (progn ,@body)
+ (coerce (/ (- (get-internal-real-time) ,t1)
+ internal-time-units-per-second)
+ 'double-float)))))
+
(defmacro time-iterations (n &body body)
(let ((i (gensym))
(count (gensym)))
,element-type) ,table-name)
(cons buffer buffers))))))))
+(defmacro def-cached-instance (name)
+ (let* ((new-name (concat-symbol "new-" name "-instance"))
+ (release-name (concat-symbol "release-" name "-instance"))
+ (cache-name (concat-symbol "*cached-" name "-instance-table*"))
+ (lock-name (concat-symbol "*cached-" name "-instance-lock*")))
+ `(eval-when (:compile-toplevel :load-toplevel :execute)
+ (defvar ,cache-name nil)
+ (defvar ,lock-name (kmrcl::make-lock ',name))
+
+ (defun ,new-name ()
+ (kmrcl::with-lock-held (,lock-name)
+ (if ,cache-name
+ (pop ,cache-name)
+ (make-instance ',name))))
+
+ (defun ,release-name (instance)
+ (kmrcl::with-lock-held (,lock-name)
+ (push instance ,cache-name))))))
+
+(defmacro with-ignore-errors (&rest forms)
+ `(progn
+ ,@(mapcar
+ (lambda (x) (list 'ignore-errors x))
+ forms)))
+
+(defmacro ppmx (form)
+ "Pretty prints the macro expansion of FORM."
+ `(let* ((exp1 (macroexpand-1 ',form))
+ (exp (macroexpand exp1))
+ (*print-circle* nil))
+ (cond ((equal exp exp1)
+ (format t "~&Macro expansion:")
+ (pprint exp))
+ (t (format t "~&First step of expansion:")
+ (pprint exp1)
+ (format t "~%~%Final expansion:")
+ (pprint exp)))
+ (format t "~%~%")
+ (values)))
+
+(defmacro defconst (symbol value &optional doc)
+ `(defconstant ,symbol (if (boundp ',symbol)
+ (symbol-value ',symbol)
+ ,value)
+ ,@(when doc (list doc))))