Today アクセスカウンター Yesterday アクセスカウンター

ホワット・ア・ワンダフル・ワールド

私は知識に何ものかを付け加え,また他の人々がより多くのものを付け加える手助けをした --- G.H.ハーディ

全記事一覧 << 2008/07 12345678910111213141516171819202122232425262728293031 2008/09 >>

プロフィール

あろは (alohakun)

  • Author:あろは (alohakun)
  • 若槻俊宏 (WAKATSUKI toshihiro)

    連絡先 : alohakun ___at___ gmail.com
    mixi : http://mixi.jp/show_friend.pl?id=182927
    twitter : http://twitter.com/alohakun

    abstract

    プログラミングという人間の知的行為を体系化し,単なる職人芸ではなく,サイエンスにするための研究をしています.

    具体的には,等価変換計算モデルに基づいた,仕様記述からのプログラム合成の研究をしています.

    もっと噛み砕くと,プログラムの正しさをどのように定式化し,どのような枠組みで,どのように変換を進めていけば,正しさを保証したまま,効率的なプログラムを手に入れることができるのか,ということについて研究しています.

    キーワード : equivalent transformation, computation model, programming paradigm, formal specification, program synthesis













    あわせて読みたい


    この日記のはてなブックマーク数


    スカウター : ホワット・ア・ワンダフル・ワールド


    Map









    FC2 BLOG RANKING

FC2カウンター

ブロとも申請フォーム

この人とブロともになる

やっと動いたよォオオーー

2006/08/09(水) 18:35:48

他の例題をやりつつ,コンパイラのバグを取りつつ,この間からダラダラずっと取り組んでいた,n 番目の素数を求める nthprime2 D ルール (nthprime *n *nthprime) のコンパイルに,ようやく成功しました.こんなんに何日かかってるんだ,俺のクズ… orz

結局,ETI のレベルでのプログラム変換を徹底して,完全に C のレベルと同じことをする (ETI の配列 (というか,このレベルだと,何でも入るタプル.Java で言うところの,Object 型の配列) 機能とかは,いっさい使わない.本当に,ただのワード配列として,その上に全てのデータ構造をエンコードしていく) ようにしたのが勝因でした.

つまり,C コードへの変換が,死ぬほど単純化されるので,バグが入り込む余地が無くなる.ETI の上でバグ無しで動くのならば,C にコンパイルしても正しく動く (小手先の変なことはいっさいしない).出力結果まで,ほとんど同じ.

ETI (単に ETI の機能を使って出力しているので,C と違って余計なところまで表示されてる.あと,C とは若干構造がことなる部分もある)

[D]>(main (nthprime 2 *))
-------------------------D execution ---------------------
{5 2 2 1 3 7 () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () ()}
{14 INT 2 PVAR () PVAR () REF 9 ARRAY 2 () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () ()}
{1 2 2 1 3 7 2 15 7 17 19 1 27 () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () ()}
{28 INT 2 INT 3 PVAR () REF 9 ARRAY 2 INT 2 INT 3 INT 5 INT 1 INT 2 PVAR () INT 2 INT 2 () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () ()}
----------------------------------------------------------
succeeded.
(main (nthprime 2 3))


C にコンパイルしたもの

$ ./etc '(nthprime 2 *)'

----------------------------------------------------------

String : "(nthprime 2 *)"

Array[] = {26, CONS, SYM, 6, REF, 17, STR, 8, 0x0000006E, 0x00000074, 0x00000068, 0x00000070, 0x00000072, 0x00000069, 0x0000006D, 0x00000065, 0x00000000, CONS, INT, 2, REF, 22, CONS, PVAR, 0, NIL, 0};

Prity print : Memory : {

length : 26


1 Cons
2 (sym (ref 6))
4 (ref 17)
6 String
7 strlen : 8
8 "nthprime"
17 Cons
18 (i 2)
20 (ref 22)
22 Cons
23 (pvar)
25 ()
}

Symbolic expression => (nthprime 2 *23)



{4 2 2 1 3}


{4 2 2 2 *3}

Memory : {

length : 4


1 (i 2)
3 (pvar)
}
nthprime2
Dynamic linking : nthprime2.dll

.....
succeeded !
call : nthprime2



{5 2 2 1 3 7}

Array[] = {14, INT, 2, PVAR, 0, PVAR, 0, REF, 9, ARRAY, 2, NIL, 0, NIL, 0};
Remove : nthprime2.dll

succeeded.
Array[] = {24, INT, 2, INT, 3, PVAR, 0, REF, 9, ARRAY, 2, INT, 2, INT, 3, INT, 5, INT, 1, INT, 2, PVAR, 0, INT, 2};
Memory : {

length : 24


1 (i 2)
3 (i 3)
5 (pvar)
7 (ref 9)
9 Array
10 arrlen : 2
11 (i 2)
13 (i 3)
15 (i 5)
17 (i 1)
19 (i 2)
21 (pvar)
23 (i 2)
}


(nthprime 2 3)

----------------------------------------------------------

やっぱり C 速いよ C.100 とかでも一瞬だ.400 ぐらいまでも一瞬だけど,それ以上は再帰呼び出ししてるからスタックが溢れちゃう.

$ ./etc '(nthprime 100 *)'

----------------------------------------------------------

(省略)
succeeded.
Array[] = {3720, INT, 100, INT, 541, PVAR, 0, REF, 9, ARRAY, 100, INT, 2, INT, 3, INT, 5, INT, 7, INT, 11, INT, 13, INT, 17, INT, 19, INT, 23, INT, 29, INT, 31, INT, 37, INT, 41, INT, 43, INT, 47, INT, 53, INT, 59, INT, 61, INT, 67, INT, 71, INT, 73, INT, 79, INT, 83, INT, 89, INT, 97, INT, 101, INT, 103, INT, 107, INT, 109, INT, 113, INT, 127, INT, 131, INT, 137, INT, 139, INT, 149, INT, 151, INT, 157, INT, 163, INT, 167, INT, 173, INT, 179, INT, 181, INT, 191, INT, 193, INT, 197, INT, 199, INT, 211, INT, 223, INT, 227, INT, 229, INT, 233, INT, 239, INT, 241, INT, 251, INT, 257, INT, 263, INT, 269, INT, 271, INT, 277, INT, 281, INT, 283, INT, 293, INT, 307, INT, 311, INT, 313, INT, 317, INT, 331, INT, 337, INT, 347, INT, 349, INT, 353, INT, 359, INT, 367, INT, 373, INT, 379, INT, 383, INT, 389, INT, 397, INT, 401, INT, 409, INT, 419, INT, 421, INT, 431, INT, 433, INT, 439, INT, 443, INT, 449, INT, 457, INT, 461, INT, 463, INT, 467, INT, 479, INT, 487, INT, 491, INT, 499, INT, 503, INT, 509, INT, 521, INT, 523, INT, 541, INT, 543, INT, 1, INT, 100, PVAR, 0, INT, 2, INT, 3, INT, 3, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 3, INT, 3, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 3, INT, 3, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 23, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 3, INT, 3, INT, 5, INT, 5, INT, 3, INT, 3, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 3, INT, 3, INT, 5, INT, 5, INT, 7, INT, 7, INT, 11, INT, 11, INT, 13, INT, 13, INT, 17, INT, 17, INT, 19, INT, 19, INT, 23, INT, 23, INT, 29};

(省略)

(nthprime 100 541)

昨日書いた,C 言語の関数呼び出しを使わざるを得ない問題は,まだ未解決なのですが… そのせいで,再帰が多くなりすぎると C スタックが溢れたりとか,いろいろ問題が.

あと,致命的なのがもう一つ.nthprime は,primeArray を nthprime が再帰的に呼び出すという構造になっているのですが,今のところ別々に C にコンパイル (nthprime.c と primeArray.c) して,手作業で dll を作るという,情けない状況 (ETI のレベルでは,全てのルール呼び出しは実行時に動的ディスパッチされるので,静的に依存関係を解決する必要が無い)… つまり,こゆこと.

$ gcc -c -shared -std=c99 -o nthprime.o nthprime.c
nthprime.c: In function `nthprime2':
nthprime.c:262: warning: implicit declaration of function `primeArray5'

$ gcc -c -shared -std=c99 -o primeArray.o primeArray.c

$ gcc -shared primeArray.o nthprime.o -o nthprime.dll

それぞれのファイルは,こんな感じ (読み飛ばしてください)

// nthprime.c
#include "et.h"

