これは、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の方は、液晶は 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円ぐらいのものが売られており、僕はそれを買って使用。
液晶無しの回路図などは、 過去のブログで
今回の処理系は、生のポインタを使用しない。
メモリが少ないのに、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。
お粗末。