JVM関連でforthに触ってみる


タイトル通りなんですが、いきなりJVMの動きを追うのも、ちときついかと思いまして
JVMの元になった、forthにでも触ってみようと思います。
forthの源流を追っていくと、バローズのマシンまで行き着いてしまうらしいのですが
それは、ご勘弁と言う事で。

どこからか、forthを調達してこなければなりません。DebianでやるかFreeBSDで
やるか? 悩む程の事は無いのですが、2chを読むために、たまたまFreeBSDが
立ち上がっていたので、今回は、FreeBSDで行きます。

どんなものがあるやら?
[sakae@fb /usr/ports/lang]$ cd /usr/ports/
[sakae@fb /usr/ports]$ make search key=forth|more
Port:   ficl-4.0.31_1
Path:   /usr/ports/lang/ficl-devel
Info:   Forth Inspired Command Language
Maint:  bms@FreeBSD.org
B-deps: gettext-0.14.5_2 gmake-3.81_1 libiconv-1.9.2_2
R-deps:
WWW:    http://ficl.sourceforge.net/

Port:   pfe-0.29.1_1
Path:   /usr/ports/lang/forth
Info:   Implementation of ANSI Forth
Maint:  andrew.nau.ua@gmail.com
B-deps: gettext-0.14.5_2 gmake-3.81_1 libiconv-1.9.2_2
R-deps:
WWW:    http://pfe.sourceforge.net/

Port:   gforth-0.6.1_2
Path:   /usr/ports/lang/gforth
Info:   Fast and portable Forth system
Maint:  ports@FreeBSD.org
B-deps: gettext-0.14.5_2 gmake-3.81_1 libiconv-1.9.2_2
R-deps:
WWW:    http://www.gnu.org/software/gforth/gforth.html

Port:   pfe-0.32.94_1
Path:   /usr/ports/lang/pfe-devel
Info:   Implementation of ANSI Forth
Maint:  andrew.nau.ua@gmail.com
B-deps: gettext-0.14.5_2 gmake-3.81_1 libiconv-1.9.2_2 perl-5.8.8
R-deps:
WWW:    http://pfe.sourceforge.net/

いろいろありますなあ!
今回は、gforthで行ってみます。

[sakae@fb /usr/ports/lang/gforth]$ sudo make
===>  gforth-0.6.2_2 is marked as broken: Does not compile on ports build cluster.
*** Error code 1

たまに、こういう事ってあるんですよ。めげないで、Makefileを眺めます。
.if ${OSVERSION} < 700000
BROKEN=         Does not compile on ports build cluster
.endif
事故責任で、これをコメントアウトしたら、コンパイル、インストールまで出来ちゃい
ましたよ。
早速、起動してみます。

[sakae@fb ~]$ gforth
Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
1 2 3 +  ok

ok って言われたってねぇ。この先どうしたらいいん? マニュアルを探してきました。

. 5  ok
. 1  ok
.
*the terminal*:4: Stack underflow
.
^
Backtrace:
$33D8ED44 dup
$33D8F9E0 s>d

2足す3は5で、それがスタックに積まれる。(この時点で、2と3はスタックから
消えている) . は、スタックから、データを取り出して表示するって訳だ。

1 2 3 4  ok
.s <4> 1 2 3 4  ok

は、データを4つスタックに積んで 取り合えず ok。.s は、スタックを調査
するコマンドだ。現在、4個のデータがスタックにあり、一番最後(上)にある
データは、4.

: foo  compiled
  dup *   compiled
;  ok

今度は、foo と言うコマンドを定義してみた。(定義の終了は、; だ)
スタックの一番上のデータを複製してから掛け算せよ。結局、スタックのTOPに
あるデータを、2乗した事になる。

foo cr .
16  ok
.s <3> 1 2 3  ok

2乗してから、カーソルを改行(cr)、そして、結果を表示。この時点で、スタック
上のデータは、一つ無くなっている。

see foo
: foo
  dup * ; ok

先ほど定義した foo を、確認してみた。
gforth に、あらかじめ定義されているコマンドも、see で、確認出来る。

see *
Code *
( $804C0AE )  mov     dword ptr 8062094 , ebp  \ $89 $2D $94 $20 $6 $8
( $804C0B4 )  mov     ebx , dword ptr 4 [esp]  \ $8B $5C $24 $4
( $804C0B8 )  mov     edx , dword ptr [ebx]  \ $8B $13
( $804C0BA )  mov     eax , dword ptr 4 [ebx]  \ $8B $43 $4
( $804C0BD )  imul    eax , edx  \ $F $AF $C2
( $804C0C0 )  add     ebx , # 4  \ $83 $C3 $4
( $804C0C3 )  mov     dword ptr 4 [esp] , ebx  \ $89 $5C $24 $4
( $804C0C7 )  add     ebp , # 4  \ $83 $C5 $4
( $804C0CA )  mov     dword ptr [ebx] , eax  \ $89 $3
( $804C0CC )  mov     eax , dword ptr FC [ebp]  \ $8B $45 $FC
( $804C0CF )  jmp     804B470  \ $E9 $9C $F3 $FF $FF
end-code
 ok

おお、いきなり、インテルと出会ってしまったわい。¥以降は、マシン語ね。
やっぱり、インテルは避けて通れないか。
と、まあ、恣意的な事を書いてきました。まとめとして、マニュアルを見ると

5.6.1 Data stack

drop      w -                      core       “drop”
nip       w1 w2 - w2               core-ext   “nip”
dup       w - w w                  core       “dupe”
over      w1 w2 - w1 w2 w1         core       “over”
tuck      w1 w2 - w2 w1 w2         core-ext   “tuck”
swap      w1 w2 - w2 w1            core       “swap”
pick      S:... u ? S:... w        core-ext   “pick”

等と、かかれています。何か判じものみたいですね。でも、dupの所にある
w - w w と言うのは、- を、境に左側が演算前、右側が結果ですと読みます。
演算前にTopに w と言うデータがあり、それを取り出して、2回stackにpush
すると言う具合。nipだと、TOPから2番目のデータを消し去る、ですね。

と、まあ、gforthを見てきたけど、余り参考にならんなー。
何かないものかと探してみると、笹田先生のYARVがあるじゃないですか。
YARVの命令表解説も、ばっちりまとめてありますね。更に、YARVを解析された方もおられる。
嬉しくなって、Ruby-1.9.2devを思わず入れてしまいました。

sakae@debian:~$ ruby -v
ruby 1.9.2dev (2009-04-03 trunk 23129) [i686-linux]

ruby-1.9Xって、コンパイルにめちゃ時間がかかるようになりました。特にGB-XXXの
コード変換(?)に時間がかかってます。中国4000年の文化の凝縮ですから、我慢我慢。

先ほど、Sunから、javaがUpdateしましたって、案内があったけど、JVMより先にYARVだな。