Concurrent Clean : ABCマシン(11)
[id:lethevert:20060421:p3]
Start = app (+) 3 5
これが、次のようなABCコードに変換される
buildh e_StdInt_d+;6 0 buildI 5 buildI 3 push_a 2 update_a 2 3 update_a 1 2 update_a 0 1 pop_a 1 jsr e_Lib_sapp pushI_a 0 pop_a 1 rtn
update_aが3つ並んでいるのは、A-Stack上の並び替えを行っているだけなので、次のように書いても同じ。
buildI 5 buildI 3 buildh e_StdInt_d+;6 0 jsr e_Lib_sapp pushI_a 0 pop_a 1 rtn
jsrは関数呼び出し。呼び出し先の関数は次のような関数。
app :: (a a -> a) a a -> a app f a b = f a b
これは、次のようにコンパイルされる。
jsr_eval 0 push_a 1 push_a 1 update_a 1 3 updatepop_a 0 2 jsr e_system_sAP push_a 1 push_a 1 update_a 1 2 update_a 0 1 pop_a 1 update_a 1 2 updatepop_a 0 1 jmp e_system_sAP
やけに長いけれど、これは、関数fの引数に対して、thunkを作っているかなぁ。e_system_sAPが何を意味しているのかよく分かってないのだけれど。
-
-
- -
-
こうかな?
jsr_eval 0 [+,3,5] push_a 1 [3,+,3,5] push_a 1 [+,3,+,3,5] update_a 1 3 [+,3,+,3,5] updatepop_a 0 2 [+,3,5] jsr e_system_sAP [(+ 3),5] push_a 1 [5,(+ 3),5] push_a 1 [(+ 3),5,(+ 3),5] update_a 1 2 [(+ 3),5,5,5] update_a 0 1 [(+ 3),(+ 3),5,5] pop_a 1 [(+ 3),5,5] update_a 1 2 [(+ 3),5,5] updatepop_a 0 1 [(+ 3),5] jmp e_system_sAP (+ 3 5)
e_system_sAPは、A-Stackのトップの関数に、2つ目のグラフを適用する関数かなと思います。つまり、こんな感じ。
e_system_sAP [a0,a1:ar] = [a0 a1:ar]
2回に分けて適用しているのは、カリー化した次のような関数が来る可能性があるから。
f a = g where g b = (+) a b
で、それ以外の部分は、A-Stack上の並び替えを行っているだけなので、このケースではこれでOK
jsr_eval 0 jsr e_system_sAP jmp e_system_sAP