(step expression)

expression の評価をステップ実行する。以下の状況で利用者との対話が行われる。
Eval: expression ?
expression を評価しようとしている。 以下のコマンドが使用できる。
(改行) 引続きステップ実行を行う。
n expression が値を返すまで通常の実行を行う。
r 式の入力を求められる。入力した式がトップレベルの環境で評価され expression の値のかわりに使用される。
e 式の入力を求められる。入力した式が expression と同じ環境で評価され、 その値が表示される。
b (break) を実行する。

Tail recursion: expression ?
expression を末尾再帰の状況で評価しようとしている。使用できるコマンドは Eval: におけるものと同じ。

Return: value ?
value が評価値として求められた。 以下のコマンドが使用できる。
(改行) 引続きステップ実行を行う。
r 式の入力を求められる。入力した式がトップレベルの環境で評価され value のかわりに使用される。
b (break) を実行する。
補足
  1. 評価するリストの第一要素が変数の場合、その変数の評価過程が表示され るのはそのリストがはじめて評価される時のみである。
  2. step はマクロ展開の過程までステップ実行する。 ただし一度展開されたマクロ呼び出しは元の式に置き換えられるので、 展開がステップ実行されるのは呼び出しの最初の評価のみとなる。
実行例
pi: (step (tak 3 2 1))
Eval: (tak 3 2 1) ? ?
step n}ext r}eturn e}val b}reak
Eval: (tak 3 2 1) ? 
 Eval: tak ? 
 Return: #<020383F8> ? 
 Eval: 3 ? 
 Return: 3 ? 
 Eval: 2 ? 
 Return: 2 ? 
 Eval: 1 ? 
 Return: 1 ? 
Tail recursion: (if (not (< y x)) z (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y))) ? ?
step n}ext r}eturn e}val b}reak
Tail recursion: (if (not (< y x)) z (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y))) ? 
 Eval: if ? 
 Return: #<0202AA40> ? 
 Eval: (not (< y x)) ? n
 Return: #f ? ?
step r}eturn b}reak
 Return: #f ? 
Tail recursion: (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y)) ? e
Expression? x
3
Tail recursion: (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y)) ? e
Expression? y
2
Tail recursion: (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y)) ? 
 Eval: tak ? 
 Return: #<020383F8> ? 
 Eval: (tak (- x 1) y z) ? e
Expression? z
1
 Eval: (tak (- x 1) y z) ? b
break> (continue)
 Eval: (tak (- x 1) y z) ? n
 Return: 1 ? r
Value? 2
 Eval: (tak (- y 1) z x) ? r
Value? 1
 Eval: (tak (- z 1) x y) ? 
  Eval: tak ? 
  Return: #<020383F8> ? 
  Eval: (- z 1) ? n
  Return: 0 ? 
  Eval: x ? 
  Return: 3 ? 
  Eval: y ? 
  Return: 2 ? 
 Tail recursion: (if-parsed (not (< y x)) z (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y))) ? n
 Return: 2 ? 
Tail recursion: (if-parsed (not (< y x)) z (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y))) ? 
 Eval: (not (< y x)) ? 
  Eval: (< y x) ? 
   Eval: y ? 
   Return: 1 ? 
   Eval: x ? 
   Return: 2 ? 
  Return: #t ? 
 Return: #f ? 
Tail recursion: (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y)) ? r
Value? 'foo
Return: foo ? 
foo
pi: (step (let ((x 0) (y 1)) (cons x y)))
Eval: (let ((x 0) (y 1)) (cons x y)) ? 
 Eval: let ? 
 Return: #<000884A8> ? 
Tail recursion: ((lambda (x y) (cons x y)) 0 1) ? 
 Eval: (lambda (x y) (cons x y)) ? 
  Eval: lambda ? 
  Return: #<00088468> ? 
 Tail recursion: (rp:lambda (x y) (cons x y)) ? 
  Eval: rp:lambda ? 
  Return: #<100FC0B8> ? 
 Return: #<0009AE90> ? 
 Eval: 0 ? 
 Return: 0 ? 
 Eval: 1 ? 
 Return: 1 ? 