bool nthprime2(word stack[], word mem[]) {
word base;

nthprime2 :

{
// (getArrayElement stack 1 *A)
base = stack[1];
// (getArrayElement mem 0 *B) = mem[0]
// (:= *C (+ (INT "mem[0]") 1))
int C = mem[0] + 1;
// (:= *D (+ (INT "mem[0]") 2))
int D = mem[0] + 2;
// (setArrayElement mem 0 (INT "D"))
mem[0] = D;
// (setArrayElement mem (INT "C") PVAR)
mem[C] = PVAR;
// (:= *E (+ 3 base))
int E = 3 + base;
// (setArrayElement stack (INT "E") (INT "C"))
stack[E] = C;
// (updateArrayLength (INT "E") stack)

if(stack[0] < E)
stack[0] = E;

// (nthprime21 stack mem)

goto nthprime21;
}

nthprime2_fail :

nthprime21 :
{

// (getArrayElement stack 1 *F)
base = stack[1];
// (not (== (1 (INT 1) base stack mem)))
if(ideref(1, base, stack, mem) == 1)
goto nthprime211;

// (nthprime22 stack mem)

goto nthprime22;
}

nthprime21_fail :

nthprime211 :
{

// (getArrayElement stack 1 *G)
base = stack[1];
// (:= *H (+ 2 base))
int H = 2 + base;
// (getArrayElement stack (INT "H") *I) = stack[H]
// (setArrayElement mem (INT "stack[H]") INT)
mem[stack[H]] = INT;
// (:= *J (+ (INT "stack[H]") 1))
int J = stack[H] + 1;
// (setArrayElement mem (INT "J") 2)
mem[J] = 2;
// (getArrayElement stack base *K) = stack[base]
// (setArrayElement stack 1 (INT "stack[base]"))
stack[1] = stack[base];
// (:= *L (- base 1))
int L = base - 1;
// (setArrayElement stack 0 (INT "L"))
stack[0] = L;
return (bool)stack[base];
}

nthprime211_fail :

nthprime22 :
{

// (getArrayElement stack 1 *M)
base = stack[1];
// (getArrayElement mem 0 *N) = mem[0]
// (:= *O (+ (INT "mem[0]") 1))
int O = mem[0] + 1;
// (:= *P (+ (INT "mem[0]") 2))
int P = mem[0] + 2;
// (setArrayElement mem 0 (INT "P"))
mem[0] = P;
// (setArrayElement mem (INT "O") PVAR)
mem[O] = PVAR;
// (:= *Q (+ 3 base))
int Q = 3 + base;
// (setArrayElement stack (INT "Q") (INT "O"))
stack[Q] = O;
// (updateArrayLength (INT "Q") stack)

if(stack[0] < Q)
stack[0] = Q;

// (:= *R (+ 1 base))
int R = 1 + base;
// (getArrayElement stack (INT "R") *S) = stack[R]
// (deref (REF (INT "stack[R]")) mem (REF *T))
word T = stack[R];
while(mem[T] == REF)
T = mem[T + 1];

// (:= *U (+ (REF "T") 1))
int U = T + 1;
// (getArrayElement mem (REF "T") INT)
if(mem[T] != INT)
goto nthprime22_fail;

// (getArrayElement mem (INT "U") *V) = mem[U]
// (:= *W (x (INT "mem[U]") 2))
int W = mem[U] * 2;
// (:= *X (+ (INT "W") 2))
int X = W + 2;
// (getArrayElement mem 0 *Y) = mem[0]
// (:= *A1 (+ (INT "mem[0]") 1))
int A1 = mem[0] + 1;
// (:= *B1 (+ (INT "mem[0]") (INT "X")))
int B1 = mem[0] + X;
// (setArrayElement mem 0 (INT "B1"))
mem[0] = B1;
// (setArrayElement mem (INT "A1") ARRAY)
mem[A1] = ARRAY;
// (:= *C1 (+ (INT "A1") 1))
int C1 = A1 + 1;
// (setArrayElement mem (INT "C1") (INT "mem[U]"))
mem[C1] = mem[U];
// (deref (REF (INT "O")) mem (REF *D1))
word D1 = O;
while(mem[D1] == REF)
D1 = mem[D1 + 1];

// (getArrayElement mem (REF "D1") PVAR)
if(mem[D1] != PVAR)
goto nthprime22_fail;

// (:= *E1 (+ (REF "D1") 1))
int E1 = D1 + 1;
// (setArrayElement mem (REF "D1") REF)
mem[D1] = REF;
// (setArrayElement mem (INT "E1") (INT "A1"))
mem[E1] = A1;
// (print stack)
printStack(stack);
// (print mem)
printArray(mem);
// (:= *F1 (+ 3 base))
int F1 = 3 + base;
// (getArrayElement stack (INT "F1") *G1) = stack[F1]
// (deref (REF (INT "stack[F1]")) mem (REF *H1))
word H1 = stack[F1];
while(mem[H1] == REF)
H1 = mem[H1 + 1];

// (:= *I1 (+ (REF "H1") 2))
int I1 = H1 + 2;
// (setArrayElement mem (INT "I1") INT)
mem[I1] = INT;
// (:= *J1 (+ (INT "I1") 1))
int J1 = I1 + 1;
// (setArrayElement mem (INT "J1") 2)
mem[J1] = 2;
// (getArrayElement mem 0 *K1) = mem[0]
// (:= *L1 (+ (INT "mem[0]") 1))
int L1 = mem[0] + 1;
// (:= *M1 (+ (INT "mem[0]") 2))
int M1 = mem[0] + 2;
// (setArrayElement mem 0 (INT "M1"))
mem[0] = M1;
// (setArrayElement mem (INT "L1") INT)
mem[L1] = INT;
// (:= *N1 (+ (INT "L1") 1))
int N1 = L1 + 1;
// (setArrayElement mem (INT "N1") 3)
mem[N1] = 3;
// (getArrayElement stack 0 *O1) = stack[0]
// (:= *P1 (+ (INT "stack[0]") 1))
int P1 = stack[0] + 1;
// (:= *Q1 (+ (INT "P1") 1))
int Q1 = P1 + 1;
// (setArrayElement stack (INT "Q1") (INT "L1"))
stack[Q1] = L1;
// (:= *R1 (+ 3 base))
int R1 = 3 + base;
// (getArrayElement stack (INT "R1") *S1) = stack[R1]
// (getArrayElement stack 0 *T1) = stack[0]
// (:= *U1 (+ (INT "stack[0]") 1))
int U1 = stack[0] + 1;
// (:= *V1 (+ (INT "U1") 2))
int V1 = U1 + 2;
// (setArrayElement stack (INT "V1") (INT "stack[R1]"))
stack[V1] = stack[R1];
// (getArrayElement mem 0 *W1) = mem[0]
// (:= *X1 (+ (INT "mem[0]") 1))
int X1 = mem[0] + 1;
// (:= *Y1 (+ (INT "mem[0]") 2))
int Y1 = mem[0] + 2;
// (setArrayElement mem 0 (INT "Y1"))
mem[0] = Y1;
// (setArrayElement mem (INT "X1") INT)
mem[X1] = INT;
// (:= *A2 (+ (INT "X1") 1))
int A2 = X1 + 1;
// (setArrayElement mem (INT "A2") 0)
mem[A2] = 0;
// (getArrayElement stack 0 *B2) = stack[0]
// (:= *C2 (+ (INT "stack[0]") 1))
int C2 = stack[0] + 1;
// (:= *D2 (+ (INT "C2") 3))
int D2 = C2 + 3;
// (setArrayElement stack (INT "D2") (INT "X1"))
stack[D2] = X1;
// (getArrayElement mem 0 *E2) = mem[0]
// (:= *F2 (+ (INT "mem[0]") 1))
int F2 = mem[0] + 1;
// (:= *G2 (+ (INT "mem[0]") 2))
int G2 = mem[0] + 2;
// (setArrayElement mem 0 (INT "G2"))
mem[0] = G2;
// (setArrayElement mem (INT "F2") INT)
mem[F2] = INT;
// (:= *H2 (+ (INT "F2") 1))
int H2 = F2 + 1;
// (setArrayElement mem (INT "H2") 1)
mem[H2] = 1;
// (getArrayElement stack 0 *I2) = stack[0]
// (:= *J2 (+ (INT "stack[0]") 1))
int J2 = stack[0] + 1;
// (:= *K2 (+ (INT "J2") 4))
int K2 = J2 + 4;
// (setArrayElement stack (INT "K2") (INT "F2"))
stack[K2] = F2;
// (:= *L2 (+ 1 base))
int L2 = 1 + base;
// (getArrayElement stack (INT "L2") *M2) = stack[L2]
// (getArrayElement stack 0 *N2) = stack[0]
// (:= *O2 (+ (INT "stack[0]") 1))
int O2 = stack[0] + 1;
// (:= *P2 (+ (INT "O2") 5))
int P2 = O2 + 5;
// (setArrayElement stack (INT "P2") (INT "stack[L2]"))
stack[P2] = stack[L2];
// (getArrayElement stack 0 *Q2) = stack[0]
// (getArrayElement stack 1 *R2)
base = stack[1];
// (:= *S2 (+ (INT "stack[0]") 1))
int S2 = stack[0] + 1;
// (setArrayElement stack (INT "S2") base)
stack[S2] = base;
// (:= *T2 (+ (INT "S2") 5))
int T2 = S2 + 5;
// (setArrayElement stack 0 (INT "T2"))
stack[0] = T2;
// (setArrayElement stack 1 (INT "S2"))
stack[1] = S2;
// (call (primeArray5 stack mem))
primeArray5(stack, mem);
// (:= *V2 (+ 1 base))
int V2 = 1 + base;
// (getArrayElement stack (INT "V2") *W2) = stack[V2]
// (deref (REF (INT "stack[V2]")) mem (REF *X2))
word X2 = stack[V2];
while(mem[X2] == REF)
X2 = mem[X2 + 1];

// (:= *Y2 (+ (REF "X2") 1))
int Y2 = X2 + 1;
// (getArrayElement mem (REF "X2") INT)
if(mem[X2] != INT)
goto nthprime22_fail;

// (getArrayElement mem (INT "Y2") *A3) = mem[Y2]
// (:= *B3 (- (INT "mem[Y2]") 1))
int B3 = mem[Y2] - 1;
// (:= *C3 (+ 3 base))
int C3 = 3 + base;
// (getArrayElement stack (INT "C3") *D3) = stack[C3]
// (deref (REF (INT "stack[C3]")) mem (REF *E3))
word E3 = stack[C3];
while(mem[E3] == REF)
E3 = mem[E3 + 1];

// (getArrayElement mem (REF "E3") ARRAY)
if(mem[E3] != ARRAY)
goto nthprime22_fail;

// (:= *F3 (x (INT "B3") 2))
int F3 = B3 * 2;
// (:= *G3 (+ (INT "F3") 2))
int G3 = F3 + 2;
// (:= *H3 (+ (REF "E3") (INT "G3")))
int H3 = E3 + G3;
// (getArrayElement mem (INT "H3") *I3) = mem[H3]
// (:= *J3 (+ (INT "H3") 1))
int J3 = H3 + 1;
// (getArrayElement mem (INT "J3") *K3) = mem[J3]
// (:= *L3 (+ 2 base))
int L3 = 2 + base;
// (getArrayElement stack (INT "L3") *M3) = stack[L3]
// (deref (REF (INT "stack[L3]")) mem (REF *N3))
word N3 = stack[L3];
while(mem[N3] == REF)
N3 = mem[N3 + 1];

// (getArrayElement mem (REF "N3") PVAR)
if(mem[N3] != PVAR)
goto nthprime22_fail;

// (:= *O3 (+ (REF "N3") 1))
int O3 = N3 + 1;
// (setArrayElement mem (REF "N3") (INT "mem[H3]"))
mem[N3] = mem[H3];
// (setArrayElement mem (INT "O3") (INT "mem[J3]"))
mem[O3] = mem[J3];
// (getArrayElement stack base *P3) = stack[base]
// (setArrayElement stack 1 (INT "stack[base]"))
stack[1] = stack[base];
// (:= *Q3 (- base 1))
int Q3 = base - 1;
// (setArrayElement stack 0 (INT "Q3"))
stack[0] = Q3;
return (bool)stack[base];
}

nthprime22_fail :

return false;

}


// primeArray.c

#include "et.h"

bool primeArray5(word stack[], word mem[]) {
word base;

primeArray5 :

{
// (getArrayElement stack 1 *A)
base = stack[1];
// (getArrayElement mem 0 *B) = mem[0]
// (:= *C (+ (INT "mem[0]") 1))
int C = mem[0] + 1;
// (:= *D (+ (INT "mem[0]") 2))
int D = mem[0] + 2;
// (setArrayElement mem 0 (INT "D"))
mem[0] = D;
// (setArrayElement mem (INT "C") PVAR)
mem[C] = PVAR;
// (:= *E (+ 6 base))
int E = 6 + base;
// (setArrayElement stack (INT "E") (INT "C"))
stack[E] = C;
// (updateArrayLength (INT "E") stack)

if(stack[0] < E)
stack[0] = E;

// (primeArray51 stack mem)

goto primeArray51;
}

primeArray5_fail :

primeArray51 :
{

// (getArrayElement stack 1 *F)
base = stack[1];
// (not (== 4 5 base stack mem))
if(ideref(4, base, stack, mem) == ideref(5, base, stack, mem))
goto primeArray511;

// (primeArray52 stack mem)

goto primeArray52;
}

primeArray51_fail :

primeArray511 :
{

// (getArrayElement stack 1 *G)
base = stack[1];
// (getArrayElement stack base *H) = stack[base]
// (setArrayElement stack 1 (INT "stack[base]"))
stack[1] = stack[base];
// (:= *I (- base 1))
int I = base - 1;
// (setArrayElement stack 0 (INT "I"))
stack[0] = I;
return (bool)stack[base];
}

primeArray511_fail :

primeArray52 :
{

// (getArrayElement stack 1 *J)
base = stack[1];
// (getArrayElement mem 0 *K) = mem[0]
// (:= *L (+ (INT "mem[0]") 1))
int L = mem[0] + 1;
// (:= *M (+ (INT "mem[0]") 2))
int M = mem[0] + 2;
// (setArrayElement mem 0 (INT "M"))
mem[0] = M;
// (setArrayElement mem (INT "L") PVAR)
mem[L] = PVAR;
// (:= *N (+ 6 base))
int N = 6 + base;
// (setArrayElement stack (INT "N") (INT "L"))
stack[N] = L;
// (updateArrayLength (INT "N") stack)

if(stack[0] < N)
stack[0] = N;

// (:= *O (+ 2 base))
int O = 2 + base;
// (getArrayElement stack (INT "O") *P) = stack[O]
// (deref (REF (INT "stack[O]")) mem (REF *Q))
word Q = stack[O];
while(mem[Q] == REF)
Q = mem[Q + 1];

// (getArrayElement mem (REF "Q") ARRAY)
if(mem[Q] != ARRAY)
goto primeArray52_fail;

// (:= *R (+ 3 base))
int R = 3 + base;
// (getArrayElement stack (INT "R") *S) = stack[R]
// (deref (REF (INT "stack[R]")) mem (REF *T))
word T = stack[R];
while(mem[T] == REF)
T = mem[T + 1];

// (:= *U (+ (REF "T") 1))
int U = T + 1;
// (getArrayElement mem (REF "T") INT)
if(mem[T] != INT)
goto primeArray52_fail;

// (getArrayElement mem (INT "U") *V) = mem[U]
// (:= *W (x (INT "mem[U]") 2))
int W = mem[U] * 2;
// (:= *X (+ (INT "W") 2))
int X = W + 2;
// (:= *Y (+ (REF "Q") (INT "X")))
int Y = Q + X;
// (getArrayElement mem (INT "Y") *A1) = mem[Y]
// (:= *B1 (+ (INT "Y") 1))
int B1 = Y + 1;
// (getArrayElement mem (INT "B1") *C1) = mem[B1]
// (deref (REF (INT "L")) mem (REF *D1))
word D1 = L;
while(mem[D1] == REF)
D1 = mem[D1 + 1];

// (getArrayElement mem (REF "D1") PVAR)
if(mem[D1] != PVAR)
goto primeArray52_fail;

// (:= *E1 (+ (REF "D1") 1))
int E1 = D1 + 1;
// (setArrayElement mem (REF "D1") (INT "mem[Y]"))
mem[D1] = mem[Y];
// (setArrayElement mem (INT "E1") (INT "mem[B1]"))
mem[E1] = mem[B1];
// (:= *F1 (+ 6 base))
int F1 = 6 + base;
// (getArrayElement stack (INT "F1") *G1) = stack[F1]
// (deref (REF (INT "stack[F1]")) mem (REF *H1))
word H1 = stack[F1];
while(mem[H1] == REF)
H1 = mem[H1 + 1];

// (:= *I1 (+ (REF "H1") 1))
int I1 = H1 + 1;
// (getArrayElement mem (REF "H1") INT)
if(mem[H1] != INT)
goto primeArray52_fail;

// (getArrayElement mem (INT "I1") *J1) = mem[I1]
// (:= *K1 (+ 6 base))
int K1 = 6 + base;
// (getArrayElement stack (INT "K1") *L1) = stack[K1]
// (deref (REF (INT "stack[K1]")) mem (REF *M1))
word M1 = stack[K1];
while(mem[M1] == REF)
M1 = mem[M1 + 1];

// (:= *N1 (+ (REF "M1") 1))
int N1 = M1 + 1;
// (getArrayElement mem (REF "M1") INT)
if(mem[M1] != INT)
goto primeArray52_fail;

// (getArrayElement mem (INT "N1") *O1) = mem[N1]
// (:= *P1 (x (INT "mem[I1]") (INT "mem[N1]")))
int P1 = mem[I1] * mem[N1];
// (not (< (1 (INT (INT "P1")) base stack mem)))
if(ideref(1, base, stack, mem) < P1)
goto primeArray521;

// (primeArray53 stack mem)

goto primeArray53;
}

primeArray52_fail :

primeArray521 :
{

// (getArrayElement stack 1 *Q1)
base = stack[1];
// (:= *R1 (+ 2 base))
int R1 = 2 + base;
// (getArrayElement stack (INT "R1") *S1) = stack[R1]
// (deref (REF (INT "stack[R1]")) mem (REF *T1))
word T1 = stack[R1];
while(mem[T1] == REF)
T1 = mem[T1 + 1];

// (:= *U1 (+ 4 base))
int U1 = 4 + base;
// (getArrayElement stack (INT "U1") *V1) = stack[U1]
// (deref (REF (INT "stack[U1]")) mem (REF *W1))
word W1 = stack[U1];
while(mem[W1] == REF)
W1 = mem[W1 + 1];

// (:= *X1 (+ (REF "W1") 1))
int X1 = W1 + 1;
// (getArrayElement mem (REF "W1") INT)
if(mem[W1] != INT)
goto primeArray521_fail;

// (getArrayElement mem (INT "X1") *Y1) = mem[X1]
// (:= *A2 (+ 1 base))
int A2 = 1 + base;
// (getArrayElement stack (INT "A2") *B2) = stack[A2]
// (deref (REF (INT "stack[A2]")) mem (REF *C2))
word C2 = stack[A2];
while(mem[C2] == REF)
C2 = mem[C2 + 1];

// (:= *D2 (+ (REF "C2") 1))
int D2 = C2 + 1;
// (getArrayElement mem (REF "C2") *E2) = mem[C2]
// (getArrayElement mem (INT "D2") *F2) = mem[D2]
// (:= *G2 (x (INT "mem[X1]") 2))
int G2 = mem[X1] * 2;
// (:= *H2 (+ (INT "G2") 2))
int H2 = G2 + 2;
// (:= *I2 (+ (REF "T1") (INT "H2")))
int I2 = T1 + H2;
// (setArrayElement mem (INT "I2") (INT "mem[C2]"))
mem[I2] = mem[C2];
// (:= *J2 (+ (INT "I2") 1))
int J2 = I2 + 1;
// (setArrayElement mem (INT "J2") (INT "mem[D2]"))
mem[J2] = mem[D2];
// (:= *K2 (+ 4 base))
int K2 = 4 + base;
// (getArrayElement stack (INT "K2") *L2) = stack[K2]
// (deref (REF (INT "stack[K2]")) mem (REF *M2))
word M2 = stack[K2];
while(mem[M2] == REF)
M2 = mem[M2 + 1];

// (:= *N2 (+ (REF "M2") 1))
int N2 = M2 + 1;
// (getArrayElement mem (REF "M2") INT)
if(mem[M2] != INT)
goto primeArray521_fail;

// (getArrayElement mem (INT "N2") *O2) = mem[N2]
// (:= *P2 (+ (INT "mem[N2]") 1))
int P2 = mem[N2] + 1;
// (:= *Q2 (+ 4 base))
int Q2 = 4 + base;
// (getArrayElement stack (INT "Q2") *R2) = stack[Q2]
// (:= *S2 (+ (INT "stack[Q2]") 1))
int S2 = stack[Q2] + 1;
// (setArrayElement mem (INT "stack[Q2]") INT)
mem[stack[Q2]] = INT;
// (setArrayElement mem (INT "S2") (INT "P2"))
mem[S2] = P2;
// (:= *T2 (+ 3 base))
int T2 = 3 + base;
// (getArrayElement stack (INT "T2") *U2) = stack[T2]
// (:= *V2 (+ (INT "stack[T2]") 1))
int V2 = stack[T2] + 1;
// (setArrayElement mem (INT "stack[T2]") INT)
mem[stack[T2]] = INT;
// (setArrayElement mem (INT "V2") 1)
mem[V2] = 1;
// (:= *W2 (+ 1 base))
int W2 = 1 + base;
// (getArrayElement stack (INT "W2") *X2) = stack[W2]
// (deref (REF (INT "stack[W2]")) mem (REF *Y2))
word Y2 = stack[W2];
while(mem[Y2] == REF)
Y2 = mem[Y2 + 1];

// (:= *A3 (+ (REF "Y2") 1))
int A3 = Y2 + 1;
// (getArrayElement mem (REF "Y2") INT)
if(mem[Y2] != INT)
goto primeArray521_fail;

// (getArrayElement mem (INT "A3") *B3) = mem[A3]
// (:= *C3 (+ (INT "mem[A3]") 2))
int C3 = mem[A3] + 2;
// (:= *D3 (+ 1 base))
int D3 = 1 + base;
// (getArrayElement stack (INT "D3") *E3) = stack[D3]
// (:= *F3 (+ (INT "stack[D3]") 1))
int F3 = stack[D3] + 1;
// (setArrayElement mem (INT "stack[D3]") INT)
mem[stack[D3]] = INT;
// (setArrayElement mem (INT "F3") (INT "C3"))
mem[F3] = C3;
// (primeArray51 stack mem)

goto primeArray51;
}

primeArray521_fail :

primeArray53 :
{

// (getArrayElement stack 1 *G3)
base = stack[1];
// (getArrayElement mem 0 *H3) = mem[0]
// (:= *I3 (+ (INT "mem[0]") 1))
int I3 = mem[0] + 1;
// (:= *J3 (+ (INT "mem[0]") 2))
int J3 = mem[0] + 2;
// (setArrayElement mem 0 (INT "J3"))
mem[0] = J3;
// (setArrayElement mem (INT "I3") PVAR)
mem[I3] = PVAR;
// (:= *K3 (+ 6 base))
int K3 = 6 + base;
// (setArrayElement stack (INT "K3") (INT "I3"))
stack[K3] = I3;
// (updateArrayLength (INT "K3") stack)

if(stack[0] < K3)
stack[0] = K3;

// (:= *L3 (+ 2 base))
int L3 = 2 + base;
// (getArrayElement stack (INT "L3") *M3) = stack[L3]
// (deref (REF (INT "stack[L3]")) mem (REF *N3))
word N3 = stack[L3];
while(mem[N3] == REF)
N3 = mem[N3 + 1];

// (getArrayElement mem (REF "N3") ARRAY)
if(mem[N3] != ARRAY)
goto primeArray53_fail;

// (:= *O3 (+ 3 base))
int O3 = 3 + base;
// (getArrayElement stack (INT "O3") *P3) = stack[O3]
// (deref (REF (INT "stack[O3]")) mem (REF *Q3))
word Q3 = stack[O3];
while(mem[Q3] == REF)
Q3 = mem[Q3 + 1];

// (:= *R3 (+ (REF "Q3") 1))
int R3 = Q3 + 1;
// (getArrayElement mem (REF "Q3") INT)
if(mem[Q3] != INT)
goto primeArray53_fail;

// (getArrayElement mem (INT "R3") *S3) = mem[R3]
// (:= *T3 (x (INT "mem[R3]") 2))
int T3 = mem[R3] * 2;
// (:= *U3 (+ (INT "T3") 2))
int U3 = T3 + 2;
// (:= *V3 (+ (REF "N3") (INT "U3")))
int V3 = N3 + U3;
// (getArrayElement mem (INT "V3") *W3) = mem[V3]
// (:= *X3 (+ (INT "V3") 1))
int X3 = V3 + 1;
// (getArrayElement mem (INT "X3") *Y3) = mem[X3]
// (deref (REF (INT "I3")) mem (REF *A4))
word A4 = I3;
while(mem[A4] == REF)
A4 = mem[A4 + 1];

// (getArrayElement mem (REF "A4") PVAR)
if(mem[A4] != PVAR)
goto primeArray53_fail;

// (:= *B4 (+ (REF "A4") 1))
int B4 = A4 + 1;
// (setArrayElement mem (REF "A4") (INT "mem[V3]"))
mem[A4] = mem[V3];
// (setArrayElement mem (INT "B4") (INT "mem[X3]"))
mem[B4] = mem[X3];
// (:= *C4 (+ 1 base))
int C4 = 1 + base;
// (getArrayElement stack (INT "C4") *D4) = stack[C4]
// (deref (REF (INT "stack[C4]")) mem (REF *E4))
word E4 = stack[C4];
while(mem[E4] == REF)
E4 = mem[E4 + 1];

// (:= *F4 (+ (REF "E4") 1))
int F4 = E4 + 1;
// (getArrayElement mem (REF "E4") INT)
if(mem[E4] != INT)
goto primeArray53_fail;

// (getArrayElement mem (INT "F4") *G4) = mem[F4]
// (:= *H4 (+ 6 base))
int H4 = 6 + base;
// (getArrayElement stack (INT "H4") *I4) = stack[H4]
// (deref (REF (INT "stack[H4]")) mem (REF *J4))
word J4 = stack[H4];
while(mem[J4] == REF)
J4 = mem[J4 + 1];

// (:= *K4 (+ (REF "J4") 1))
int K4 = J4 + 1;
// (getArrayElement mem (REF "J4") INT)
if(mem[J4] != INT)
goto primeArray53_fail;

// (getArrayElement mem (INT "K4") *L4) = mem[K4]
// (:= *M4 (mod (INT "mem[F4]") (INT "mem[K4]")))
int M4 = mem[F4] % mem[K4];
// (not (== (INT 0) (INT (INT "M4")) base stack mem))
if(0 == M4)
goto primeArray531;

// (primeArray54 stack mem)

goto primeArray54;
}

primeArray53_fail :

primeArray531 :
{

// (getArrayElement stack 1 *N4)
base = stack[1];
// (:= *O4 (+ 3 base))
int O4 = 3 + base;
// (getArrayElement stack (INT "O4") *P4) = stack[O4]
// (:= *Q4 (+ (INT "stack[O4]") 1))
int Q4 = stack[O4] + 1;
// (setArrayElement mem (INT "stack[O4]") INT)
mem[stack[O4]] = INT;
// (setArrayElement mem (INT "Q4") 1)
mem[Q4] = 1;
// (:= *R4 (+ 1 base))
int R4 = 1 + base;
// (getArrayElement stack (INT "R4") *S4) = stack[R4]
// (deref (REF (INT "stack[R4]")) mem (REF *T4))
word T4 = stack[R4];
while(mem[T4] == REF)
T4 = mem[T4 + 1];

// (:= *U4 (+ (REF "T4") 1))
int U4 = T4 + 1;
// (getArrayElement mem (REF "T4") INT)
if(mem[T4] != INT)
goto primeArray531_fail;

// (getArrayElement mem (INT "U4") *V4) = mem[U4]
// (:= *W4 (+ (INT "mem[U4]") 2))
int W4 = mem[U4] + 2;
// (:= *X4 (+ 1 base))
int X4 = 1 + base;
// (getArrayElement stack (INT "X4") *Y4) = stack[X4]
// (:= *A5 (+ (INT "stack[X4]") 1))
int A5 = stack[X4] + 1;
// (setArrayElement mem (INT "stack[X4]") INT)
mem[stack[X4]] = INT;
// (setArrayElement mem (INT "A5") (INT "W4"))
mem[A5] = W4;
// (primeArray51 stack mem)

goto primeArray51;
}

primeArray531_fail :

primeArray54 :
{

// (getArrayElement stack 1 *B5)
base = stack[1];
// (:= *C5 (+ 3 base))
int C5 = 3 + base;
// (getArrayElement stack (INT "C5") *D5) = stack[C5]
// (deref (REF (INT "stack[C5]")) mem (REF *E5))
word E5 = stack[C5];
while(mem[E5] == REF)
E5 = mem[E5 + 1];

// (:= *F5 (+ (REF "E5") 1))
int F5 = E5 + 1;
// (getArrayElement mem (REF "E5") INT)
if(mem[E5] != INT)
goto primeArray54_fail;

// (getArrayElement mem (INT "F5") *G5) = mem[F5]
// (:= *H5 (+ (INT "mem[F5]") 1))
int H5 = mem[F5] + 1;
// (:= *I5 (+ 3 base))
int I5 = 3 + base;
// (getArrayElement stack (INT "I5") *J5) = stack[I5]
// (:= *K5 (+ (INT "stack[I5]") 1))
int K5 = stack[I5] + 1;
// (setArrayElement mem (INT "stack[I5]") INT)
mem[stack[I5]] = INT;
// (setArrayElement mem (INT "K5") (INT "H5"))
mem[K5] = H5;
// (primeArray51 stack mem)

goto primeArray51;
}

primeArray54_fail :

return false;

}


こういう風に,一つのルールのまとまり (部分評価の際,同じ名前で同じアリティのルールは自動的にまとめらる) を一個の C 関数に落としていくっていうやり方は,まぁわかりやすいし直感的なんだけど,あまり可能性が広がらない,つまらないアプローチ.

これでは,C 言語のライブラリを使ってプログラミングをしていくのと,あまり変わらない.いや,それでも良いんだけど.

それだと,せっかく等価変換ルールという,理論的に扱いやすい形式で書かれていることのメリットを十分に活かせない.従来の,古いスタイルの,ライブラリを糊付けしていくプログラミングと何も変わらない.

全部が ET ルールという柔軟な形で書かれていれば,もっともっと大きな可能性が開けるのである.

例えば,巨大な ET ルールのライブラリというか,データベースを想像してみよう.そして,そこから必要なルールを取ってきて (この取ってくる方法もいろいろ考えられている.従来のような,文字列で検索したり,名前で機能を想像したり,機能ごとにまとめたり (ポケット一つの原則に反する) というアプローチは,どうしようもなく原始的で古い) ,それを組み合わせることによって,目的の機能が実現できたとする.

# ほんとに将来的には,仕様から,それの制約を充足するプログラムが自動的に組み立てられる (プログラム合成) のが理想的.今のところ,これは計算機科学の聖杯伝説ですが.

従来のライブラリなどは,汎用性を重視するため,どうしてもさまざまなオーバーヘッドが付きまとう.そのため,何度も何度も,プログラムの問題領域にあわせて,細かくチューニングしたハッシュだのなんだのが再発明されることとなった.

特に,オブジェクト指向のライブラリなんかは,モジュール化が進んでいて使いやすい反面,どうしてもオーバヘッドが大きくなる.汎用性やモジュール性と,最適化や特化はトレードオフの関係になる.たとえば,GNU の,特に GCC なんかは,関数呼び出しのオーバヘッドの削減など,効率を重視するあまり,数千行クラスの関数があったり,専用の抽象データ型が何個も何個も車輪していたり.

全部が ET ルールで書かれていれば,モジュールを部分評価して,無駄な部分を全て取り除いて,余計な中間部分を融合して,全ての末尾関数呼び出しや相互再帰を goto に,再帰呼び出しを,パターンに応じて最適化したり,といった,モジュール性や再利用と処理効率を両立できる可能性が生まれる.

極端な話,一個一個 C の関数に落としていくってのは,

(lenght () *N) --> (= *N 0).
(length (? | *Xs) *N) --> (length *Xs *N1), (:= *N (+ *N1 1)).

みたいな D ルールを,
bool
lenght(List* X) {

if(nil(X))
return 0;

return 1 + length(cdr(X));
}
みたいにしちゃうのと同じってことで.
D ルールを,こうやって,一個一個,B ルールの関数に落としていって,それをまた B ルールとして組み合わせていき,ってのは,従来的で馴染み深いけど,柔軟性が決定的に失われてしまう.

たとえば,C では,関数をまたぐ大域的な最適化は,とても難しい.

これが,必要な関数を,必要なだけライブラリからもってきて,全て融合して一つの巨大な関数に自動的に変換することができたら,そこからさらにいろいろな最適化が容易になるかもしれない.

C が速い速いとよく言われるけど,それは全然甘い,と個人的には思っている.確かにむき出しの C は速いかもしれないけど,現実的には,何らかのライブラリなりフレームワークを使わない C 言語は,使い物にならない.そして,そういうものを使うと,柔軟性や汎用性と引き換えに,オーバーヘッドが何十にも重なって遅くなる.

よく,ML や Common Lisp の方が,同じ大きな規模ならば,C よりも速い,というのは,こういうカラクリだ.グリーンスパンのナントカ法則.素人が組んだゴテゴテした C プログラムよりも,確立された ML なり Commn Lisp という枠組みの中で最適化された処理系なりフレームワークを使って組まれたプログラムの方が,無駄が無く,その分柔軟だし速い.

というか,「速い」ってのは,開発速度の方が重要です.どんなプログラムでも,最初は手抜きで,とりあえず動けば良い的な部分をいっぱい含んでいるはず.一般的に,コンパイルってのはオーダが変わらない最適化なので,アルゴリズムの方が爆発的な速度差につながります.そこのボトルネックがでかすぎると,言語間の速度差など微差になってしまう.アセンブリでゴリゴリ書けば速くなる,なんてのは,都市伝説です.一般的には,「開発が進む」速度が速いプログラムほど,言語に関係なく実行速度も速くなる (十分に複雑なプログラムならば).

# C は「実行」速度以外何もかも捨てた言語,Scheme は柔軟性以外何もかも捨てた言語というイメージが.ひげぽんさんが,Scheme で OS を書いたらどうだろうみたいな話をしていて,実は密かに期待しているのですが,OS みたいなシステムズプログラミングには,Lisp の皮を被った C 言語である,Common Lisp の方が良いのかも,という気が.まぁ,俺様 OS を作るぐらいなんだから,移植性なども一切無視した,独自仕様の俺様言語処理系もついでに作って,そこでは C スタックなどを一切放棄して,Scheme の継続がネイティブに使える (本質的に計算機と相性が悪い,特にレジスタとかコンテキストがいっぱいある RISC だと… というイメージもありますが,工夫次第でなんとかなるのかもしれない.ていうか,いまどきの計算機は速いし) とかだったら話は別ですし,やたら面白いのですが.

うーん,無駄に長くなった.

まぁ,要するに,古いアプローチには限界があるよ,ソフトウェアが巨大化するにしたがって,開発速度も実行速度も遅くなっていくよ,このままだとソフトウェア産業に未来無いよ,ということが言いたかったわけで.

ちょっと嬉しさで饒舌になりすぎた.聞き流してください.

さーてと,もっといろいろな例題を試しつつ,コンパイルのインフラをちゃんとしていかないとなぁ.いままでちょっと,やっつけでテキトーに書きすぎた.書いては捨て,書いては捨てではなく,ちゃんと形にしないと… ていうか,そろそろ一区切り付いてきたので,レポートを書き始めないと.

いろいろヤバイ.

今日の朝,手話の方から誘いがあって,昼まっからビアガーデンに行ってきた (さすがに途中で帰ってきた) ので,頭がちょっといたい.1 杯ぐらいしか飲んでないのに… 日に当てられたのかなぁ… 天気が良すぎでした.

いやぁ,それにしても,動いて良かったよ.
ET 言語処理系関係TB:0CM:0 このエントリーを含むはてなブックマーク | livedoorクリップ livedoorクリップ BuzzurlにブックマークBuzzurlにブックマーク newsing it!

疲れたよ…

2006/08/09(水) 00:34:02

来る日も来る日も,コンパイラが生成した,ほとんどアセンブリみたいな C 言語とにらめっこしつつ,バグを取る日々.そりゃぁ,精神も荒廃してきますよ.日記が壊れ気味でも気にしてはいけにゃい.

今日は,length とかをコンパイルしてみた.これは,末尾再帰ではなく,再帰を使わざるを得ない例題,という難しさがあるの〜.

// (length *リスト *リストの長さ)

(length () *N) --> (= *N 0).
(length (? | *Xs) *N) --> (length *Xs *N1), (:= *N (+ *N1 1)).

そうすると,問題は,今までのように goto だけでは上手くいかないのである.スタックかどっかに戻り番地を確保しておいて,処理が終わったら,終わったところから元の場所 (これが,いわゆる,アセンブリ言語のレベルでの,継続 continuation という値の正体.高級言語になればなるほど,もっといろいろな実行時の環境 (コンテキスト)情報が増える) まで飛んで処理を再開しないといけない.

スタック (ワード配列) に順番に引数積む;
ベース値を適切に書き換える;

(ベース + n が,n 番目のローカル変数のインデクスになる.テキトーに,スタック配列の 1 番目とかに確保してる.0 番目には現在のスタックの長さが入っている.スタックフレームの構造はいろいろ変わるかも.今はかなりテキトー)

goto length; // サブルーチンの最初に戻る.

次にここに戻ってきて,ここから処理を再開しないといけない.

しっかし,戻ってくるところのアドレスなんて,C みたいな高級言語からは,ポータブルには取れっこないよなぁ…

# ETI レベルでは,どこまでプリミティブにプログラム変換しようとも限界があり,ここまで低水準なところにはもともと触れないので,問題が表面化しない.

というわけで,今のところは,本当に関数を再帰呼び出しているのですが…

この方法だと,複数のお互いに呼び合う D ルールを,一つの巨大な C 関数に無理矢理融合変換,関数呼び出しなんて無し,内部で直接 goto でぐるぐる回りまくる,とかいうコンパイルができなくなるとか,いろいろと問題が.

GCC なんかだと,

bool
func(word stack[], word mem[]) {

...

dokka :

なんか処理;

goto (void *)stack[retValueIndex];

← 今ここをプログラムカウンタが指しているとする;

引数積む;
ワード配列に,無理やり void * を詰め込む;
stack[retValueIndex] = (word)&&continuationLABEL;
スタックポインタずらす.

goto dokka;

continuationLABEL :

継続処理;

...

}

みたいな,いろいろと無理があることを強引にすれば,なんとかなるかも.

5.3 Labels as Values

(このときの C スタックやら実行時コンテキストを setjmp かなんかで,どっかに丸ごと保存しておいて,&&LABEL といっしょにクローズしておけば,継続オブジェクトとかができる… のかもしれない.よく知らない.setjmp/longjmp とかもあんまり使ったことないし…)

もはや C 言語でも何でも無い !

関数を超えたジャンプも余裕.ダイクストラ先生もびっくりだ.

というか,無理やり,関数呼び出しという C 言語の構造化言語としての枠組みを使わないで,ネイティブコンパイラを書いたほうが楽なことっていっぱいあるんだよなぁ… でもポータビリティが無くなり過ぎるし,いまどきの CPU のレジスタ割り当てとかパイプライニングとかは,もう素人じゃどうしようもないレベルだし.やっぱり,C の歴史とポータビリティとベンダー提供の超絶コンパイラは捨てがたい.C-- とか良く知らないだけですけど…

それにしても,値としてラベルを使うことができる GCC は偉いよ.C って,やっぱり,いまいち中途半端に高級なんだよなぁ.リターンアドレスぐらい触らせてくれ〜 スタックフレーム弄らせてくれ〜 これぐらい標準化してくれ !! ていぅか関数呼び出しによる構造化なんていらねーよー 本当に,単なるポータブルなアセンブリ言語だったら良かったのに (無茶苦茶)

(いろいろ毒されてきて,もはや関数型どころか,構造化プログラミングすらどうでもよくなってきている管理人)
ET 言語処理系関係TB:0CM:10 このエントリーを含むはてなブックマーク | livedoorクリップ livedoorクリップ BuzzurlにブックマークBuzzurlにブックマーク newsing it!

最近ダレ気味

2006/08/03(木) 23:36:46

どんどん生活が夜型に… 私は,夜になると意味も無く死にたくなるというわけがわからない精神構造の人間なので,これは非常に由々しき事態.

do {

夜がふける ; 研究に疲れてくる ; 人生に疲れてくる ; いろいろつらくなる ; 酒浸り ; 意味も無く廃テンション ; 無意味に遅くまで起きてる ; 朝起きれない ; 起きれなくて,朝から自己嫌悪 ; やる気がなくなる ; 東京とかに比べればぜんぜんとはいえ,暑い ; ますますやる気がなくなる ; 無意味に遅くまで研究室にいる ; 夜が更ける ; 研究が進まない ; 将来に対する漠然とした不安 ; 一向に消化されないレポートの山 ; ゲンナリ ; 現実逃避 ; ますますやる気が無くなる ; 気力,体力が消耗 ; 無意味に深夜

} while(true);

まぁ,酒は良くないよね.

すべての原因は研究が進まないことにあるのだ.

あーあー,研究なんて,凡人がするもんじゃないな.僕は深夜のコンビニでレジ打ったりしてだらだら生きていくべきだと思った.

みんなに喜ばれる,素敵な森のパン屋さんになりたいなぁ… ケーキを焼いたり,クッキーを焼いたり.お客さんはクマさんウサギさんとか.

… 朝早いから無理だろうなぁ (駄目)




人間止めますか,現実逃避ダメ絶対.

まぁ,私のコードジェネレーションが死ぬほど適当なのが悪い自業自得なんですが,コンパイラのバグが取れなくて困ってます.そりゃあ全てを投げ出して,盗んだバイクで走り出したくもなりますよ.

append とか factorial あたりの簡単なルールは,もう大方コンパイルして dll 作って S 式 (クエリー) を読み込むインタフェースから起動できるようになってきたので,今は n 番目の素数を求める nthprime とか,ちょっと複雑なやつをコンパイルできるようにしています.かなり行き当たりばったりに作っているので,いろいろ無理が出てきてますが.

# リファクタリング (テストが怪しいので,おこがましい言い方ですが) している間は表面上は何も進んでないように見えるため,進捗報告がいろいろ苦しくなってイヤーンな感じになりますし… とりあえず nthprime が動いたら,いろいろ綺麗にしていきたい.これでもだいぶがんばってるのですが.

(アカデミックな人って,みんな無意味に素数生成大好きだよね ☆)

コンパイルする D ルールは,こんな感じ.

(nthprime *1 *A), {(== *1 1)}
--> (= *A 2).
(nthprime *B *C)
--> (createArray *D *B),
(setArrayElement *D 0 2),
(primeArray 3 *D 0 1 *B),
(:= *E (- *B 1)),
(getArrayElement *D *E *C),
(DestroyArray *D).

(DestroyArray *D) --> (print *D).

(primeArray *F *G *H *I *J), {(== *I *J)} -->.

(primeArray *K *L *M *N *O),
{(getArrayElement *L *M *P),
(:= *Q (x *P *P)),
(< *K *Q)}
--> (setArrayElement *L *N *K),
(:= *R (+ *N 1)),
(:= *S (+ *K 2)),
(primeArray *S *L 1 *R *O).

(primeArray *T *A *i *W *X),
{(getArrayElement *A *i *Y),
(:= 0 (mod *T *Y))}
--> (:= *A1 (+ *T 2)),
(primeArray *A1 *A 1 *W *X).

(primeArray *B1 *A *i *E1 *F1)
--> (getArrayElement *A *i *G1),
(:= *i1 (+ *i 1)),
(primeArray *B1 *A *i1 *E1 *F1).


まぁ,この D ルールは私が書いたものじゃないので,実はよくわからないところが何箇所かあるのですが.

明らかに不要な命令とかあったし.なんか,微妙に変換器を意識したのか,手続き型言語っぽい感じになってるし.わざわざヘッドでのパターンマッチを使わないでいるところとか.DestroyArray とかは,ETI のレベルでは不要 (GC されるから) なので,配列を表示させたりと,どうでも良いようなことしてます.

おそらく,何らかの変換器を通ったものなのでしょう.変数名とかが機械的に A1 F1 E1 とか振られていて,分かり難いですが,まぁこの程度なら何とか (ちょこっと中途半端に書き直していたりもしますが).

しかしまぁ,別に人間がこれ書き換えたりするわけではないので,問題無しと.単なる例題ですので.

一応動かしてみると,

[D]>(nthprime 10 *)
-------------------------D execution ---------------------
{2 3 5 7 11 13 17 19 23 29}
----------------------------------------------------------
succeeded.
(nthprime 10 29)

ちゃんと動いてるっぽいですね.

要は,配列に順番に素数を詰めていって,比較しつつ探索を進めていく感じ.

まぁ,これをまたテキトーに何段階かプログラム変換すると (初期の方には,私はかかわってないので,途中までブラックボックスです).

?- (include "runtime.eti").

(as (main (nthprime *A *B))
:
(makeStack *C)
(makeHeap *D)
(setArgs 1 (*A *B) 2 *C *D)
(saveStack *C *E)
(nthprime2 *C *D)
(returnArgs 1 (*A *B) 2 *E *D))

(as (nthprime2 *G *H)
(getArrayElement *G 1 *F)
:
(dec ((arr 3)) *F *G *H)
(nthprime21 *G *H))

(as (nthprime21 *C *D)
(getArrayElement *C 1 *I)
(not (== 1 (INT 1) *I *C *D))
:
(nthprime22 *C *D))

(as (nthprime21 *C *D)
(getArrayElement *C 1 *I)
:
(makeSexp 2 2 *I *C *D)
(return TRUE *I *C *D))

(as (nthprime22 *C *D)
(getArrayElement *C 1 *I)
:
(eval (newpvar 3) *I *C *D *J)
(createArray *J 1 *I *C *D)
//(print (createArray *J 1 *I *C *D))
(setArrayElement 3 (INT 0) (INT 2) *I *C *D)
//(print (setArrayElement 3 (INT 0) (INT 2) *I *C *D))
(subst s 1 (INT 3) *I *C *D)
(subst s 2 3 *I *C *D)
(subst s 3 (INT 0) *I *C *D)
(subst s 4 (INT 1) *I *C *D)
(subst s 5 1 *I *C *D)
(--call (primeArray5 5 *C *D))
(eval (- 1 (INT 1)) *I *C *D *K)
(getArrayElement 3 *K 2 *I *C *D)
(return TRUE *I *C *D))
/*
(as (main (primeArray *L *M *N *O *P))
:
(makeStack primeArray *C)
(makeHeap *D)
(setArgs 1 (*L *M *N *O *P) 2 *C *D)
(saveStack *C *Q)
(primeArray5 *C *D)
(returnArgs 1 (*L *M *N *O *P) 2 *Q *D))
*/
(as (primeArray5 *S *T)
(getArrayElement *S 1 *R)
:
(dec ((char 6)) *R *S *T)
(primeArray51 *S *T))

(as (primeArray51 *C *D)
(getArrayElement *C 1 *I)
(not (== 4 5 *I *C *D))
:
(primeArray52 *C *D))

(as (primeArray51 *C *D)
(getArrayElement *C 1 *I)
:
(return TRUE *I *C *D))

(as (primeArray52 *C *D)
(getArrayElement *C 1 *I)
(eval (newpvar 6) *I *C *D *U)
(getArrayElement 2 3 *U *I *C *D)
(eval (x 6 6) *I *C *D *V)
(not (< 1 *V *I *C *D))
:
(primeArray53 *C *D))

(as (primeArray52 *C *D)
(getArrayElement *C 1 *I)
:
(setArrayElement 2 4 1 *I *C *D)
(eval (+ 4 (INT 1)) *I *C *D *W)
(subst t 4 *W *I *C *D)
(subst t 3 (INT 1) *I *C *D)
(eval (+ 1 (INT 2)) *I *C *D *X)
(subst t 1 *X *I *C *D)
(primeArray51 *C *D))

(as (primeArray53 *C *D)
(getArrayElement *C 1 *I)
(eval (newpvar 6) *I *C *D *Y)
(getArrayElement 2 3 *Y *I *C *D)
(eval (mod 1 6) *I *C *D *A1)
(not (== (INT 0) *A1 *I *C *D))
:
(primeArray54 *C *D))

(as (primeArray53 *C *D)
(getArrayElement *C 1 *I)
:
(subst t 3 (INT 1) *I *C *D)
(eval (+ 1 (INT 2)) *I *C *D *B1)
(subst t 1 *B1 *I *C *D)
(primeArray51 *C *D))

(as (primeArray54 *C *D)
(getArrayElement *C 1 *I)
:
(eval (+ 3 (INT 1)) *I *C *D *C1)
(subst t 3 *C1 *I *C *D)
(primeArray51 *C *D))

こーんな感じで,かなり手続き型言語チックに.この API というか変換のやり方とか形式のところ全般が,私が進めているところです.

なんか,デバッグのためのコードもコメントアウトされたまんまで混じっちゃってますが,気にしないでください.

runtime.eti ってのは,私がテキトーに書いた,ETI の上で上記のプログラムを動かすための,基本的な実行用ルールが定義されているファイルです.

main ってのは,ETI の上でのエントリーポイントです.コンパイルする際には無視されます.

んで,これを部分評価すると

[D]>(peval "nthprime.eti")
-------------------------D execution ---------------------
(as (main (nthprime *A *B)) :
(createArray *C 200)
(setArrayElement *C 2 2)
(setArrayElement *C 1 2)
(setArrayElement *C 0 2)
(createArray *D 300)
(setArrayElement *D 0 0)
(setSexp 1 *A 2 *C *D)
(setSexp 2 *B 2 *C *D)
(getArrayElement *C 0 *E)
(:= *F (+ *E 1))
(createArray *G *F)
(saveArray *F *C *G)
(nthprime2 *C *D)
(returnArg 1 *A 2 *G *D)
(returnArg 2 *B 2 *G *D))

(as (nthprime2 *H *I)
(getArrayElement *H 1 *J) :
(getArrayElement *I 0 *K)
(:= *L (+ *K 1))
(:= *M (+ *K 2))
(setArrayElement *I 0 *M)
(setArrayElement *I *L PVAR)
(:= *N (+ 3 *J))
(setArrayElement *H *N *L)
(updateArrayLength *N *H)
(nthprime21 *H *I))

(as (nthprime21 *O *P)
(getArrayElement *O 1 *Q)
(not (== 1 (INT 1) *Q *O *P)) :
(nthprime22 *O *P))

(as (nthprime21 *R *S)
(getArrayElement *R 1 *T) :
(:= *U (+ 2 *T))
(getArrayElement *R *U *V)
(setArrayElement *S *V INT)
(:= *W (+ *V 1))
(setArrayElement *S *W 2)
(getArrayElement *R *T *X)
(setArrayElement *R 1 *X)
(:= *Y (- *T 1))
(setArrayElement *R 0 *Y))

(as (nthprime22 *A1 *B1)
(getArrayElement *A1 1 *C1) :
(getArrayElement *B1 0 *D1)
(:= *E1 (+ *D1 1))
(:= *F1 (+ *D1 2))
(setArrayElement *B1 0 *F1)
(setArrayElement *B1 *E1 PVAR)
(:= *G1 (+ 3 *C1))
(setArrayElement *A1 *G1 *E1)
(updateArrayLength *G1 *A1)
(:= *H1 (+ 1 *C1))
(getArrayElement *A1 *H1 *I1)
(deref (REF *I1) *B1 (REF *J1))
(:= *K1 (+ *J1 1))
(getArrayElement *B1 *J1 INT)
(getArrayElement *B1 *K1 *L1)
(:= *M1 (x *L1 2))
(createArray *N1 *M1)
(deref (REF *E1) *B1 (REF *O1))
(getArrayElement *B1 *O1 PVAR)
(:= *P1 (+ *O1 1))
(setArrayElement *B1 *O1 ARRAY)
(setArrayElement *B1 *P1 *N1)
(:= *Q1 (+ 3 *C1))
(getArrayElement *A1 *Q1 *R1)
(deref (REF *R1) *B1 (REF *S1))
(:= *T1 (+ *S1 1))
(getArrayElement *B1 *T1 *U1)
(setArrayElement *U1 0 INT)
(setArrayElement *U1 1 2)
(getArrayElement *B1 0 *V1)
(:= *W1 (+ *V1 1))
(:= *X1 (+ *V1 2))
(setArrayElement *B1 0 *X1)
(setArrayElement *B1 *W1 INT)
(:= *Y1 (+ *W1 1))
(setArrayElement *B1 *Y1 3)
(getArrayElement *A1 0 *A2)
(:= *B2 (+ (+ *A2 1) 1))
(setArrayElement *A1 *B2 *W1)
(:= *C2 (+ 3 *C1))
(getArrayElement *A1 *C2 *D2)
(getArrayElement *A1 0 *E2)
(:= *F2 (+ (+ *E2 1) 2))
(setArrayElement *A1 *F2 *D2)
(getArrayElement *B1 0 *G2)
(:= *H2 (+ *G2 1))
(:= *I2 (+ *G2 2))
(setArrayElement *B1 0 *I2)
(setArrayElement *B1 *H2 INT)
(:= *J2 (+ *H2 1))
(setArrayElement *B1 *J2 0)
(getArrayElement *A1 0 *K2)
(:= *L2 (+ (+ *K2 1) 3))
(setArrayElement *A1 *L2 *H2)
(getArrayElement *B1 0 *M2)
(:= *N2 (+ *M2 1))
(:= *O2 (+ *M2 2))
(setArrayElement *B1 0 *O2)
(setArrayElement *B1 *N2 INT)
(:= *P2 (+ *N2 1))
(setArrayElement *B1 *P2 1)
(getArrayElement *A1 0 *Q2)
(:= *R2 (+ (+ *Q2 1) 4))
(setArrayElement *A1 *R2 *N2)
(:= *S2 (+ 1 *C1))
(getArrayElement *A1 *S2 *T2)
(getArrayElement *A1 0 *U2)
(:= *V2 (+ (+ *U2 1) 5))
(setArrayElement *A1 *V2 *T2)
(getArrayElement *A1 0 *W2)
(getArrayElement *A1 1 *X2)
(:= *Y2 (+ *W2 1))
(setArrayElement *A1 *Y2 *X2)
(:= *A3 (+ *Y2 5))
(setArrayElement *A1 0 *A3)
(setArrayElement *A1 1 *Y2)
(call (primeArray5 *A1 *B1))
(:= *B3 (+ 1 *C1))
(getArrayElement *A1 *B3 *C3)
(deref (REF *C3) *B1 (REF *D3))
(:= *E3 (+ *D3 1))
(getArrayElement *B1 *D3 INT)
(getArrayElement *B1 *E3 *F3)
(:= *G3 (- *F3 1))
(:= *H3 (+ 3 *C1))
(getArrayElement *A1 *H3 *I3)
(deref (REF *I3) *B1 (REF *J3))
(:= *K3 (+ *J3 1))
(getArrayElement *B1 *K3 *L3)
(:= *M3 (x *G3 2))
(getArrayElement *L3 *M3 *N3)
(:= *O3 (+ *M3 1))
(getArrayElement *L3 *O3 *P3)
(:= *Q3 (+ 2 *C1))
(getArrayElement *A1 *Q3 *R3)
(deref (REF *R3) *B1 (REF *S3))
(getArrayElement *B1 *S3 PVAR)
(:= *T3 (+ *S3 1))
(setArrayElement *B1 *S3 *N3)
(setArrayElement *B1 *T3 *P3)
(getArrayElement *A1 *C1 *U3)
(setArrayElement *A1 1 *U3)
(:= *V3 (- *C1 1))
(setArrayElement *A1 0 *V3))

(as (primeArray5 *W3 *X3)
(getArrayElement *W3 1 *Y3) :
(getArrayElement *X3 0 *A4)
(:= *B4 (+ *A4 1))
(:= *C4 (+ *A4 2))
(setArrayElement *X3 0 *C4)
(setArrayElement *X3 *B4 PVAR)
(:= *D4 (+ 6 *Y3))
(setArrayElement *W3 *D4 *B4)
(updateArrayLength *D4 *W3)
(primeArray51 *W3 *X3))

(as (primeArray51 *E4 *F4)
(getArrayElement *E4 1 *G4)
(not (== 4 5 *G4 *E4 *F4)) :
(primeArray52 *E4 *F4))

(as (primeArray51 *H4 *I4)
(getArrayElement *H4 1 *J4) :
(getArrayElement *H4 *J4 *K4)
(setArrayElement *H4 1 *K4)
(:= *L4 (- *J4 1))
(setArrayElement *H4 0 *L4))

