forth色々

『獄窓記』(ポプラ社)なんて本を読んだ。囚人番号755の人の本は無かったけど、この 本が図書館に有ったからだ。755の人は、獄から出てきてセブンゴーゴーって会社を 起したようだけど、これ自分への戒めのためなんでしょうか。

獄に入ると、健康に成り、自分を見つめ直すきっかけになると言う。獄窓記は、元 国会議員が、秘書給与の不正使用を問われ、入獄した時の記録。前半は、入獄する に至るまでの経過が描かれている。後半は、獄内での記録。そして最後は 出獄の日で終わる。読み応え十分。

前半は、記憶にある政界の人達が実名でバンバンと登場してくる。政治家は 秘書がいなければ何も出来ない。だから公認の秘書の給料は国から出しますってのは 至極まっとうな話。名義を借りて給料を受け取り、それを他の目的に流用する。 台所事情が苦しいところでは、つい考えてしまいそうな話だな。

入獄して、工場と呼ばれる場所で作業するんだけど、件の人は特殊工場という所に 配置される。ここは、年寄りとかの介護が必要な囚人達を、まがりなりにも懲役させる 場所。そこでの介護士役を仰せつかったそうだ。 755の人も同じような境遇で過ごしたって、言ってたな。

獄内には、あめとむちが用意されてるとか。規則でがんじがらめになってて、破ると ご飯を減らされたり仮出所が伸びるようになってる。これがむち。精神的な鞭ですな。

あめの方は、模範度合いによって昇進し、それによって手紙とか面会の自由度が 上がったり、慰問会に参加出来たり。そして、何と言っても、仮出所の時期が 短縮されるとか。

獄に入る前に生まれた子を連れて、奥さんが面会に来る場面なんかは、本当にドラマ そっくりでした、と言うか現実なんですね。当事者が語るから迫力ありましたよ。

怖いけど、中がどうなってるか覗いてみたい人にはうってつけの本です。勿論、入所 希望者にもお勧めです。最近は、外の荒波に嫌気して入所希望者が多いそうですよ。

forth on LOL

CL-USER> (setq mine (new-forth))

