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) の差が未だに分からん。