SICP 読み (305) 5.5 翻訳系
割込み (というか本業) が入ってこないからどんどんヤッツケる。
次 (f (g 'x) 'y)
しかし一旦直列な命令列にして云々とゆーのはどう考えても無理だろ。でも面白いのでこのまま続けてみる。未だに三番目と四番目の差が分からんし。
(save continue) は略で以下。
(save env) (assign unev (op operands) (reg exp)) (save unev) (assign exp (op operator) (reg exp)) (assign val (op lookup-variable-value) (reg exp) (reg env)) (restore unev) (restore env) (assign argl (op empty-arglist)) (assign proc (reg val)) (save proc) (save argl) (assign exp (op first-operand) (reg unev)) (save env) (save unev) ;; (g 'x) (save continue) (save env) (assign unev (op operands) (reg exp)) (save unev) (assign exp (op operator) (reg exp)) (assign val (op lookup-variable-value) (reg exp) (reg env)) (restore unev) (restore env) (assign argl (op empty-arglist)) (assign proc (reg val)) (save proc) (save argl) (assign exp (op first-operand) (reg unev)) (assign val (op text-of-quotation) (reg exp)) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl)) (restore proc) (goto (label apply-dispatch)) ;; 略 (val に結果が格納されて restore された continue に戻る) (restore unev) (restore env) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl)) (assign unev (op rest-operands) (reg unev)) (save argl) (assign exp (op first-operand) (reg unev)) (assign val (op text-of-quotation) (reg exp)) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl)) (restore proc) (goto (label apply-dispatch))
長い。一日の文字数限界超えたら笑うが、そこまで書ける訳ゃないだろ、と。
続
ヤッツけ中にでっかい割込みが数件。ばたばた杉で頭痛。レモネードをいただきつつ、続行。いきなり seq1 と seq2 に分けちまえ。以下がその一の seq1。
(assign unev (op operands) (reg exp)) (assign exp (op operator) (reg exp)) (assign val (op lookup-variable-value) (reg exp) (reg env))
次が seq2
(assign argl (op empty-arglist)) (assign proc (reg val))
これは save/restore が省略できる。次がその二の seq1。
(save argl) (assign exp (op first-operand) (reg unev)) (save env) (save unev) ;; (g 'x) (save continue) (save env) (assign unev (op operands) (reg exp)) (save unev) (assign exp (op operator) (reg exp)) (assign val (op lookup-variable-value) (reg exp) (reg env)) (restore unev) (restore env) (assign argl (op empty-arglist)) (assign proc (reg val)) (save proc) (save argl) (assign exp (op first-operand) (reg unev)) (assign val (op text-of-quotation) (reg exp)) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl)) (restore proc) (goto (label apply-dispatch)) ;; 略 (val に結果が格納されて restore された continue に戻る) (restore unev) (restore env) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl)) (assign unev (op rest-operands) (reg unev)) (save argl) (assign exp (op first-operand) (reg unev)) (assign val (op text-of-quotation) (reg exp)) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl))
で、次が seq2
(goto (label apply-dispatch))
ここでは proc の save/restore が必要になりますな。引数の評価で (g 'x) な application がございますのでカブってしまう。
で、この seq1 の一群はさらに分割可能。
むむ
なんかカン違いしてる気がするぞ。
演算子を eval するときのソレが微妙。このあたり
(save env) (assign unev (op operands) (reg exp)) (save unev) (assign exp (op operator) (reg exp)) (assign val (op lookup-variable-value) (reg exp) (reg env)) (restore unev) (restore env) (assign argl (op empty-arglist)) (assign proc (reg val))
これも入れ子になっていると見ないと駄目かも。いっこめが
(assign unev (op operands) (reg exp)) (save unev) (assign exp (op operator) (reg exp)) (assign val (op lookup-variable-value) (reg exp) (reg env)) (restore unev)
な seq1 と
(restore env) (assign argl (op empty-arglist)) (assign proc (reg val))
な seq2 でその中に
(assign exp (op operator) (reg exp)) (assign val (op lookup-variable-value) (reg exp) (reg env))
な seq1 と空っぽの seq2 がある形になるのかなぁ。これで考えても一応いっこめの seq1 は save/restore 省略可能だし、にこめについては seq2 が無いのでこれも省略可能。
再開
その二の seq1 な式をさらに分割。の前に再度件の seq1 を
(save argl) (assign exp (op first-operand) (reg unev)) (save env) (save unev) ;; (g 'x) (save continue) (save env) (assign unev (op operands) (reg exp)) (save unev) (assign exp (op operator) (reg exp)) (assign val (op lookup-variable-value) (reg exp) (reg env)) (restore unev) (restore env) (assign argl (op empty-arglist)) (assign proc (reg val)) (save proc) (save argl) (assign exp (op first-operand) (reg unev)) (assign val (op text-of-quotation) (reg exp)) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl)) (restore proc) (goto (label apply-dispatch)) ;; 略 (val に結果が格納されて restore された continue に戻る) (restore unev) (restore env) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl)) (assign unev (op rest-operands) (reg unev)) (save argl) (assign exp (op first-operand) (reg unev)) (assign val (op text-of-quotation) (reg exp)) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl))
大まかな切り分けから、という事で seq1 が
(assign exp (op first-operand) (reg unev)) (save env) (save unev) ;; (g 'x) (save continue) (save env) (assign unev (op operands) (reg exp)) (save unev) (assign exp (op operator) (reg exp)) (assign val (op lookup-variable-value) (reg exp) (reg env)) (restore unev) (restore env) (assign argl (op empty-arglist)) (assign proc (reg val)) (save proc) (save argl) (assign exp (op first-operand) (reg unev)) (assign val (op text-of-quotation) (reg exp)) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl)) (restore proc) (goto (label apply-dispatch)) ;; 略 (val に結果が格納されて restore された continue に戻る) (restore unev) (restore env)
seq2 が
(assign argl (op adjoin-arg) (reg val) (reg argl)) (assign unev (op rest-operands) (reg unev)) (save argl) (assign exp (op first-operand) (reg unev)) (assign val (op text-of-quotation) (reg exp)) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl))
ちなみに対象になるレジスタは argl です。ここでも seq1 側で argl を初期化したりなんかしておりますので save/restore は必要。あるいは直上の seq2 で言うと
(assign exp (op first-operand) (reg unev)) (assign val (op text-of-quotation) (reg exp))
が seq1 で
(assign argl (op adjoin-arg) (reg val) (reg argl))
が seq2 になる。対象になるレジスタは argl ですがこれはセイフ。ってこの切り分けかたはダウトだな。次の一群の式は seq2 が無い形になってますので判断微妙。
やっぱ上から順に見ていくのが正しいのかなぁ。
再度検討要
ここまで深く考えなくても良い気がしてきた。ただ三番目の (f (g 'x) y) と (f (g 'x) 'y) の差が未だに分からん。