Skip to content

Instantly share code, notes, and snippets.

@y2q-actionman
Last active September 27, 2018 07:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save y2q-actionman/5a8cbf54013106a1580dc5aaf5deb129 to your computer and use it in GitHub Desktop.
Save y2q-actionman/5a8cbf54013106a1580dc5aaf5deb129 to your computer and use it in GitHub Desktop.
Common Lisp での power-assert (30分で作った適当実装)
(in-package :cl-user)
(defmacro power-assert (form)
(assert (listp form))
(let ((op (first form))
(result (gensym))
binding
eval-form)
(assert (fboundp op) ()
"Operator must be fbound. (op is ~A)" op)
(assert (not (special-operator-p op)) ()
"Operator must not a special-operator (op is ~A)" op)
(assert (not (macro-function op)) ()
"Operator must not a macro (currently) (op is ~A)." op)
(loop for arg in (rest form)
as gsym = (gensym)
do (push `(,gsym ,arg) binding)
collect gsym into eval-form-args
finally
(setf binding (nreverse binding)
eval-form (list* op eval-form-args)))
`(let (,@binding (,result nil))
(handler-bind
((error (lambda (e)
(format *debug-io* "~&Result: ~A~%" ,result)
,@(loop for i from 1
for (gsym original) in binding
collect `(format *debug-io* "~&~:R form: ~A => ~A~%"
,i ',original ,gsym))
;; decline
)))
(setf ,result
(assert ,eval-form ()
"Assertion ~A failed" ',form))))))
#|
(power-assert (eq (+ 1 2) (- 5 2)))
CL-USER> (power-assert (eq (+ 1 2) (- 5 1)))
Result: NIL
first form: (+ 1 2) => 3
second form: (- 5 1) => 4
Assertion (EQ (+ 1 2) (- 5 1)) failed
[Condition of type SIMPLE-ERROR]
|#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment