移植するぞ
ちい散歩じゃなくて雄三散歩でもなくて、早朝sakae散歩です。
普段は猫なんて見かける事は無いんだけど、どうした事か3匹の猫達に出会ってしまったよ。 きっと前夜は、この地区の年次猫集会でも有ったんだろうな。話合われた内容は、領土(なわばり) 問題、食料(ねずみ)の年間取得量問題、そして子猫に対する交通安全確保問題ぐらいかな。 これ以上の事は、宮沢賢治さんの本でも参照かな。
猫会議は人目に付かないように深夜行われる。猫社会でもきっと会議の後は宴会になるんだろな。 猫の場合は酒よりも、またたびが好物のはずだから、またたびパーティが開かれたに違いない。 泥酔状態では家に帰れないだろうから、あちこちで興奮を鎮めていたと思われる。
そんな彼(彼女)らに出会ったんだろうな。三毛猫は、りんご畑の下でうずくまっていた。もう一匹は、 茶トラ模様君、畑の畝の間で寝てた。最後の奴は、よろよろと道を横切る黒猫だった。 あれ? 黒猫が目の前を横切ると、何とかって迷信が有ったようだけど、今は思いだせんぞ。
おいらの家でも昔、猫を飼っていた事がある。引越しをした時、新しい家に馴染まず、女房が 手を焼いて、実家に預けたなあ。両親にかわいがられて幸せだったんだけど(きっと猫総会にも 新参猫として出席したに違いない)、りんご畑と道路の区別が付かなかったみたいで、交通事故 にあって亡くなってしまった。冬はゆたんぽがわりで、重宝した事を今になって思い出したよ。
そう言えば、友人も猫を飼っているそうなんだけど、隣家の猫と大喧嘩の果てに(名誉の?) 重症を負ってしまい、病院へ入院したとか。治療費が10万円を超えたとぼやいていたぞ。
それだけで済めば良かったんだけど、退院して家に戻った猫君。気がたっていたらしくて、 ご主人様の足の親指を噛んだとか。爪が剥がれる重症で、人間様も大事になったらしい。
たかが猫、されど猫。
sasagawa888さんのschemeを試す
SECDマシンに魅せられて、自分の勉強の為に、Simpleと言うSchemeコンパイラを開発されている 人が居る。
その開発記録が公開 されていて、興味深く読ませてもらっている。
Windows上で開発されているとの事なので、おいらも試しに、FreeBSDで動くか(野次馬根性丸だし) やってみたい。実を言うと、ソースが公開された直後に、一度トライした事が有るんだけど、 コンパイルでエラーを喰らって、投げ出していたんだ。
今回は旨くいくか、早速やってみる。
[sakae@secd ~/Simple-eed5d5d]$ make gcc -c main.c main.c:10:21: error: windows.h: No such file or directory In file included from main.c:14: simp.h:1: error: stray '\357' in program simp.h:1: error: stray '\273' in program simp.h:1: error: stray '\277' in program main.c: In function 'main': main.c:26: warning: return type of 'main' is not 'int' *** Error code 1 Stop in /usr/home/sakae/Simple-eed5d5d.
ありゃ、エラーですよ。
\xef\xbb\xbf /* simple (simple Scheme compiler) written by kenichi sasagawa 2012/1 */ :
vimでは見えないけど、viで開くと、simp.hの行頭にゴミ文字が見えたので、消す。それから、 ここは、FreeBSDなので、windows.hも消した。で、どうかな?
[sakae@secd ~/Simple-eed5d5d]$ make gcc -c main.c main.c: In function 'main': main.c:26: warning: return type of 'main' is not 'int' gcc -c cell.c cell.c:361:2: warning: no newline at end of file gcc -c list.c list.c:546:2: warning: no newline at end of file gcc -c function.c gcc -c compute.c gcc main.o cell.o list.o function.o compute.o -o simp main.o: In function `printflt': main.c:(.text+0x52b9): undefined reference to `floor' cell.o: In function `norm_comp': cell.c:(.text+0xb78): undefined reference to `floor' function.o: In function `f_integerp': function.c:(.text+0x45c): undefined reference to `ceil' :
まだエラーだ。でも、floorとかcellとか、数学関係者が居ないって事だな。ならば、makefileに、-lm を 追加しよう。ついでに、軟弱になって、-g も付けてgdbで追えるようにしておこう。
[sakae@secd ~/Simple-eed5d5d]$ make gcc -g -c main.c main.c: In function 'main': main.c:26: warning: return type of 'main' is not 'int' gcc -g -c cell.c cell.c:361:2: warning: no newline at end of file gcc -g -c list.c list.c:546:2: warning: no newline at end of file gcc -g -c function.c gcc -g -c compute.c gcc main.o cell.o list.o function.o compute.o -o simp -lm
コンパイル完了! こんなに簡単に移植できんの?
[sakae@secd ~/Simple-eed5d5d]$ ./simp educational Scheme compiler Simple Ver0.17.4 (written by sasagawa888) セグメンテーション違反: 11 (コアダンプ)
甘かったわい。さて、何処で落ちてるのかな?
[sakae@secd ~/Simple-eed5d5d]$ gdb simp simp.core GNU gdb (GDB) 7.4 [GDB v7.4 for FreeBSD] : Program terminated with signal 11, Segmentation fault. #0 0x0804fe60 in cdr (lis=675593984) at list.c:30 30 return(GET_CDR(lis)); (gdb) bt #0 0x0804fe60 in cdr (lis=675593984) at list.c:30 #1 0x080510e7 in macronamep (sym=644) at list.c:457 #2 0x08049bf6 in comp (expr=733, env=757, code=762, tail=1) at main.c:245 #3 0x080490a7 in comp (expr=740, env=757, code=761, tail=1) at main.c:116 #4 0x08049126 in comp (expr=746, env=757, code=756, tail=1) at main.c:120 #5 0x08049eb9 in comp_body (body=747, env=757, code=756) at main.c:282 #6 0x08049325 in comp (expr=749, env=0, code=755, tail=5) at main.c:139 #7 0x0804951d in comp (expr=752, env=0, code=753, tail=5) at main.c:154 #8 0x08048eea in compile (expr=752) at main.c:88 #9 0x08055070 in f_load (lvar=580) at function.c:1514 #10 0x08048c63 in main () at main.c:33
cdrに渡される値が、どうも範囲外のようだ。得意のvimとgdbの合わせ技で、ソースを見ながら 追ってみるか。と、思ったんだけど、貴重なコメントが、SJISのようで、ことごとく文字化け しちゃう。ここは、将来の事を考えて、utf8に変換しておこう。インデントが4tabだったり8tab だったりして落ち着かないので整頓しておく。ついでに、ctagsで、すいすい tag-jump出来るようにしておこう。
for f in *.[ch] do nkf -w $f >$$ cat $$ | sed -e 's%//\(.*\)%/*\1*/%' >$f #indent $f -i4 gindent $f -kr done rm -f *.BAK $$ *~ #ctags *.[ch] exctags *.[ch]
これ、上記の贅沢な要求を叶えるスクリプト。最初、indentはFreeBSD備え付けのやつを使って いたんだけど、// comment を、2行に分解しちゃうんで、GNU製のやつにした。ctagsも機能豊富 なやつに取り替えた。
ctags と indent
ちょいと寄り道して、ctagsとindentを調べてみた。
ctagsって、vi(m)で、CTRL+] と CTRL+t で、関数間をすいすい飛び回るやつ。ソース閲覧ツール だ。これの対抗馬は、globalなんだけど、vimを使うようになってからは、もっぱらctagsを 使ってる。
最近は、私の心代わりを察知したかどうかか知らないけど、 globalを解説した本が、出版されたようだ。 いろいろ出来るようで、面白そう。でもまあ、ctagsだって、いろいろな言語をサポートして 元気一杯みたいだしなあ。
[sakae@secd /usr/ports/devel/ctags]$ cat pkg-descr Exuberant Ctags generates an index (or tag) file of source language objects in source files that allows these items to be quickly and easily located by a text editor or other utility. Alternatively, it can generate a cross reference file which lists, in human-readable form, information about the various objects found in a set of source code files. Supported languages include: Assembler, ASP, AWK, BETA, C, C++, C#, COBOL, Eiffel, Fortran, HTML, Java, Javascript, Lisp, Lua, Make, Pascal, Perl, PHP, PL/SQL, Python, REXX, Ruby, S-Lang, Scheme, Shell (Bourne/Korn/Z), Standard ML, Tcl, Vera, Verilog, Vim and Yacc. WWW: http://ctags.sourceforge.net/
まあ、これぐらいの言語をサポートしてくれていたら、不自由する事は無いわな。 FreeBSDでは、自分で入れないと恩恵に与れないけど、GNUで出来ているLinuxだと、デフォで 使えるはず。(最近の軟弱なDesktopバージョンだと、入っていないかな?)
indentは、Cのソース用の整形ツールだ。FreeBSDではデフォで入っているけど、ちょっと融通が 利かない。(上の例みたいに、一行コメントを旨く扱えないとか)そこで、GNU版に頼る事に なる。
さすが、GNU版って事で、GNUがお勧めする(行稼ぎに貢献?)スタイルに整形するってのがデフォ の挙動だけど、Kernighan & Ritchie style とか、original Berkeley風とか、 Linux風とかも オプション一発で指定出来るようになっている。おいらは、勿論、 "The C Programming Language"本 風ですよ。それ以外は有り得ないっていう老人風頑固ささ。
上で、vimを使って、すいすい飛び回るって書いたけど、それを加速するvimのプラグインを 発見したよ。 taglistがそうなんだ。 何とvim語で4500ラインもある超大作です。よく書くわと感心せまそう。
てけとーにソースファイルを読み込んだ後こやつを起動すると(:Tlistで)、画面が左右に割れて、左側に変数名とか関数名のリストが 出て来る。CTRL+w で、左側に移動してからカーソルを合せてENTERを叩けば、飛んでく。 matzさんじゃないけど、名は体を表すんで、大体どんな風になってるかソースの構造を想像 出来て便利ですたい。
比較法
さてどうやってデバッグしよう。ものは試しと言う事で、Linuxで動くか確認してみる。だって、 オリジナルは、Windows上のMinGW環境なんだから、これほとんどLinuxと看做せるよね。
ArchBangへ持って行ったら動いちゃったよ。ちょいとおかしな事はあるけど。
educational Scheme compiler Simple Ver0.17.4 (written by sasagawa888) Simp> (car '(a b c)) a Simp> (exit) Segmentation fault
macronamep(って、Cじゃ?が使えないからLisp風ネーミング)で止めて、比較してみる。 最初は、FreeBSDの場合
(gdb) where #0 macronamep (sym=644) at list.c:507 #1 0x08049bf6 in comp (expr=733, env=757, code=762, tail=1) at main.c:283 #2 0x080490a7 in comp (expr=740, env=757, code=761, tail=1) at main.c:145 #3 0x08049126 in comp (expr=746, env=757, code=756, tail=1) at main.c:149 #4 0x08049eb9 in comp_body (body=747, env=757, code=756) at main.c:325 #5 0x08049325 in comp (expr=749, env=0, code=755, tail=5) at main.c:166 #6 0x0804951d in comp (expr=752, env=0, code=753, tail=5) at main.c:184 #7 0x08048eea in compile (expr=752) at main.c:116 #8 0x08055070 in f_load (lvar=580) at function.c:1626 #9 0x08048c63 in main () at main.c:35
こちらは、ArchLinuxの場合
(gdb) where #0 macronamep (sym=646) at list.c:507 #1 0x08049a33 in comp (expr=735, env=759, code=764, tail=1) at main.c:283 #2 0x08048f3e in comp (expr=742, env=759, code=763, tail=1) at main.c:145 #3 0x08048fbb in comp (expr=748, env=759, code=758, tail=1) at main.c:149 #4 0x08049cc6 in comp_body (body=749, env=759, code=758) at main.c:325 #5 0x080491a9 in comp (expr=751, env=0, code=757, tail=5) at main.c:166 #6 0x0804938f in comp (expr=754, env=0, code=755, tail=5) at main.c:184 #7 0x08048d9b in compile (expr=754) at main.c:116 #8 0x08054116 in f_load (lvar=580) at function.c:1626 #9 0x08048b17 in main () at main.c:35
見て分かるように、compileに渡る引数がずれてる。これが不幸の始まりなのね。さて、この後 どうしよう? しばし、作戦会議だな。困ったら、猫の手でも借り手くるか。 たまには、猫の肉球、ぐりぐりして、癒されたいぞ。