極小Lispマシン 作り :-P :-) | たけおか ぼちぼち日記

たけおか ぼちぼち日記

思いついたらメモ


これは、Lisp Advent Calendar 2013 のDEC/05 です。


1981年だか82年だか、僕の居た大学のコンピュータクラブで、Lispを作るのが流行った。
5人ぐらいで、バラバラに オレオレLisp を作った。

Lispというものは、readerがもっとも難しいと思う。
昔風の eval は、すぐにできる気がする。

gcは、なかなかバグが取れない。C言語で書くと、Cのローカル変数や、Cのスタックに生きてるconsへのポインタが乗るが、そこはスキャンできなかったりするのが、主な原因だろう。

当時、あたくしは、BASICでLispを書いていた。
8bit機である。私は6809@1MHz の載ったBASIC Master Level3 を使っていた。
RAMは、8~48KBytes ぐらいの機械が普通だった。
BASIC master Level3は、30万円ぐらいして、5inch 片面フロッピ・ドライブとそのI/Fカードが35万円ぐらいした気がする…


さて、現在…
32bit MIPS core のPIC32が200円程度である。
PIC32MX220は、ROM:32K Bytes, RAM:8K Bytes を内蔵。
クロック周波数は40MHzで、1.56 DhrystoneMIPS。

ARM Cortex-M0 CoreのLPC1114が110円程度である。
LPC1114FN28 は、ROM:32K Bytes, RAM:4K Bytes
クロック周波数は50MHz(最大),内臓CR発信器で12MHzで使用。

32bit Coreで、40MHz って、なんぼほど速いねん!?!
RAMも4KB あれば、なんでも(?)できるぜっ。(そうか?)


そこで、極小 Lispマシンをつくろう、と思い立ったです。
BASIC インタープリタも動くんですけど、Lispインタープリタも動く。
(Flash ROMは、焼き直す)

Lisp処理系の名前「Lise:the Lisp Engine」というのは、冒頭の1981年頃の オレオレLispに付けた名前。
当時から リーゼ(liese)というシャンプー があり、その名前にインスパイアされ、Liseという女の子の名前にした。(爆笑)




まず、PIC32のマシン

たけおか ぼちぼち日記-PIC32たけおか ぼちぼち日記-Lisp running(PIC32)たけおか ぼちぼち日記-PIC32 board



PIC32の方は、液晶は Aitendo で買った 白黒の FSTN グラフィック液晶
FSTN液晶モジュール(128×64/SPI)[AD-12864-SPI]
これを、PIC32のGPIOにつないで、ソフトウェアでGPIOを制御し、SPI 的なタイミングで、コマンドを書き込む。
液晶のつなぎやすさのみを優先し、GPIOのピンを選択。

CPUチップの他には、コンデンサしか載っていない。可変抵抗は、LCDのバックライトの明るさ調整。

ネットに、8x5 ドットのフォントが落ちていたので、とりあえず、それを入れて、文字表示を行う。
(こういう液晶は、縦8ドットを1ワードとしてアクセスする。縦8ドットのフォントは、使いやすい。
当然、液晶を90°回転させた状態でマウントするなら、縦横は入れ替わるが…)

極小マシンに、キーボードは付けられないのでスイッチを何個にするか考える。
ゲームボーイ配列が面白いだろう、と、思って作ったが…
完成品を、@zick_minoh の後輩(僕の後輩でもある)の学生に見せたところ、
「だいぶ前に、zickさんが、ポケステで動かしてたのと同じですか?」と素直に言われて、驚いた。
そういえば、そんなのあったなぁ…

たぶん、以前に見た このポケステLispに、発想が引っ張られてしまったんだろうなぁ。
うーん、つまらない。
しかし、筐体を、100円ショップで売られている画鋲のケースにしたり、それにアロンアルファでスイッチを付けたり、結構、苦労しているのだ。
大体においては、ちびマシンは、入れ物が大事なのである。
だらだらした動画(無音)をあげました(2013/DEC/11)