Tail recursion: (cons x y) ? 
 Eval: cons ? 
 Return: #<100FBA18> ? 
 Eval: x ? 
 Return: 0 ? 
 Eval: y ? 
 Return: 1 ? 
Return: (0 . 1) ? 
(0 . 1)

(trace function-name ...)

function-name を名前として持つ手続きの呼び出しと戻りにおいてそれぞれ引数、 値を表示させるようにする。 Scheme においては手続きはリターンしないことも多いので呼び出しフレームは インデントではなくシリアル番号で示すようにしてある。

実行例

pi: (trace tak)
#<done>
pi: (tak 3 2 1)
<0>Call: (tak 3 2 1)
<1>Call: (tak 2 2 1)
<1>Return: 1
<2>Call: (tak 1 1 3)
<2>Return: 3
<3>Call: (tak 0 3 2)
<3>Return: 2
<4>Call: (tak 1 3 2)
<4>Return: 2
<0>Return: 2
2

(trap function-name ...)

trace では表示のみであるが、trap では呼び出しのたびに利用者との対話を行う。 戻りでは表示も行われないが、 そのことによって末尾再帰によるくり返しでも正常に実行可能である。
Call: (function . args) ?
function が呼び出されようとしている。 以下のコマンドが使用できる。
(改行) そのまま実行を続ける。
s ステップ実行に入る。
r 式の入力を求められる。 入力した式がトップレベルの環境で評価され戻り値のかわりに使用される。
b (break) を実行する。
実行例
pi: (trap tak)
#<done>
pi: (tak 3 2 1)
Call: (tak 3 2 1) ? 
Call: (tak 2 2 1) ? 
Call: (tak 1 1 3) ? ?
pass s}tep r}eturn b}erak
Call: (tak 1 1 3) ? b
break> (continue)
Call: (tak 1 1 3) ? s
Eval: (if-parsed (not (< y x)) z (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y))) ? 
 Eval: (not (< y x)) ? n
 Return: #t ? 
Tail recursion: z ? 
Return: 3 ? 
Call: (tak 0 3 2) ? 
Call: (tak 1 3 2) ? r
Value? -1
-1

(untrace function-name ...)

trace, trap を解除する。

(trace-error expression)

rhizome/pi は通常エラーが起こった場合その場所について何も報告しない。 trace-error のもとで実行することによりエラー時のバックトレースを対話的に ブラウズすることができる。ただし実行速度はかなり遅くなる。
frame ?
以下のコマンドが使用できる。
(改行) 親フレームを表示する。
e 式の入力を求められる。 入力した式が frame と同じ環境で評価され、 その値が表示される。
b (break) を実行する。
a 全フレームを表示する。
q バックトレースの表示を終了する。
なお、バックトレースの情報は変数 $err にセーブされており、 (backtrace $err) で再表示させることができる。 (もちろん $err の内容を他の変数等に移すこともできる。)

実行例

pi: (define (len1 l) (if (null? l) 0 (+ (len1 (cdr l)) 1)))
#<done>
pi: (trace-error (len1 '(1 2 3 . 4)))

Illegal argument supplied to function
Backtrace:
(cdr l) ? ?
parent e}val b}reak a}ll q}uit
(cdr l) ? e
Expression? l
4
(cdr l) ? 
(len1 (cdr l)) ? 
=tail-recursion=> (+ (len1 (cdr l)) 1) ? 
(len1 (cdr l)) ? 
=tail-recursion=> (+ (len1 (cdr l)) 1) ? e
Expression? l
(3 . 4)
=tail-recursion=> (+ (len1 (cdr l)) 1) ? 
(len1 (cdr l)) ? e
Expression? l
(2 3 . 4)
(len1 (cdr l)) ? b
break> (continue)
(len1 (cdr l)) ? a
=tail-recursion=> (+ (len1 (cdr l)) 1)
(len1 (cdr l))
=tail-recursion=> (+ (len1 (cdr l)) 1)
(len1 (quote-parsed 1 2 3 . 4))
#f
pi: (trace-error (len1 '(1 2 3 4 5 6 7 8 . 9)))

Illegal argument supplied to function
Backtrace:
(cdr l) ? e
Expression? l
9
(cdr l) ? q
#f

インデックス