SICP 読み (294) 5.4 積極制御評価器
ハンドアセンブルな今日この頃。書いてる事が微妙ですが、ようやく終わります。
問題 5.26
昨晩の続きにトライ。if が eval される時点から開始。この時点で stack は空なので最大深さは分かりやすい。トータルの回数は何回だろ。(昨晩エントリの最後らへんで_save 18 回で最大深さは 6 回_とある)
- eval-dispatch で if 認定
- exp、env、continue が save (深さ 3)
- continue に ev-if-decide セット
- exp に条件式 (> counter n) セット
- eval-dispatch で application 認定
- eval-dispatch にて variable 認定
- primitive な手続きが val にセットされて continue (ev-appl-did-ope) に jmp
- unev、env が restore (深さ 4)
- argl に空リストがセット
- proc に val (> な手続き) がセット
- proc、argl を save (深さ 6)
- exp に被演算子リストの最初の要素 (counter) セット
- env、unev を save (深さ 8)
- continue に ev-appl-accumulate-arg セット
- eval-dispatch にて variable 認定
- eval-dispatch にて variable 認定
- val に n の値 (1) セット
- continue (ev-appl-accum-last-arg) に jmp
- argl を restore (深さ 5)
- argl に val (1) を追加
- proc を restore (深さ 4) して primitive-apply 方面へ去る
- val に (> 1 1) の結果 (#f になるんかな) をセット
- continue を restore (深さ 3) してそこ (ev-if-decide) に jmp
- continue、env、exp を restore (深さ 0)
- exp に else な式 (iter (* counter product) (+ counter 1)) をセットして eval-dispatch 方面へ去る
- eval-dispatch にて application 認定
- continue、env を save (深さ 2)
- unev に operands ((* counter product) (+ counter 1)) をセットして save (深さ 3)
- exp に operator (iter) セット
- continue に ev-appl-did-operator セット eval 方面に去る
- eval-dispatch にて variable 認定
- val に手続きセットして continue (ev-appl-did) に jmp
- unev、env を restore (深さ 1)
- argl に空リストをセット、proc に val をセット
- proc を save (深さ 2)
- argl も save (深さ 3)
- exp に unev の先頭要素 (* counter product) をセット
- env、unev を save (深さ 5)
- continue に ev-appl-accumulate-arg をセットして eval 方面へ
- eval-dispatch で application 認定
- continue、env を save (深さ 7)
- unev に operands (counter product) をセットして save (深さ 8)
- exp に operator (*) をセット
- continue に ev-appl-did-operator をセットして eval 方面へ
- eval では variable 認定
- val に primitive な手続きがセットされて continue に jmp
- unev と env を resotre (深さ 6)
- argl に空リストをセット、proc に val をセット
- proc を save (深さ 7)
- argl も save (深さ 8)
- exp に unev の先頭要素 (counter) をセット
- env と unev を save (深さ 10)
- continue に ev-appl-accumulate-arg をセットして eval 方面へ
- eval-dispatch で variable 認定
- val に counter が束縛されている値 (1) を格納
- continue (ev-appl-accumulate-arg) へ jmp
- unev、env、argl を restore (深さ 7)
- argl に val (1) を追加
- unev に unev の cdr をセット
- ev-appl-operand-loop に jmp
- argl を save (深さ 8)
- exp に unev の先頭要素 (product) をセット
- 最終要素なので ev-appl-last-arg に jmp
- continue に ev-appl-accum-last-arg をセットして eval 方面へ
- eval-dispatch にて variable 認定
- val に product が束縛されている値 (1) を格納
- continue (ev-appl-accum-last-arg) に jmp
- argl を restore (深さ 7)
- argl に val (1) を追加
- proc を restore (深さ 6)
- apply-dispatch に jmp
- primitive-apply に jmp
- val に (* 1 1) の結果を格納
- continue (ev-appl-accumulate-arg) を restore (深さ 5)
- continue に jmp
- unev、env、argl を resotre (深さ 2)
- argl に val を追加
- unev に unev の cdr をセット (+ counter 1)
- ev-appl-operand-loop に jmp
- argl を save (深さ 3)
- exp に unev の先頭要素をセット
- 最終要素なので ev-appl-last-arg に jmp
- continue に ev-appl-accum-last-arg をセットして eval 方面へ
- eval-dispatch にて application 認定
- continue、env を save (深さ 5)
- unev に operands (counter 1) をセットして save (深さ 6)
- exp に operator (+) をセット
- continue に ev-appl-did をセットして eval 方面
- eval-dispatch にて variable 認定
- val に primitive な手続きがセットされて continue に jmp
- unev と env を restore (深さ 4)
- argl に空リストをセット、proc に val をセット
- proc を save (深さ 5)
- argl を save (深さ 6)
- exp に unev の先頭要素 (counter) をセット
- env と unev を save (深さ 8)
- continue に ev-appl-accumulate-arg をセットして eval 方面へ
- eval-dispatch で variable 認定
- val に counter が束縛されている値 (1) を格納
- continue (ev-appl-accumulate-arg) へ jmp
- unev、env、argl を restore (深さ 5)
- argl に val (1) を追加
- unev に unev の cdr をセット
- ev-appl-operand-loop に jmp
- argl を save (深さ 6)
- exp に unev の先頭要素 (1) をセット
- 最終要素なので ev-appl-last-arg に jmp
- continue に ev-appl-accum-last-arg をセットして evel 方面へ
- eval-dispatch にて self-eval 認定
- val に exp の値をセット
- continue (ev-appl-accum-last-arg) に jmp
- argl を restore (深さ 5)
- argl に val を追加
- proc を restore (深さ 4)
- apply-dispatch に jmp
- primitive-apply に jmp
- val に (+ 1 1) の結果を格納
- continue を restore して jmp (ev-appl-accum-last-arg)
- argl を restore (深さ 2)
- argl に val (2) を追加
- proc を restore (深さ 1)
- apply-dispatch に jmp
- compound-apply に jmp
- 環境の準備をして ev-sequence に jmp
- exp に if 式をセット
- ラストの式なので ev-sequence-last-exp に jmp
- continue を restore (深さ 0) して eval 方面へ去る
- eval-dispatch で if 認定 (この項の最初に戻った)
- exp、env、continue を save (深さ 3)
- continue に ev-if-decide セット
- exp に条件式 (> counter n) セット
- eval-dispatch で application 認定
- continue、env が save (深さ 5)
- unev に operands (counter n) セット
- unev も save (深さ 6)
- exp に演算子 (>) セット
- continue に ev-appl-did-operator セット
- eval-dispatch にて variable 認定
- primitive な手続きが val にセットされて continue (ev-appl-did-ope) に jmp
- unev、env が restore (深さ 4)
- argl に空リストがセット
- proc に val (> な手続き) がセット
- proc、argl を save (深さ 6)
- exp に被演算子リストの最初の要素 (counter) セット
- env、unev を save (深さ 8)
- continue に ev-appl-accumulate-arg セット
- eval-dispatch にて variable 認定
- eval-dispatch にて variable 認定
- val に n の値 (1) セット
- continue (ev-appl-accum-last-arg) に jmp
- argl を restore (深さ 5)
- argl に val (1) を追加
- proc を restore (深さ 4) して primitive-apply 方面へ去る
- val に (> 2 1) の結果 (#t になるんかな) をセット
- continue を restore (深さ 3) してそこ (ev-if-decide) に jmp
- continue、env、exp を restore (深さ 0)
- exp に then な式 (product) をセットして eval-dispatch 方面へ去る
- eval-dispatch にて variable 認定
- val に product の値 (1) をセット
- continue に jmp
やったぁ終わったぞ〜♪
再帰呼び出し時に stack が空っぽだったあたり、ポイント高し。
save の回数
数えてみたら 64 だった。最大深さも 10 でぴったり。