fu7mu4’s diary

はてなダイアリーから移転しました。

cl-user:step のない clozure cl のために cl-stepper を入れる

clozure cl では step (cl-user:step) が実装されていないそうだ。

(defun fact (x)
   (if (< x 1)
	1
	(* x (fact (1- x)))))
(step (fact 5)) ;;-> 120  ;cclではステップ実行できずに直ぐに値がかえってくる。


そこで quicklisp で cl-stepper を入れてみた。

(ql:quickload "com.informatimago.common-lisp.lisp.stepper")

cl-stepper:step をつかってみる。

各段階毎に入力の選択肢がでるみたいだ。

(Will evaluate (fact 5) ;;;評価する内容
Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)? ;;;選択肢

実行例

(defpackage :test (:use :cl-stepper))
(in-package :test)
(defun fact (x)
   (if (< x 1)
	1
	(* x (fact (1- x)))))
(step (fact 5))
;;; ここからステップ実行開始
(Will evaluate (fact 5)
 Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s
Will evaluate (fact 5)
 (Will evaluate 5
  Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s

  (--> 5))
 (Entering function fact
   (Bind x                to 5)
  Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s

  (Will evaluate (if (< x 1) 1 (* x (fact #)))
   Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s
Will evaluate (if (< x 1) 1 (* x (fact #)))
   (Will evaluate (< x 1)
    Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s
Will evaluate (< x 1)
    (Will evaluate x
     Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s

     (x ==> 5))
    (Will evaluate 1
     Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s

     (--> 1))
    Evaluation of (< x 1) returned one result ==> NIL)
   (Will evaluate (* x (fact (1- x)))
    Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s
Will evaluate (* x (fact (1- x)))
    (Will evaluate x
     Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s

     (x ==> 5))
    (Will evaluate (fact (1- x))
     Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s
Will evaluate (fact (1- x))
     (Will evaluate (1- x)
      Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s
Will evaluate (1- x)
      (Will evaluate x
       Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s

       (x ==> 5))
      Evaluation of (1- x) returned one result ==> 4)
     (Entering function fact
       (Bind x                to 4)
      Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s

      (Will evaluate (if (< x 1) 1 (* x (fact #)))
       Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?s
Will evaluate (if (< x 1) 1 (* x (fact #)))
       (Will evaluate (< x 1)
        Step Into (s, si, RET), Step over (so), Trace (t), Function (f), Run (r), List (l), Eval (e), Debugger (d), Abort (a, q)?q

(in-package :cl-user) ; 元にもどる

追記

インストールは簡単におわったが、実行方法を誤解したため、とても時間がかかってしまった。

(in-package :cl-user)
(cl-stepper:step (fact 5))

とやると、評価中にまた step を呼出すんだけれど、それが cl-user:step になってしまうためすぐに終わってしまう。cl-stepper:step を step で呼びだせるようにしないとうまくいかないので注意。これ以外の方法としては、たとえば、step というシンボルに cl-stepper:step をBINDすればいけるのだろうが、試していない。