(as (primeArray52 *M4 *N4)
(getArrayElement *M4 1 *O4)
(getArrayElement *N4 0 *P4)
(:= *Q4 (+ *P4 1))
(:= *R4 (+ *P4 2))
(setArrayElement *N4 0 *R4)
(setArrayElement *N4 *Q4 PVAR)
(:= *S4 (+ 6 *O4))
(setArrayElement *M4 *S4 *Q4)
(updateArrayLength *S4 *M4)
(:= *T4 (+ 2 *O4))
(getArrayElement *M4 *T4 *U4)
(deref (REF *U4) *N4 (REF *V4))
(:= *W4 (+ *V4 1))
(getArrayElement *N4 *W4 *X4)
(:= *Y4 (+ 3 *O4))
(getArrayElement *M4 *Y4 *A5)
(deref (REF *A5) *N4 (REF *B5))
(:= *C5 (+ *B5 1))
(getArrayElement *N4 *B5 INT)
(getArrayElement *N4 *C5 *D5)
(:= *E5 (x *D5 2))
(getArrayElement *X4 *E5 *F5)
(:= *G5 (+ *E5 1))
(getArrayElement *X4 *G5 *H5)
(deref (REF *Q4) *N4 (REF *I5))
(getArrayElement *N4 *I5 PVAR)
(:= *J5 (+ *I5 1))
(setArrayElement *N4 *I5 *F5)
(setArrayElement *N4 *J5 *H5)
(:= *K5 (+ 6 *O4))
(getArrayElement *M4 *K5 *L5)
(deref (REF *L5) *N4 (REF *M5))
(:= *N5 (+ *M5 1))
(getArrayElement *N4 *M5 INT)
(getArrayElement *N4 *N5 *O5)
(:= *P5 (+ 6 *O4))
(getArrayElement *M4 *P5 *Q5)
(deref (REF *Q5) *N4 (REF *R5))
(:= *S5 (+ *R5 1))
(getArrayElement *N4 *R5 INT)
(getArrayElement *N4 *S5 *T5)
(:= *U5 (x *O5 *T5))
(not (< 1 (INT *U5) *O4 *M4 *N4)) :
(primeArray53 *M4 *N4))

(as (primeArray52 *V5 *W5)
(getArrayElement *V5 1 *X5) :
(:= *Y5 (+ 2 *X5))
(getArrayElement *V5 *Y5 *A6)
(deref (REF *A6) *W5 (REF *B6))
(:= *C6 (+ *B6 1))
(getArrayElement *W5 *C6 *D6)
(:= *E6 (+ 4 *X5))
(getArrayElement *V5 *E6 *F6)
(deref (REF *F6) *W5 (REF *G6))
(:= *H6 (+ *G6 1))
(getArrayElement *W5 *G6 INT)
(getArrayElement *W5 *H6 *I6)
(:= *J6 (+ 1 *X5))
(getArrayElement *V5 *J6 *K6)
(deref (REF *K6) *W5 (REF *L6))
(:= *M6 (+ *L6 1))
(getArrayElement *W5 *L6 *N6)
(getArrayElement *W5 *M6 *O6)
(:= *P6 (x *I6 2))
(setArrayElement *D6 *P6 *N6)
(:= *Q6 (+ *P6 1))
(setArrayElement *D6 *Q6 *O6)
(:= *R6 (+ 4 *X5))
(getArrayElement *V5 *R6 *S6)
(deref (REF *S6) *W5 (REF *T6))
(:= *U6 (+ *T6 1))
(getArrayElement *W5 *T6 INT)
(getArrayElement *W5 *U6 *V6)
(:= *W6 (+ *V6 1))
(:= *X6 (+ 4 *X5))
(getArrayElement *V5 *X6 *Y6)
(:= *A7 (+ *Y6 1))
(setArrayElement *W5 *Y6 INT)
(setArrayElement *W5 *A7 *W6)
(:= *B7 (+ 3 *X5))
(getArrayElement *V5 *B7 *C7)
(:= *D7 (+ *C7 1))
(setArrayElement *W5 *C7 INT)
(setArrayElement *W5 *D7 1)
(:= *E7 (+ 1 *X5))
(getArrayElement *V5 *E7 *F7)
(deref (REF *F7) *W5 (REF *G7))
(:= *H7 (+ *G7 1))
(getArrayElement *W5 *G7 INT)
(getArrayElement *W5 *H7 *I7)
(:= *J7 (+ *I7 2))
(:= *K7 (+ 1 *X5))
(getArrayElement *V5 *K7 *L7)
(:= *M7 (+ *L7 1))
(setArrayElement *W5 *L7 INT)
(setArrayElement *W5 *M7 *J7)
(primeArray51 *V5 *W5))

(as (primeArray53 *N7 *O7)
(getArrayElement *N7 1 *P7)
(getArrayElement *O7 0 *Q7)
(:= *R7 (+ *Q7 1))
(:= *S7 (+ *Q7 2))
(setArrayElement *O7 0 *S7)
(setArrayElement *O7 *R7 PVAR)
(:= *T7 (+ 6 *P7))
(setArrayElement *N7 *T7 *R7)
(updateArrayLength *T7 *N7)
(:= *U7 (+ 2 *P7))
(getArrayElement *N7 *U7 *V7)
(deref (REF *V7) *O7 (REF *W7))
(:= *X7 (+ *W7 1))
(getArrayElement *O7 *X7 *Y7)
(:= *A8 (+ 3 *P7))
(getArrayElement *N7 *A8 *B8)
(deref (REF *B8) *O7 (REF *C8))
(:= *D8 (+ *C8 1))
(getArrayElement *O7 *C8 INT)
(getArrayElement *O7 *D8 *E8)
(:= *F8 (x *E8 2))
(getArrayElement *Y7 *F8 *G8)
(:= *H8 (+ *F8 1))
(getArrayElement *Y7 *H8 *I8)
(deref (REF *R7) *O7 (REF *J8))
(getArrayElement *O7 *J8 PVAR)
(:= *K8 (+ *J8 1))
(setArrayElement *O7 *J8 *G8)
(setArrayElement *O7 *K8 *I8)
(:= *L8 (+ 1 *P7))
(getArrayElement *N7 *L8 *M8)
(deref (REF *M8) *O7 (REF *N8))
(:= *O8 (+ *N8 1))
(getArrayElement *O7 *N8 INT)
(getArrayElement *O7 *O8 *P8)
(:= *Q8 (+ 6 *P7))
(getArrayElement *N7 *Q8 *R8)
(deref (REF *R8) *O7 (REF *S8))
(:= *T8 (+ *S8 1))
(getArrayElement *O7 *S8 INT)
(getArrayElement *O7 *T8 *U8)
(:= *V8 (mod *P8 *U8))
(not (== (INT 0) (INT *V8) *P7 *N7 *O7)) :
(primeArray54 *N7 *O7))

(as (primeArray53 *W8 *X8)
(getArrayElement *W8 1 *Y8) :
(:= *A9 (+ 3 *Y8))
(getArrayElement *W8 *A9 *B9)
(:= *C9 (+ *B9 1))
(setArrayElement *X8 *B9 INT)
(setArrayElement *X8 *C9 1)
(:= *D9 (+ 1 *Y8))
(getArrayElement *W8 *D9 *E9)
(deref (REF *E9) *X8 (REF *F9))
(:= *G9 (+ *F9 1))
(getArrayElement *X8 *F9 INT)
(getArrayElement *X8 *G9 *H9)
(:= *I9 (+ *H9 2))
(:= *J9 (+ 1 *Y8))
(getArrayElement *W8 *J9 *K9)
(:= *L9 (+ *K9 1))
(setArrayElement *X8 *K9 INT)
(setArrayElement *X8 *L9 *I9)
(primeArray51 *W8 *X8))

(as (primeArray54 *M9 *N9)
(getArrayElement *M9 1 *O9) :
(:= *P9 (+ 3 *O9))
(getArrayElement *M9 *P9 *Q9)
(deref (REF *Q9) *N9 (REF *R9))
(:= *S9 (+ *R9 1))
(getArrayElement *N9 *R9 INT)
(getArrayElement *N9 *S9 *T9)
(:= *U9 (+ *T9 1))
(:= *V9 (+ 3 *O9))
(getArrayElement *M9 *V9 *W9)
(:= *X9 (+ *W9 1))
(setArrayElement *N9 *W9 INT)
(setArrayElement *N9 *X9 *U9)
(primeArray51 *M9 *N9))

----------------------------------------------------------
succeeded.
(peval "nthprime.eti")

こんな感じに,runtime.eti から include したルールの unfold とか定数畳み込み (算術単一化,記号処理) とか融合変換 (ヘッド部に影響を与えない単一化とかをやれるだけやって,余計な処理や中間構造を取り除く) を,再帰的にやれるだけやり,後には非常にプリミティブなルールと,ETI に組み込みの B ルールだけが残ります.

C コードジェネレーションには不要なので取り除かれてますが, ?-(include "runtime.eti"). すれば,ちゃんと一番最初のと同じ動作をすることが確認できます.というか,ETI の上での評価をあらかじめ部分的に安全なところだけをやっているだけなので,当たり前ですが.

not の評価とか,いろいろ微妙なところはまだやってないで,かなり甘い部分評価です.基本的な型判定ルールとかだけだったら,問題は無いので,そのうちに.それでも,あらかじめ展開しておくと,2 倍程度には容易に高速化されます.全てが等価変換ルールで定義されているので,こういうプログラムの合成が容易なのですねぇ.

本当は,型推論とか,もっといろいろ最適化や検証は可能なんですけど,とりあえず今は部分評価だけ.まぁ,やることはいくらでもあります… orz