zick君の ポケステLisp
ポケステでLispインタプリタ動かしてみた
ポケステでLispインタプリタ動かしてみた on ニコ動

ポケステは、RAMが2KBか、頑張ってるなぁ…
でも、zickは、入力補助が「コンプリーション」とか言ってるな。

こちらは、上ボタンを押すと、シンボルテーブルから、シンボルを取ってきて、入力候補にするぞ。
一回入力したシンボルは、シンボルテーブルにあるし、コンプリーションより楽なはず。
アプリケーションごとに、リセットすると、シンボルテーブルが肥大化せず、割と入力が楽。

ニュートラル状態から、下ボタン押下は、通常の1文字が候補に出る。

() '\177?+-*/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~

という順序で候補文字が出る。

スイッチ入力と並行して、シリアル・ラインからの文字入力も受け付ける。
液晶に表示される8x5ドットの文字は、極小過ぎて、オジサンには極めて読みづらい。
なので、通常は、シリアルラインから入力して、楽しむ。(^^;
表示は、液晶とシリアルラインに同じものが出力される。

free cell(利用可能なcons cell)は、800個程度あり、まぁまぁ実用的。



液晶無しの回路図などは、 過去のブログで



ARM LPC1114 のマシンは、液晶はつないでいるが、入力はシリアルラインのみ。
液晶には、Lispプログラムから自由に表示できる。

筐体になるケースとか、入力方法を検討中。
ポケステLispの轍は踏むまい。www

こちらは、4KBしかメモリがないので、
free cell(使用可能なcons)は、39個。
これでは、デモ以外、何もできない。
まぁ、そういうもんだ。\(^^;/

この機械の液晶は、Aitendoで売られている下記
ノキア液晶5110(SPI)[M-LCD5110-PCB]
以前は、基板と液晶がバラになってて、500円ぐらいのものが売られており、僕はそれを買って使用。

たけおか ぼちぼち日記-Lisp runningたけおか ぼちぼち日記-LPC1114たけおか ぼちぼち日記-LPC1141 board

液晶無しの回路図などは、 過去のブログで




今回の処理系は、生のポインタを使用しない。
メモリが少ないのに、32bitのポインタを使用すると非常に非効率である。
なので、consは、C言語の配列上に取る。
consのcar,cdrには、配列のオフセットを入れて表現。
オフセットは、unsigned short (16bit)。
tag を3bitにして、オフセット(ポインタ)の最上位3bitに入れている。
シンボルテーブルは、現在は、consとは別な領域に取っている。

fix num(小さな整数)が、13bitなので、符号付きで -4096~ +4095 しか表現できず、
すぐにオーバーフローして、やや辛い。
小規模組込用途で、使えるような、使えないような、ぎりぎりの線上。(^^;


appendできます

Lise>>(set! ap (lambda(x y) (cond ((eq? x nil) y)(#t (cons(car x)(ap(cdr x) y))))))
closure-40FC
Lise>>(ap '(a b) '(z x))
gc (a b z x )
Lise>>


クロージャなんぞも、一応ちゃんとつけてある。

Lise>>(set! aaa (let (z) (set! z 0) (lambda (x) (set! z (cons x z)))))
closure-421C
Lise>>(aaa 'asd)
gc (asd .0)
Lise>>(aaa 'asd)
(asd asd .0)
Lise>>(aaa 'asd)
(asd asd asd .0)
Lise>>(aaa 'asd)
(asd asd asd asd .0)
Lise>>(aaa 'asd)
(asd asd asd asd asd .0)
Lise>>(aaa 'asd)
(asd asd asd asd asd asd .0)
Lise>>(aaa 'asd)
gc (asd asd asd asd asd asd asd .0)
Lise>>z
NIL
Lise>>

最後に、z を見ているのは、グローバルな変数zに (asd asd asd asd asd asd asd .0)
が入っていないことを確認している。


ちなみに、Scheme風のシンボル名を使っているが、継続が無いので、ただの昔Lisp。
お粗末。