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