あとは,これを,とりあえず大域的な最適化とか何も考えないで, 1-to-1 で C 言語に落とすと,こうなります.この時にも,いろいろ小手先の最適化とか,コードジェネレーションのためのアレコレが.(INT とか,(REF とか,微妙に型が付いているのが確認できると思います.たいしたことは何もしてませんが.単なる生メモリの塊 (ワード配列) なのに,ヒープとかラベルが付いてますが,まぁあまり細かいところは気にしないでください…

#include "et.h"

bool nthprime2(word stack[], word heap[]) {
word base;

{
// (getArrayElement stack 1 *A)
base = stack[1];
// (getArrayElement heap 0 *B) = heap[0]
int C = heap[0] + 1;
// (:= *C (+ (INT "heap[0]") 1))
int D = heap[0] + 2;
// (:= *D (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "D"))
heap[0] = D;
// (setArrayElement heap (INT "C") PVAR)
heap[C] = PVAR;
int E = 3 + base;
// (:= *E (+ 3 base))
// (setArrayElement stack (INT "E") (INT "C"))
stack[E] = C;
// (updateArrayLength (INT "E") stack)

if(stack[0] < E)
stack[0] = E;

// (nthprime21 stack heap)

goto nthprime21;
}

nthprime21 :
{

// (getArrayElement stack 1 *F)
base = stack[1];
// (not (== (1 (INT 1) base stack heap)))
if(1 == ideref(1, base, stack, heap))
goto nthprime211;

// (nthprime22 stack heap)

goto nthprime22;
}

nthprime211 :
{

// (getArrayElement stack 1 *G)
base = stack[1];
int H = 2 + base;
// (:= *H (+ 2 base))
// (getArrayElement stack (INT "H") *I) = stack[H]
// (setArrayElement heap (INT "stack[H]") INT)
heap[stack[H]] = INT;
int J = stack[H] + 1;
// (:= *J (+ (INT "stack[H]") 1))
// (setArrayElement heap (INT "J") 2)
heap[J] = 2;
// (getArrayElement stack base *K) = stack[base]
// (setArrayElement stack 1 (INT "stack[base]"))
stack[1] = stack[base];
int L = base - 1;
// (:= *L (- base 1))
// (setArrayElement stack 0 (INT "L"))
stack[0] = L;
return (bool)stack[base];
}
nthprime22 :
{

// (getArrayElement stack 1 *M)
base = stack[1];
// (getArrayElement heap 0 *N) = heap[0]
int O = heap[0] + 1;
// (:= *O (+ (INT "heap[0]") 1))
int P = heap[0] + 2;
// (:= *P (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "P"))
heap[0] = P;
// (setArrayElement heap (INT "O") PVAR)
heap[O] = PVAR;
int Q = 3 + base;
// (:= *Q (+ 3 base))
// (setArrayElement stack (INT "Q") (INT "O"))
stack[Q] = O;
// (updateArrayLength (INT "Q") stack)

if(stack[0] < Q)
stack[0] = Q;

int R = 1 + base;
// (:= *R (+ 1 base))
// (getArrayElement stack (INT "R") *S) = stack[R]
word T = stack[R];
while(heap[T] == REF)
T = heap[T + 1];

int U = T + 1;
// (:= *U (+ (REF "T") 1))
// (getArrayElement heap (REF "T") INT)
if(heap[T] != INT)
printf("werning : heap[T] != INT\n\n");
// (getArrayElement heap (INT "U") *V) = heap[U]
int W = heap[U] * 2;
// (:= *W (x (INT "heap[U]") 2))
// (createArray *X (INT "W"))
word X = heap[0] + 1;
heap[0] = W + 2;
heap[X] = ARRAY;
heap[X + 1] = W;

word Y = O;
while(heap[Y] == REF)
Y = heap[Y + 1];

// (getArrayElement heap (REF "Y") PVAR)
if(heap[Y] != PVAR)
printf("werning : heap[Y] != PVAR\n\n");
int A1 = Y + 1;
// (:= *A1 (+ (REF "Y") 1))
// (setArrayElement heap (REF "Y") ARRAY)
heap[Y] = ARRAY;
// (setArrayElement heap (INT "A1") (REF "X"))
heap[A1] = X;
int B1 = 3 + base;
// (:= *B1 (+ 3 base))
// (getArrayElement stack (INT "B1") *C1) = stack[B1]
word D1 = stack[B1];
while(heap[D1] == REF)
D1 = heap[D1 + 1];

int E1 = D1 + 1;
// (:= *E1 (+ (REF "D1") 1))
// (getArrayElement heap (INT "E1") *F1) = heap[E1]
// (setArrayElement (INT "heap[E1]") 0 INT)
heap[heap[E1] + 0 + 2] = INT;
// (setArrayElement (INT "heap[E1]") 1 2)
heap[heap[E1] + 1 + 2] = 2;
// (getArrayElement heap 0 *G1) = heap[0]
int H1 = heap[0] + 1;
// (:= *H1 (+ (INT "heap[0]") 1))
int I1 = heap[0] + 2;
// (:= *I1 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "I1"))
heap[0] = I1;
// (setArrayElement heap (INT "H1") INT)
heap[H1] = INT;
int J1 = H1 + 1;
// (:= *J1 (+ (INT "H1") 1))
// (setArrayElement heap (INT "J1") 3)
heap[J1] = 3;
// (getArrayElement stack 0 *K1) = stack[0]
int L1 = stack[0] + 1 + 1;
// (:= *L1 (+ (+ (INT "stack[0]") 1) 1))
// (setArrayElement stack (INT "L1") (INT "H1"))
stack[L1] = H1;
int M1 = 3 + base;
// (:= *M1 (+ 3 base))
// (getArrayElement stack (INT "M1") *N1) = stack[M1]
// (getArrayElement stack 0 *O1) = stack[0]
int P1 = stack[0] + 1 + 2;
// (:= *P1 (+ (+ (INT "stack[0]") 1) 2))
// (setArrayElement stack (INT "P1") (INT "stack[M1]"))
stack[P1] = stack[M1];
// (getArrayElement heap 0 *Q1) = heap[0]
int R1 = heap[0] + 1;
// (:= *R1 (+ (INT "heap[0]") 1))
int S1 = heap[0] + 2;
// (:= *S1 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "S1"))
heap[0] = S1;
// (setArrayElement heap (INT "R1") INT)
heap[R1] = INT;
int T1 = R1 + 1;
// (:= *T1 (+ (INT "R1") 1))
// (setArrayElement heap (INT "T1") 0)
heap[T1] = 0;
// (getArrayElement stack 0 *U1) = stack[0]
int V1 = stack[0] + 1 + 3;
// (:= *V1 (+ (+ (INT "stack[0]") 1) 3))
// (setArrayElement stack (INT "V1") (INT "R1"))
stack[V1] = R1;
// (getArrayElement heap 0 *W1) = heap[0]
int X1 = heap[0] + 1;
// (:= *X1 (+ (INT "heap[0]") 1))
int Y1 = heap[0] + 2;
// (:= *Y1 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "Y1"))
heap[0] = Y1;
// (setArrayElement heap (INT "X1") INT)
heap[X1] = INT;
int A2 = X1 + 1;
// (:= *A2 (+ (INT "X1") 1))
// (setArrayElement heap (INT "A2") 1)
heap[A2] = 1;
// (getArrayElement stack 0 *B2) = stack[0]
int C2 = stack[0] + 1 + 4;
// (:= *C2 (+ (+ (INT "stack[0]") 1) 4))
// (setArrayElement stack (INT "C2") (INT "X1"))
stack[C2] = X1;
int D2 = 1 + base;
// (:= *D2 (+ 1 base))
// (getArrayElement stack (INT "D2") *E2) = stack[D2]
// (getArrayElement stack 0 *F2) = stack[0]
int G2 = stack[0] + 1 + 5;
// (:= *G2 (+ (+ (INT "stack[0]") 1) 5))
// (setArrayElement stack (INT "G2") (INT "stack[D2]"))
stack[G2] = stack[D2];
// (getArrayElement stack 0 *H2) = stack[0]
// (getArrayElement stack 1 *I2)
base = stack[1];
int J2 = stack[0] + 1;
// (:= *J2 (+ (INT "stack[0]") 1))
// (setArrayElement stack (INT "J2") base)
stack[J2] = base;
int K2 = J2 + 5;
// (:= *K2 (+ (INT "J2") 5))
// (setArrayElement stack 0 (INT "K2"))
stack[0] = K2;
// (setArrayElement stack 1 (INT "J2"))
stack[1] = J2;
// (call (primeArray5 stack heap))
goto primeArray5;
int M2 = 1 + base;
// (:= *M2 (+ 1 base))
// (getArrayElement stack (INT "M2") *N2) = stack[M2]
word O2 = stack[M2];
while(heap[O2] == REF)
O2 = heap[O2 + 1];

int P2 = O2 + 1;
// (:= *P2 (+ (REF "O2") 1))
// (getArrayElement heap (REF "O2") INT)
if(heap[O2] != INT)
printf("werning : heap[O2] != INT\n\n");
// (getArrayElement heap (INT "P2") *Q2) = heap[P2]
int R2 = heap[P2] - 1;
// (:= *R2 (- (INT "heap[P2]") 1))
int S2 = 3 + base;
// (:= *S2 (+ 3 base))
// (getArrayElement stack (INT "S2") *T2) = stack[S2]
word U2 = stack[S2];
while(heap[U2] == REF)
U2 = heap[U2 + 1];

int V2 = U2 + 1;
// (:= *V2 (+ (REF "U2") 1))
// (getArrayElement heap (INT "V2") *W2) = heap[V2]
int X2 = R2 * 2;
// (:= *X2 (x (INT "R2") 2))
// (getArrayElement (INT "heap[V2]") (INT "X2") *Y2) = heap[heap[V2] + X2]
int A3 = X2 + 1;
// (:= *A3 (+ (INT "X2") 1))
// (getArrayElement (INT "heap[V2]") (INT "A3") *B3) = heap[heap[V2] + A3]
int C3 = 2 + base;
// (:= *C3 (+ 2 base))
// (getArrayElement stack (INT "C3") *D3) = stack[C3]
word E3 = stack[C3];
while(heap[E3] == REF)
E3 = heap[E3 + 1];

// (getArrayElement heap (REF "E3") PVAR)
if(heap[E3] != PVAR)
printf("werning : heap[E3] != PVAR\n\n");
int F3 = E3 + 1;
// (:= *F3 (+ (REF "E3") 1))
// (setArrayElement heap (REF "E3") (INT "heap[heap[V2] + X2]"))
heap[E3] = heap[heap[V2] + X2];
// (setArrayElement heap (INT "F3") (INT "heap[heap[V2] + A3]"))
heap[F3] = heap[heap[V2] + A3];
// (getArrayElement stack base *G3) = stack[base]
// (setArrayElement stack 1 (INT "stack[base]"))
stack[1] = stack[base];
int H3 = base - 1;
// (:= *H3 (- base 1))
// (setArrayElement stack 0 (INT "H3"))
stack[0] = H3;
return (bool)stack[base];
}
primeArray5 :
{

// (getArrayElement stack 1 *I3)
base = stack[1];
// (getArrayElement heap 0 *J3) = heap[0]
int K3 = heap[0] + 1;
// (:= *K3 (+ (INT "heap[0]") 1))
int L3 = heap[0] + 2;
// (:= *L3 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "L3"))
heap[0] = L3;
// (setArrayElement heap (INT "K3") PVAR)
heap[K3] = PVAR;
int M3 = 6 + base;
// (:= *M3 (+ 6 base))
// (setArrayElement stack (INT "M3") (INT "K3"))
stack[M3] = K3;
// (updateArrayLength (INT "M3") stack)

if(stack[0] < M3)
stack[0] = M3;

// (primeArray51 stack heap)

goto primeArray51;
}

primeArray51 :
{

// (getArrayElement stack 1 *N3)
base = stack[1];
// (not (== 4 5 base stack heap))
if(ideref(4, base, stack, heap) == ideref(5, base, stack, heap))
goto primeArray511;

// (primeArray52 stack heap)

goto primeArray52;
}

primeArray511 :
{

// (getArrayElement stack 1 *O3)
base = stack[1];
// (getArrayElement stack base *P3) = stack[base]
// (setArrayElement stack 1 (INT "stack[base]"))
stack[1] = stack[base];
int Q3 = base - 1;
// (:= *Q3 (- base 1))
// (setArrayElement stack 0 (INT "Q3"))
stack[0] = Q3;
return (bool)stack[base];
}
primeArray52 :
{

// (getArrayElement stack 1 *R3)
base = stack[1];
// (getArrayElement heap 0 *S3) = heap[0]
int T3 = heap[0] + 1;
// (:= *T3 (+ (INT "heap[0]") 1))
int U3 = heap[0] + 2;
// (:= *U3 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "U3"))
heap[0] = U3;
// (setArrayElement heap (INT "T3") PVAR)
heap[T3] = PVAR;
int V3 = 6 + base;
// (:= *V3 (+ 6 base))
// (setArrayElement stack (INT "V3") (INT "T3"))
stack[V3] = T3;
// (updateArrayLength (INT "V3") stack)

if(stack[0] < V3)
stack[0] = V3;

int W3 = 2 + base;
// (:= *W3 (+ 2 base))
// (getArrayElement stack (INT "W3") *X3) = stack[W3]
word Y3 = stack[W3];
while(heap[Y3] == REF)
Y3 = heap[Y3 + 1];

int A4 = Y3 + 1;
// (:= *A4 (+ (REF "Y3") 1))
// (getArrayElement heap (INT "A4") *B4) = heap[A4]
int C4 = 3 + base;
// (:= *C4 (+ 3 base))
// (getArrayElement stack (INT "C4") *D4) = stack[C4]
word E4 = stack[C4];
while(heap[E4] == REF)
E4 = heap[E4 + 1];

int F4 = E4 + 1;
// (:= *F4 (+ (REF "E4") 1))
// (getArrayElement heap (REF "E4") INT)
if(heap[E4] != INT)
printf("werning : heap[E4] != INT\n\n");
// (getArrayElement heap (INT "F4") *G4) = heap[F4]
int H4 = heap[F4] * 2;
// (:= *H4 (x (INT "heap[F4]") 2))
// (getArrayElement (INT "heap[A4]") (INT "H4") *I4) = heap[heap[A4] + H4]
int J4 = H4 + 1;
// (:= *J4 (+ (INT "H4") 1))
// (getArrayElement (INT "heap[A4]") (INT "J4") *K4) = heap[heap[A4] + J4]
word L4 = T3;
while(heap[L4] == REF)
L4 = heap[L4 + 1];

// (getArrayElement heap (REF "L4") PVAR)
if(heap[L4] != PVAR)
printf("werning : heap[L4] != PVAR\n\n");
int M4 = L4 + 1;
// (:= *M4 (+ (REF "L4") 1))
// (setArrayElement heap (REF "L4") (INT "heap[heap[A4] + H4]"))
heap[L4] = heap[heap[A4] + H4];
// (setArrayElement heap (INT "M4") (INT "heap[heap[A4] + J4]"))
heap[M4] = heap[heap[A4] + J4];
int N4 = 6 + base;
// (:= *N4 (+ 6 base))
// (getArrayElement stack (INT "N4") *O4) = stack[N4]
word P4 = stack[N4];
while(heap[P4] == REF)
P4 = heap[P4 + 1];

int Q4 = P4 + 1;
// (:= *Q4 (+ (REF "P4") 1))
// (getArrayElement heap (REF "P4") INT)
if(heap[P4] != INT)
printf("werning : heap[P4] != INT\n\n");
// (getArrayElement heap (INT "Q4") *R4) = heap[Q4]
int S4 = 6 + base;
// (:= *S4 (+ 6 base))
// (getArrayElement stack (INT "S4") *T4) = stack[S4]
word U4 = stack[S4];
while(heap[U4] == REF)
U4 = heap[U4 + 1];

int V4 = U4 + 1;
// (:= *V4 (+ (REF "U4") 1))
// (getArrayElement heap (REF "U4") INT)
if(heap[U4] != INT)
printf("werning : heap[U4] != INT\n\n");
// (getArrayElement heap (INT "V4") *W4) = heap[V4]
int X4 = heap[Q4] * heap[V4];
// (:= *X4 (x (INT "heap[Q4]") (INT "heap[V4]")))
// (not (< (1 (INT (INT "X4")) base stack heap)))
if(1 < ideref(X4, base, stack, heap))
goto primeArray521;

// (primeArray53 stack heap)

goto primeArray53;
}

primeArray521 :
{

// (getArrayElement stack 1 *Y4)
base = stack[1];
int A5 = 2 + base;
// (:= *A5 (+ 2 base))
// (getArrayElement stack (INT "A5") *B5) = stack[A5]
word C5 = stack[A5];
while(heap[C5] == REF)
C5 = heap[C5 + 1];

int D5 = C5 + 1;
// (:= *D5 (+ (REF "C5") 1))
// (getArrayElement heap (INT "D5") *E5) = heap[D5]
int F5 = 4 + base;
// (:= *F5 (+ 4 base))
// (getArrayElement stack (INT "F5") *G5) = stack[F5]
word H5 = stack[F5];
while(heap[H5] == REF)
H5 = heap[H5 + 1];

int I5 = H5 + 1;
// (:= *I5 (+ (REF "H5") 1))
// (getArrayElement heap (REF "H5") INT)
if(heap[H5] != INT)
printf("werning : heap[H5] != INT\n\n");
// (getArrayElement heap (INT "I5") *J5) = heap[I5]
int K5 = 1 + base;
// (:= *K5 (+ 1 base))
// (getArrayElement stack (INT "K5") *L5) = stack[K5]
word M5 = stack[K5];
while(heap[M5] == REF)
M5 = heap[M5 + 1];

int N5 = M5 + 1;
// (:= *N5 (+ (REF "M5") 1))
// (getArrayElement heap (REF "M5") *O5) = heap[M5]
// (getArrayElement heap (INT "N5") *P5) = heap[N5]
int Q5 = heap[I5] * 2;
// (:= *Q5 (x (INT "heap[I5]") 2))
// (setArrayElement (INT "heap[D5]") (INT "Q5") (INT "heap[M5]"))
heap[heap[D5] + Q5 + 2] = heap[M5];
int R5 = Q5 + 1;
// (:= *R5 (+ (INT "Q5") 1))
// (setArrayElement (INT "heap[D5]") (INT "R5") (INT "heap[N5]"))
heap[heap[D5] + R5 + 2] = heap[N5];
int S5 = 4 + base;
// (:= *S5 (+ 4 base))
// (getArrayElement stack (INT "S5") *T5) = stack[S5]
word U5 = stack[S5];
while(heap[U5] == REF)
U5 = heap[U5 + 1];

int V5 = U5 + 1;
// (:= *V5 (+ (REF "U5") 1))
// (getArrayElement heap (REF "U5") INT)
if(heap[U5] != INT)
printf("werning : heap[U5] != INT\n\n");
// (getArrayElement heap (INT "V5") *W5) = heap[V5]
int X5 = heap[V5] + 1;
// (:= *X5 (+ (INT "heap[V5]") 1))
int Y5 = 4 + base;
// (:= *Y5 (+ 4 base))
// (getArrayElement stack (INT "Y5") *A6) = stack[Y5]
int B6 = stack[Y5] + 1;
// (:= *B6 (+ (INT "stack[Y5]") 1))
// (setArrayElement heap (INT "stack[Y5]") INT)
heap[stack[Y5]] = INT;
// (setArrayElement heap (INT "B6") (INT "X5"))
heap[B6] = X5;
int C6 = 3 + base;
// (:= *C6 (+ 3 base))
// (getArrayElement stack (INT "C6") *D6) = stack[C6]
int E6 = stack[C6] + 1;
// (:= *E6 (+ (INT "stack[C6]") 1))
// (setArrayElement heap (INT "stack[C6]") INT)
heap[stack[C6]] = INT;
// (setArrayElement heap (INT "E6") 1)
heap[E6] = 1;
int F6 = 1 + base;
// (:= *F6 (+ 1 base))
// (getArrayElement stack (INT "F6") *G6) = stack[F6]
word H6 = stack[F6];
while(heap[H6] == REF)
H6 = heap[H6 + 1];

int I6 = H6 + 1;
// (:= *I6 (+ (REF "H6") 1))
// (getArrayElement heap (REF "H6") INT)
if(heap[H6] != INT)
printf("werning : heap[H6] != INT\n\n");
// (getArrayElement heap (INT "I6") *J6) = heap[I6]
int K6 = heap[I6] + 2;
// (:= *K6 (+ (INT "heap[I6]") 2))
int L6 = 1 + base;
// (:= *L6 (+ 1 base))
// (getArrayElement stack (INT "L6") *M6) = stack[L6]
int N6 = stack[L6] + 1;
// (:= *N6 (+ (INT "stack[L6]") 1))
// (setArrayElement heap (INT "stack[L6]") INT)
heap[stack[L6]] = INT;
// (setArrayElement heap (INT "N6") (INT "K6"))
heap[N6] = K6;
// (primeArray51 stack heap)

goto primeArray51;
}

primeArray53 :
{

// (getArrayElement stack 1 *O6)
base = stack[1];
// (getArrayElement heap 0 *P6) = heap[0]
int Q6 = heap[0] + 1;
// (:= *Q6 (+ (INT "heap[0]") 1))
int R6 = heap[0] + 2;
// (:= *R6 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "R6"))
heap[0] = R6;
// (setArrayElement heap (INT "Q6") PVAR)
heap[Q6] = PVAR;
int S6 = 6 + base;
// (:= *S6 (+ 6 base))
// (setArrayElement stack (INT "S6") (INT "Q6"))
stack[S6] = Q6;
// (updateArrayLength (INT "S6") stack)

if(stack[0] < S6)
stack[0] = S6;

int T6 = 2 + base;
// (:= *T6 (+ 2 base))
// (getArrayElement stack (INT "T6") *U6) = stack[T6]
word V6 = stack[T6];
while(heap[V6] == REF)
V6 = heap[V6 + 1];

int W6 = V6 + 1;
// (:= *W6 (+ (REF "V6") 1))
// (getArrayElement heap (INT "W6") *X6) = heap[W6]
int Y6 = 3 + base;
// (:= *Y6 (+ 3 base))
// (getArrayElement stack (INT "Y6") *A7) = stack[Y6]
word B7 = stack[Y6];
while(heap[B7] == REF)
B7 = heap[B7 + 1];

int C7 = B7 + 1;
// (:= *C7 (+ (REF "B7") 1))
// (getArrayElement heap (REF "B7") INT)
if(heap[B7] != INT)
printf("werning : heap[B7] != INT\n\n");
// (getArrayElement heap (INT "C7") *D7) = heap[C7]
int E7 = heap[C7] * 2;
// (:= *E7 (x (INT "heap[C7]") 2))
// (getArrayElement (INT "heap[W6]") (INT "E7") *F7) = heap[heap[W6] + E7]
int G7 = E7 + 1;
// (:= *G7 (+ (INT "E7") 1))
// (getArrayElement (INT "heap[W6]") (INT "G7") *H7) = heap[heap[W6] + G7]
word I7 = Q6;
while(heap[I7] == REF)
I7 = heap[I7 + 1];

// (getArrayElement heap (REF "I7") PVAR)
if(heap[I7] != PVAR)
printf("werning : heap[I7] != PVAR\n\n");
int J7 = I7 + 1;
// (:= *J7 (+ (REF "I7") 1))
// (setArrayElement heap (REF "I7") (INT "heap[heap[W6] + E7]"))
heap[I7] = heap[heap[W6] + E7];
// (setArrayElement heap (INT "J7") (INT "heap[heap[W6] + G7]"))
heap[J7] = heap[heap[W6] + G7];
int K7 = 1 + base;
// (:= *K7 (+ 1 base))
// (getArrayElement stack (INT "K7") *L7) = stack[K7]
word M7 = stack[K7];
while(heap[M7] == REF)
M7 = heap[M7 + 1];

int N7 = M7 + 1;
// (:= *N7 (+ (REF "M7") 1))
// (getArrayElement heap (REF "M7") INT)
if(heap[M7] != INT)
printf("werning : heap[M7] != INT\n\n");
// (getArrayElement heap (INT "N7") *O7) = heap[N7]
int P7 = 6 + base;
// (:= *P7 (+ 6 base))
// (getArrayElement stack (INT "P7") *Q7) = stack[P7]
word R7 = stack[P7];
while(heap[R7] == REF)
R7 = heap[R7 + 1];

int S7 = R7 + 1;
// (:= *S7 (+ (REF "R7") 1))
// (getArrayElement heap (REF "R7") INT)
if(heap[R7] != INT)
printf("werning : heap[R7] != INT\n\n");
// (getArrayElement heap (INT "S7") *T7) = heap[S7]
int U7 = heap[N7] % heap[S7];
// (:= *U7 (mod (INT "heap[N7]") (INT "heap[S7]")))
// (not (== (INT 0) (INT (INT "U7")) base stack heap))
if(0 == U7)
goto primeArray531;

// (primeArray54 stack heap)

goto primeArray54;
}

primeArray531 :
{

// (getArrayElement stack 1 *V7)
base = stack[1];
int W7 = 3 + base;
// (:= *W7 (+ 3 base))
// (getArrayElement stack (INT "W7") *X7) = stack[W7]
int Y7 = stack[W7] + 1;
// (:= *Y7 (+ (INT "stack[W7]") 1))
// (setArrayElement heap (INT "stack[W7]") INT)
heap[stack[W7]] = INT;
// (setArrayElement heap (INT "Y7") 1)
heap[Y7] = 1;
int A8 = 1 + base;
// (:= *A8 (+ 1 base))
// (getArrayElement stack (INT "A8") *B8) = stack[A8]
word C8 = stack[A8];
while(heap[C8] == REF)
C8 = heap[C8 + 1];

int D8 = C8 + 1;
// (:= *D8 (+ (REF "C8") 1))
// (getArrayElement heap (REF "C8") INT)
if(heap[C8] != INT)
printf("werning : heap[C8] != INT\n\n");
// (getArrayElement heap (INT "D8") *E8) = heap[D8]
int F8 = heap[D8] + 2;
// (:= *F8 (+ (INT "heap[D8]") 2))
int G8 = 1 + base;
// (:= *G8 (+ 1 base))
// (getArrayElement stack (INT "G8") *H8) = stack[G8]
int I8 = stack[G8] + 1;
// (:= *I8 (+ (INT "stack[G8]") 1))
// (setArrayElement heap (INT "stack[G8]") INT)
heap[stack[G8]] = INT;
// (setArrayElement heap (INT "I8") (INT "F8"))
heap[I8] = F8;
// (primeArray51 stack heap)

goto primeArray51;
}

primeArray54 :
{

// (getArrayElement stack 1 *J8)
base = stack[1];
int K8 = 3 + base;
// (:= *K8 (+ 3 base))
// (getArrayElement stack (INT "K8") *L8) = stack[K8]
word M8 = stack[K8];
while(heap[M8] == REF)
M8 = heap[M8 + 1];

int N8 = M8 + 1;
// (:= *N8 (+ (REF "M8") 1))
// (getArrayElement heap (REF "M8") INT)
if(heap[M8] != INT)
printf("werning : heap[M8] != INT\n\n");
// (getArrayElement heap (INT "N8") *O8) = heap[N8]
int P8 = heap[N8] + 1;
// (:= *P8 (+ (INT "heap[N8]") 1))
int Q8 = 3 + base;
// (:= *Q8 (+ 3 base))
// (getArrayElement stack (INT "Q8") *R8) = stack[Q8]
int S8 = stack[Q8] + 1;
// (:= *S8 (+ (INT "stack[Q8]") 1))
// (setArrayElement heap (INT "stack[Q8]") INT)
heap[stack[Q8]] = INT;
// (setArrayElement heap (INT "S8") (INT "P8"))
heap[S8] = P8;
// (primeArray51 stack heap)

goto primeArray51;
}

}

こんな感じで,ひとつのファイル内のルール集合は,巨大な一つの C 関数にコンパイルされます.
見た目は C ですけど,やってることはアセンブラです.
関数コールとかも,自前でスタック管理して,スタックフレーム積んで (単なる,メモリを表現した配列へのインデックスとかだけですが.2 本のワードの配列だけで全てのデータ構造の表現と処理を行ってます) スタックポインタずらして goto とかになってます.ET において,変数のスコープはルール内のみなので,テキトーにスコープが {} で切ってあって,他のルールへは goto で全部移動してます.
普通は,関数を超えた goto とかはできないのですが,全部一個の関数に無理やりしているので,何でもアリアリ赤 5 個入り,アリス焼き鳥チップ有り,一枚千円役満御祝儀 13 枚です.
これにより,あんまりポインタも使ってませんし,解析も容易に成りそうなので,C コンパイラがいろいろがんばってくれそう,という期待も膨らみますが,とりあえず本当にテキトーに作ったものなので,やたら変数が宣言されていたりと,それ以上に今のところは無駄だらけ.追々何とかしていかないと.

とりあえず,メタ計算で,変数が使われる回数ぐらいは調べて,無駄な中間変数を潰したりしないと駄目かも.C コンパイラに期待しても良いのですが,生成されたコードを読むのも大変過ぎますし.

というか,まだちゃんと動いてないので,これからもうちょっといろいろ作りこんで,デバッグ環境も整えていかないと.

さすがに,この規模になってくると,コンパイラのデバッグも一苦労.まぁ,たぶんいくつか等価変換のパターンの記述漏れがあるということで,おおよその見当は付いてますが.たぶん,配列周り (というか,ここしか無い).一見ダラダラと長くて複雑そうに見えますけど,構造的にはかなり単純なので.

ネイティブコンパイラを作ってる人達もこんな感じでいろいろ苦労しているのだろうか ? 生成されたアセンブリ言語とにらめっこよりは,まだマシなんだろうけど… 疲れる.

まぁ,コンパイラみたいな,コードの等価変換ルールを延々と書き並べていくような処理は,ET のお家芸なので,コンパイラのコード自体は 1000 行程度のがいくつかと,かなり短いんだけど.C へのトランスレータなんて,200 〜 300 行ぐらいだし.D ルールのレベルで全ての C の概念 (コンパイラが使う程度のサブセットですが) を表現できるので.

あと,今は一つづつファイルを示してますが,本当は,2 番目の配列を使うレベルの D ルールのフェイズから,nthprime2.dll (Windows 環境の場合) まで一発で自動生成されます.ETI の上で実行している上,私の部分評価とかバックエンドの実装がテキトーすぎるので,やたら時間がかかりますが (10 〜 15 秒ぐらい ?).

計ってみた.

[D]>(expand "nthprime.eti" "nthprime.c" "nthprime2.dll")
-------------------------D execution ---------------------
----------------------------------------------------------
succeeded.
(expand "nthprime.eti" "nthprime.c" "nthprime2.dll")
execution time: 7695 [msec]

あんまり信用できませんが,とりあえず 10 秒弱くらい ? やっぱり遅いなぁ.

まぁ,速度はとりあえず私が辛抱すれば良いだけなので… でも 10 秒弱でも意外とストレスです.GCC とかに慣れてると,やたら遅く感じます.まぁ,インタプリタなので仕方ないのですが.

まぁ,あんまり詳しくは書けないのですが,だいたいこんなことやってますですよ,はい.大事なことは何も説明してないので,雰囲気ぐらいしか伝わらないとは思いますが.
ET 言語処理系関係TB:0CM:5 このエントリーを含むはてなブックマーク | livedoorクリップ livedoorクリップ BuzzurlにブックマークBuzzurlにブックマーク newsing it!