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