Re: Capturing input-output relation of a function

Andreas Franke via Sbcl-help <[email protected]> Tue, 21 Jan 2025 12:35:03 +0000
Newsgroups gmane.lisp.steel-bank.general
Message-ID <trinity-a3b98d02-701d-4115-b521-09bfff9c5037-1737462903226@trinity-msg-rest-gmx-gmx-live-bbc95d94c-4g6mf>
(defun capture-args/values ()
(destructuring-bind (breakpoint-fun-frame . more-frames)
(list-backtrace :start 3 :count 3)
(destructuring-bind (_lambda _lambda-list _in _trace-breakpoint-fun)
(first breakpoint-fun-frame)
(assert (eql 'lambda _lambda))
(assert (listp _lambda-list))
(assert (eql :in _in))
(ecase _trace-breakpoint-fun
((sb-debug::trace-start-breakpoint-fun)
(let ((args (cdddr breakpoint-fun-frame)))
(destructuring-bind (_trace-call _trace-info _f . _args)
(first more-frames)
(declare (ignorable _trace-info))
(assert (eql 'sb-debug::trace-call _trace-call))
(assert (equal args _args))
(list (sb-kernel:%fun-name _f)
:args _args))))
((sb-debug::trace-end-breakpoint-fun)
(let ((values (cadddr breakpoint-fun-frame)))
(destructuring-bind (_trace-call _trace-info _f . _args)
(second more-frames)
(declare (ignorable _trace-info))
(assert (eql 'sb-debug::trace-call _trace-call))
(list (sb-kernel:%fun-name _f)
:args _args
:values values))))))))

(trace ff :condition-all (progn (push (capture-args/values) mystack) nil))

(ff 3)

(progn (mapc #'print (reverse mystack)) (values))

==>

(FF :ARGS (3))
(FF :ARGS (2))
(FF :ARGS (1))
(FF :ARGS (1) :VALUES (1))
(FF :ARGS (2) :VALUES (2))
(FF :ARGS (3) :VALUES (6))

Using :condition-after should give you what you need.

HTH,

Andreas

Given

(defun ff (n) (if (< n 2) 1 (* n (ff (1- n)))))

(ff 3)

I want to capture the input-output pairs:

(ff 1 1)

(ff 2 2)

(ff 3 6)

(defvar mystack nil)

_______________________________________________
Sbcl-help mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sbcl-help