#<CLOSURE (LAMBDA (&REST PARAMS)) {5AC75635}>
CL-USER> (go-forth mine 5 dup * print)
; in: GO-FORTH MINE
;     (LET ((#:FORTH1312 MINE))
;       (DOLIST (W '(5 DUP * PRINT)) (FUNCALL #:FORTH1312 W)))
;

25
NIL

久しぶりにsbclとslimeを使ったよ。

FORTH on browser

先週までfactorの超入門をやったけど(本当に面白いのはGUIを扱った部分だろうけど)、誰でも 手軽に試してみるには敷居が高いかな。

そんな訳で、Netをうろうろしてみたら、Webから試せるのをPythonのあの人が公開してるのを 発見。

forth on browser

debuggerまで付いてて、stackを視覚化してくれていて、超括弧いい。括弧が要らないのは 括弧アレルギーな人にはうってつけです。

色々Forth

forthは考え方が単純なので、おいらみたいな単純な人でももどきは簡単に作れます。 色々なアイデアを盛り込む土台としても最適。

そんな訳で世はforth系に溢れているはず。で、探してみましたよ。そしたら、

Forth関連の情報サイトのまとめ

なんていうサイトを発見。一部リンク切れが有ったりしますが、案内所としては 充実してるぞ。案内に従って落としてきてもいいんだけど、世はまさにお手軽時代。 コマンドいっぱーつでインストール出来ないと、見抜きもしてもらえません。

ってな訳で

Debanでforth

の事情はどうなってるか。

sakae@debian7:~$ gforth
Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit

:0: User interrupt
Backtrace:
$B7213E1C key-file
$B72273E0 (key)
$B7218FA4 xkey
$B7219004 edit-line
$B7219408 accept
$B721907C perform
  ok
bye

間違ってC-cしちゃったら、面白そうなのが出てきたけど、これを手がかりに、新しい 遊びを創造出来るのだろうか?

sakae@debian7:~$ pforth
PForth V21
pForth loading dictionary from file /usr/lib/pforth/pforth.dic
     File format version is 8
     Name space size = 120000
     Code space size = 300000
     Entry Point     = 0
     Little  Endian Dictionary
Begin AUTO.INIT ------
^C

gforthのgはGNUの略。pforthのpは、ポータブルだそうです。きっとipadなんかにも移植 されてるのかな? そうじゃなきゃ、ポータブルを名乗る資格なし。

で、探してみたけどforthってのも探し難いワードだな。誰でも思いつくようなワードって のは、いろんなアプリに付けられていて、見つけられなかった。これはもう、JSで作れって 事なのかな。

jsforth

JavaScriptForthQuickReference

余談はさておき、もう一つ

sakae@debian7:~$ yforth
yForth? v0.1+beta - Written by Luca Padovani (C) 1996.
This software is Freeware, use it at your own risk.
^C

とまあ、おいらのDebianで、何も特殊な事をせずに、入れてみたものでした。知名度って 事では、gforthあたりになるんですかね?

FreeBSDでforth

対抗上、やらざるを得ないな。

[sakae@pcbsd ~]$ gforth
Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
bye
[sakae@pcbsd ~]$ pfe
\ Portable Forth Environment 0.33.71 (Apr 11 2013 07:32:00)
Copyright (C) Dirk Uwe Zoller  1993 - 1995.
Copyright (C) Tektronix, Inc.  1998 - 2003.
Copyright (C) Guido U. Draheim 2005 - 2008.
ANS/ffa ITC Forth - Please enter LICENSE and WARRANTY.
Running on i386 freebsd9.1 - to quit say BYE. ok
1 2 + . 3 ok
bye
Goodbye!
[sakae@pcbsd ~]$ onyx
onyx:0> 2 3 * .
Error $undefined
ostack: (2 3)
dstack: (-dict- -dict- -dict- -dict-)
cstack: ()
estack/istack trace (0..2):
0:      *
1:      -file-
2:      --start--
onyx:3> [sakae@pcbsd ~]$

Uum、 onyxって、どう使うんだろう? エラーになった途端に、内部情報を曝け出して くれるのはありがたいんだけど、随分といろいろなstackを持ってるな。

これはもう、13年もののパソコンにも入れておいて、じっくり触ってみるしかないだろう。 13年もののパソコンと言うと、FreeBSD6.4が入っているやつ。勿論、この頃の時代の バイナリーパッケージなんて無いんで、レシピに従って、コンパイルしてして入れるしか ない。

で、入れてみた。途中で、libpcreがコンフリクトしてるから、make deinstall(削除)して から、make reinstall(インストール)してねって言われた。何も考えずに、deinstall したら、運が尽きた。

firefoxとかemacsとかmltermが古いのを使ってるから、再コンパイルしてねって警告が 出てきたんだ。案の定、firefoxを起動してみると、libpcreが見つからんと怒られた。 メジャーバージョンが変わってしまったのね。(変えたのはお前だろうに)

emacsとかは兎も角、firefoxの再コンパイルなんて、この糞熱い時に やりたくないよーーー。きっとパソコンが熱中症になっちゃうぞ。熱センサーがいかれ かけてるんで、暑さを忘れて頑張ってしまうお年寄りだからね。

これはもう、firefox諦めよう。だけど、emacsにもmltermにも関係してる、libpcreって 何よ? 調べてみたらperl由来の正規表現を取り出して、よそのアプリでも使えるように したものらしい。

[sakae@pcbsd /usr/ports/devel/pcre]$ cat pkg-descr
The PCRE library is a set of functions that implement regular expression
pattern matching using the same syntax and semantics as Perl 5, with just
a few differences. The current implementation corresponds to Perl 5.005.
PCRE is  used by many programs, including Exim, Postfix, and PHP.

Written by: Phil Hazel <ph10@cam.ac.uk>

WWW: http://www.pcre.org/

perlは世紀表現命って所があって、それに追従して常にライブラリィーも 進化してんだな。一部ユーザーには迷惑な話だ事。(おいらはもう、正規表現病を克服 して、わけわかめなやつは使わなくなったからね。なんと言う自己チュー)

古いPCの余生

今まで、このPCで頑張ってXを上げてfirefoxを(無理して)使ってきた。買った当時は、 大容量メモリ(256kB)って振れ込みだったんだけど、いつの間にか、若者に追い越されて 今ではすっかりロートルになってる。でも、老兵死なずで頑張っていたんだ。 盛んにswapの嵐にも耐えながらね。

大体Xが老体に堪えていたんだな。これを期にXからもfirefoxからも開放してあげる事に しよう。余生はゆったり過ごす計画。で、ケアマネージャに相談しましたよ。

X無しで、Web見はどうします? w3mでいいじゃん。mlterm無しじゃ日本語見れないよね。 emacsもしかしですな。そうなると、外せないのは、X無しで、どうやって日本語を表示 するかですね。

さすが、ケアマネ、話がうまいね。

えっと、X無しで日本語表示って言うと、konかjfbtermの2択ですね。jfbtermを入れてみた。 起動すると、やけに細かいフォントで表示してくれる。えっと設定は何処だ。/usr/local/etc/jfbterm.conf に有った。16ドット用に切り替えたら、目にやさしくなったよ。

でも、横幅と言うか横方向の桁数が広がりすぎて、w3mを使う時疲れる。screenで画面を 割ればいいかと思ったら、生憎使ってるscreenがサポートしてない。だったらtmuxを使えよ と言うのは、置いておいて、 Cygwin で GNU Screen を使って画面の縦分割をしてみる 参考にpatchが当たったscreenを頂いてきて使う事にした。画面の桁数を調整出来たほうが便利と思って 探してみたら、

defencoding utf8
escape ^t^t
#hardstatus alwayslastline "screen | %c |%w"

# split window -- ^t x 2, change window -- ^t x o, new shell -- ^t c
bind -c REGION 2 split
bind -c REGION 1 only
bind -c REGION 0 remove
bind -c REGION o focus
bind -c REGION ^ resize
bind x command -c REGION

bind r eval 'echo "Resize window"' 'command -c resize'
bind -c resize ^]  command
bind -c resize j eval 'resize +1' 'command -c resize'
bind -c resize k eval 'resize -1' 'command -c resize'

こんな設定をしておいて、Ctl-t r し、j、k で調整出来るのね。ああ、縦割りは、Ctrl-t | で、出来る。縦だから縦棒って覚えておけば良い。

jfbtermって最大でも、20Mぐらいしかメモリーを消費しない、省資源なやつです。CUIユーザー にはぴったりなやつだと思うぞ。

emacsだけは再コンパイルが必要。どうせならと思って、emacs24のnoX版を選んでみたんだ けど、gccが古くて(emacsがgccに頼りすぎ?)コンパイルエラー。かくして、野良buildで 古めのemacsを、--without-x オプション付きでコンパイルして入れた。こうして、portsが 壊れて行くんですな。長く生きていると、しょうがない事と諦めましょ。

さて、w3mで検索ぐらいはしたい。日本語入力が欲しいなあ。 emacsにleimってSKK崩れの入力メソッドが有る事を思い出したぞ。と言うことは、w3mを emacsから使えればいいんだ。その設定は前にやってた。日本語はどうやって入力するんだったかなあ。 調べたら、C-\ で行けた。長生きはするもんだねぇ。

forth on Fedora 19

掲示板を見ていると、赤帽の実験所 19号棟の評判が良い。特にLXDE版が使い易いとか。 使い易いってのは、起動が素早いって言う意味ね。間違い無き様。 Fedoraから辿れるんだけど、LXDE版をミラーしてる 所は無いようなんで、まったりとDLするしかない。

forth目当てで、久しぶりにFedoraとご対面する事にした。インストールしてる時に アカウントの設定をさせるなんて、なかなか進んでるじゃない。パスワードの強度も 同時にチェックしてくれるし。進化してるね。

[sakae@fedora ~]$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda3       30295068 2688792  26060704  10% /
devtmpfs          509932       0    509932   0% /dev
tmpfs             513748      76    513672   1% /dev/shm
tmpfs             513748     912    512836   1% /run
tmpfs             513748       0    513748   0% /sys/fs/cgroup
tmpfs             513748      20    513728   1% /tmp
/dev/sda1         487652   88819    373233  20% /boot
/dev/sr0          671148  671148         0 100% /run/media/sakae/Fedora-Live-LXDE-i686-19-1

これからyumのお世話になって、どんなforthが有るか探してみたいんだけど、その前に、、、 yumの作者さん、残念ながら事故で亡くなっちゃいましたね。ご冥福をお祈りします。

[sakae@fedora ~]$ yum search forth
Loaded plugins: langpacks
updates/19/i386/pkgtags                                  | 312 kB     00:00
============================== N/S matched: forth ==============================
gforth.i686 : Fast and portable implementation of the ANS Forth language

  Name and summary matches only, use "search all" for everything.

これしか無いのかな。やっぱり、赤帽の客層は違うの? 客層が違ってもgforthが認識されて るって事は、デファクト・スタンダードなんだな。この世界の事が良く分かったよ。

折角fedoraを入れた事なんで、最近Netで見つけた Rubyist が今すぐ Elixir を使ってみるべき理由 ってのに出てた、ELixirってのは、有るかな? 有った、入れて みた。そのうちに、使ってみよう。

Fedora記念にfactorが入るかやってみる。gcc、gcc-c++ が入ってねぇーよって、まず怒られた。 開発するのは、特殊な人達だから自分で用意せいとな。で、コンパイルが始まったら、 何やらgtkglextとかが無いとぬかす。yum searchでそれっぽいのを探すと、 gtkglext-devel.i686が有ったので、入れた。そしたら、factorだけは出来上がったな。

GUIの世界に行って、boidsとかテトリスを動かしてみたら、動いちゃった。動くものですなあ。 ちょっと感動しましただ。まあ、考えてみれば当たり前か。factorのイメージは、vmの上で 動くワードの寄せ集めなんだから、vmさえ出来れば、後は動くわな。ちなみに、factor資源 一式は、debianからrsyncを使って持ってきたものです。rsync使えるようにしておいて良かったわい。

イメージを含めてupdateしようと思ったら、何とfedoraにはgitも入っていなかった。やっぱり素の fedoraは、開発系には振ってないのね。徹底して開発系にしておこう。思いつくまま、ruby2、R, ipythonあたりを入れた。

おいらの知ってるRは1.5だったけど、いつの間にか3系になってた。これもそれも、ビッグデータの 時流に乗るには、貫禄が有った方が良いっていう、マーケッティング戦略なんでしょうか。

話はくるくる回るけど、元に戻ってgforthの話。emacsから使えるだろうな。なんたって GNUの仲間だから、使えない訳ないよな。ソースの中にgforth.elが有るんで、それを .emacs.dの 中に放り込みます。

最近のemacsでは、.emacs.dの中に、init.elなんて のを作って、それを、.emacsの代わりにするようです。そして、そこに

[sakae@fedora ~]$ cat .emacs.d/init.el

(autoload 'forth-mode "gforth.el")
(setq auto-mode-alist (cons '("\\.fs\\'" . forth-mode) auto-mode-alist))
(autoload 'forth-block-mode "gforth.el")
(setq auto-mode-alist (cons '("\\.fb\\'" . forth-block-mode) auto-mode-alist))
(add-hook 'forth-mode-hook (function (lambda ()
     (setq forth-indent-level 4)
     (setq forth-minor-indent-level 2)
     (setq forth-hilight-level 3) )))

こんな具合に、マニュアルからコピペしておきましょう。

使い方は、簡単です。ソースの中に有った、fib.fsとかを適当に開きます。

\ Note: This is incorrect ("n fib" produces the result for fib(n+1)),
\ but we do not change it to ensure that future timing results are
\ comparable to older timing results.

: fib ( n1 -- n2 )
    dup 2 < if
        drop 1
    else
        dup
        1- recurse
        swap 2 - recurse
        +
    then ;

: main 34 fib drop ;

それから、 M-x run-forth すると画面が割れて、repl(って、表現で良いのだろうか?)が起動 します。

そしたら、C-c C-l すれば、replにファイルをロードしてくれます。(replから直接、 C-c C-lでも良い)後は使うだけ。

Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
s" /home/sakae/src/gforth-0.7.2/fib.fs" included  ok
10 fib .
10 fib . 89  ok
bye
bye

Process forth finished

つらつらとマニュアルを見てたら、gforthにも、see なんてのが有った。

see .
: .
  s>d d. ; ok
see +
Code +
( $804BDEB )  mov     dword ptr 8063B20 , ebx  \ $89 $1D $20 $3B $6 $8
( $804BDF1 )  lea     eax , dword ptr [esi]  \ $8D $6
( $804BDF3 )  mov     edx , dword ptr [esi]  \ $8B $16
( $804BDF5 )  lea     ebx , dword ptr 4 [ebx]  \ $8D $5B $4
( $804BDF8 )  add     esi , # 4  \ $83 $C6 $4
( $804BDFB )  add     dword ptr 4 [eax] , edx  \ $1 $50 $4
( $804BDFE )  mov     edx , dword ptr FC [ebx]  \ $8B $53 $FC
( $804BE01 )  mov     eax , edx  \ $89 $D0
( $804BE03 )  jmp     eax  \ $FF $E0
end-code

いきなりマシン語が出てきて、ちょっとびっくり。

vmgen

gforthのソースツリーを眺めていたら、vmgen-exなんていうdirが有った。これは何者? infoしたら、どうやら簡単に独自言語を作るしかけらしい。

vmgen-ex内にMakefileが有り、READMEも有ったんで、これはやって見る鹿。コンパイル するには、bisonとm4それにflexが必要なのね。

infoには、

     Makefile
     README
     disasm.c           wrapper file
     engine.c           wrapper file
     peephole.c         wrapper file
     profile.c          wrapper file
     mini-inst.vmg      simple VM instructions
     mini-super.vmg     superinstructions (empty at first)
     mini.h             common declarations
     mini.l             scanner
     mini.y             front end (parser, VM code generator)
     support.c          main() and other support functions
     fib.mini           example mini program
     simple.mini        example mini program
     test.mini          example mini program (tests everything)
     test.out           test.mini output
     stat.awk           script for aggregating profile information
     peephole-blacklist list of instructions not allowed in superinstructions
     seq2rule.awk       script for creating superinstructions

こんな案内が有った。取り合えずmakeしたら、miniなんてのが出来たので、

[sakae@fedora vmgen-ex]$ cat fib.mini
func fib(n)
  var r;
  if n<2 then
    r:=1;
  else
    r:=fib(n-1)+fib(n-2);
  end if;
  return r;
  // the language syntax (return only at end) leads to inefficient code here
end func;

func main()
  return fib(34);

こういう、モジュラー風なのを喰わせてみた。

[sakae@fedora vmgen-ex]$ ./mini -d fib.mini
0xb776b008: ll _IP0=0xc  _IP1=0x2
0xb776b014: lessthan
0xb776b018: zbranch target=0xb776b038
0xb776b020: lit i=1
0xb776b028: storelocal ioffset=8
0xb776b030: branch target=0xb776b07c
0xb776b038: ll _IP0=0xc  _IP1=0x1
0xb776b044: sub
0xb776b048: call target=0xb776b008  iadjust=-4
0xb776b054: ll _IP0=0xc  _IP1=0x2
0xb776b060: sub
0xb776b064: call target=0xb776b008  iadjust=-4
0xb776b070: add
0xb776b074: storelocal ioffset=8
0xb776b07c: loadlocal ioffset=8
0xb776b084: return iadjust=8
0xb776b08c: lit i=34
0xb776b094: call target=0xb776b008  iadjust=-4
0xb776b0a0: return iadjust=0
0xb776b0a8: call target=0xb776b08c  iadjust=0
0xb776b0b4: end
result = 9227465

みんな大好き、逆アセンブリ付きで、実行してみた。こういうのRubyのあの人が得意中の得意の はず。-pを付けるとプロファイラーも動くよ。便利な世の中です。

所で、肝心のvmgenってのがさっぱり出てきません。不思議に思って、コンパイル過程の ログを取ってみました。

bison -y mini.y && mv y.tab.c mini.tab.c
m4 mini-inst.vmg >mini.vmg
vmgen mini.vmg
flex -l mini.l
gcc -O3 -fomit-frame-pointer -Wall    -c -o mini.tab.o mini.tab.c
gcc -O3 -fomit-frame-pointer -Wall    -c -o support.o support.c
gcc -O3 -fomit-frame-pointer -Wall    -c -o peephole.o peephole.c
gcc -O3 -fomit-frame-pointer -Wall    -c -o profile.o profile.c
gcc -O3 -fomit-frame-pointer -Wall    -c -o disasm.o disasm.c
gcc -O3 -fomit-frame-pointer -Wall    -c -o engine.o engine.c
gcc -O3 -fomit-frame-pointer -Wall -DVM_DEBUG -DVM_PROFILING -Dengine=engine_debug -c -o engine-debug.o engine.c
gcc -O3 -fomit-frame-pointer -Wall mini.tab.o support.o peephole.o profile.o disasm.o engine.o engine-debug.o -o mini

vmgenは何やってる? 幸いシェル語みたい。肝心な部分は、

prims2x=$GFORTHDATADIR/prims2x$version.fs
file=`basename $1 .vmg`
$GFORTH -m 1000000 -e "create vmgen" $prims2x -e "c-flag on s\" $file-vm.i\" out-filename 2! s\" $1\" ' output-c ' output-c-combined process-file bye" > $file-vm.i &&
$GFORTH -m 1000000 -e "create vmgen" $prims2x -e "c-flag on s\" $1\" ' output-disasm dup process-file bye" > $file-disasm.i &&
$GFORTH -m 1000000 -e "create vmgen" $prims2x -e "c-flag on s\" $1\" ' output-gen ' noop process-file bye" > $file-gen.i &&
$GFORTH -m 1000000 -e "create vmgen" $prims2x -e "c-flag on s\" $1\" ' output-label dup process-file bye" > $file-labels.i &&
$GFORTH -m 1000000 -e "create vmgen" $prims2x -e "c-flag on s\" $1\" ' output-profile dup process-file bye" > $file-profile.i &&
$GFORTH -m 1000000 -e "create vmgen" $prims2x -e "c-flag on s\" $1\" ' noop ' output-peephole process-file bye" > $file-peephole.i

どうやらgforthの力を借りて、

[sakae@fedora vmgen-ex]$ ls *.i
mini-disasm.i  mini-labels.i    mini-profile.i
mini-gen.i     mini-peephole.i  mini-vm.i

こういうC言語用のインクルードファイルを生成してるのでした。

メインツリーにも、何とか.vmgってファイルが沢山置いて有ったけど、これはgforthアプリを 作る為の企画書なんだろうな。確認の為に自分でコンパイルして、その時のログでも 眺めてみれば良いかな。

GFORTH="./preforth -p ".:~+:."" ./gfgen -fast
if test -z ""; then \
        for i in -ll-reg -ll; do make optgforth-fast OPT=$i && cp -p gforth-fast${i} gforth-fast && break; done; \
else \
        ( cd engine && make gforth-fast ) && \
        cp -p engine/gforth-fast gforth-fast && \
        chcon -t unconfined_execmem_exec_t gforth-fast; \
        true; \
        make checkone ENGINE=./engine/gforth-fast; \
fi

gforthを作る時は、まずprefotrhってのが作られて、専用のgfgenを使ってるぽい。 複雑な事をしてる事。どんな理由が有るんだろう?