(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) を実行する。 |
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)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