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 認定
    • continue、env が save (深さ 5)
    • unev に 被演算子 (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 認定
    • val に counter の値 (1) をセット
    • continue (ev-appl-accumulate-arg) に jmp
    • unev、env、argl を restore (深さは 5)
    • argl に 1 が追加される
    • unev に被演算子リストの cdr がセット
    • ev-appl-operand-loop に jmp
    • argl が save (深さ 6)
    • exp に被演算子リストの先頭要素 (n) がセット
    • 最後の要素なので ev-appl-last-arg に jmp
    • continue に ev-appl-accum-last-arg セット
  • 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 認定
    • val に counter の値 (2) をセット
    • continue (ev-appl-accumulate-arg) に jmp
    • unev、env、argl を restore (深さは 5)
    • argl に 2 が追加される
    • unev に被演算子リストの cdr がセット
    • ev-appl-operand-loop に jmp
    • argl が save (深さ 6)
    • exp に被演算子リストの先頭要素 (n) がセット
    • 最後の要素なので ev-appl-last-arg に jmp
    • continue に ev-appl-accum-last-arg セット
  • 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 でぴったり。