SICP 読み (283) 5.4 積極制御評価器

問題 5.25

ええと、thunk にされる式って compound な手続きの引数だったはず。なので一旦 eval で引数に格納 (束縛) された中身を取り出した上でそれを force-it する、という流れ。
で、actual-value の一連の処理は以下

actual-value
  (save continue)
  (assign continue (label force-it))
  (goto (label eval-dispatch))

force-it
  (restore continue)
  (test (op thunk?) (reg val))
  (branch (label go-to-actual-value))
  (goto (reg continue))

go-to-actual-value
  (assign exp (op thunk-exp) (reg val))
  (assign env (op thunk-env) (reg val))
  (goto (label actual-value))

なのだろうか。これ、一応正しいと見て 4.2 節なナニを見てみるに

  • apply に渡す operator は actual-value したものを渡す
  • primitive な手続きは引数を actual-value する
  • compound な手続きは引数を delay する

を盛り込めば ev-application は OK なのかなぁ。ちょっと気になるのは上記の actual-value の中で exp と env を上書きしているトコロ。actual-value を呼ぶ前に push してれば問題ないとは思うのですが。
とりあえず、ざくっと検討したソレを以下に。

ev-application
  (save continue)
  (save env)
  (assign unev (op operands) (reg exp))
  (save uenv)
  (assign exp (op operator) (reg exp))
  (assign continue (label ev-appl-did-operator)
  (goto (label actual-value))

ev-appl-did-operator
  (restore uenv)
  (restore env)
  (assign argl (op empty-arglist))
  (assign proc (reg val))
  (test (op no-operands?) (reg unev))
  (branch (label apply-dispatch))
  (test (op primitive-procedure?) (reg proc)
  (branch (label ev-appl-operand-loop))

ev-appl-delay-loop
  (save proc)
  (save argl)
  (assign exp (op first-operand) (reg uenv))
  (test (op last-operand?) (reg uenv))
  (branch (label ev-appl-last-delay-arg))
  (assign val (op delay-it) (reg exp))
  (save env)
  (save uenv)
  (goto (label ev-appl-accumlate-arg))

ev-appl-operand-loop
  (save proc)
  (save argl)
  (assign exp (op first-operand) (reg uenv))
  (test (op last-operand?) (reg uenv))
  (branch (label ev-appl-last-arg))
  (save env)
  (save uenv)
  (assign continue (label ev-appl-accumulate-arg))
  (goto (label actual-value))

ev-appl-accumulate-arg
  (restore unev)
  (restore env)
  (restore argl)
  (restore proc)
  (assign argl (op adjoin-arg) (reg val) (reg argl))
  (assign unev (op rest-operands) (reg unev))
  (test (op compound-procedure?) (reg proc))
  (branch (label ev-appl-delay-loop))
  (goto (label ev-appl-operand-loop))

ev-appl-last-delay-arg
  (assign val (op delay-it) (reg exp))
  (goto (label ev-appl-accum-last-arg))

ev-appl-last-arg
  (assign continue (label ev-appl-accum-last-arg))
  (goto (label actual-value))

ev-appl-accum-last-arg
  (restore argl)
  (assign argl (op adjoin-arg) (reg val) (reg argl))
  (restore proc)
  (goto (label apply-dispatch))

なんとなくで良いので当たってて欲しい (弱
あとは ev-if が以下になっていれば良いのかなぁ。

ev-if
  (save exp)                    ; save expression for later
  (save env)
  (save continu)
  (assign continue (label ev-if-decide))
  (assign exp (op if-predicate) (reg exp))
  (goto (label actual-value))  ; evaluate the predicate

とりあえず検証は別途とゆー事でエントリ投入。できればもう少し机上検証予定。