昨年10月頃, このブログに書いた個人用電卓は, 機能を拡張したヴァージョンが, シミュレータ上で快適に稼働している.
今回はそのプログラミング技法を紹介する.
Schemeで書いたシミュレータは, スタックの代りにリストを使う. car側がスタックトップである. 電卓実機はスタックを突き破ってポップも出来るが, リストではそうはいかぬ. また実機は2の補数の64ビットであったが, シミュレータはbignumである.
シミュレータには押しボタンはないから, それに相当する文字を決める.
0〜9は文字も0〜9.
十六進のA,B,...,Fは小文字でa,b,...,f.
算術演算+,-,*,/はそのまま.
基数変換Hex, Dec, OctはH,D,O.
数値を区切るEntはE.
Pop, Dup, Exc, Chsはそれぞれ ^,",:,_.
Sqt, Fct, Pow, JDはそれぞれS,F,P,Jである.
従って3*(2+1)は, 3E2E1+* と入力する. リターンは無視.
拡張機能には, まず補助スタックが出来た. これも実態はリストである.
命令は2個
U スタックをポップし, そこにあったものを補助スタックにプッシュする.
N 補助スタックをポップし, そこにあったものをスタックにプッシュする.
こうすることで, 例えばスタックトップの4個を回転する:
:U:U:NNで(d c b a ...)を(c b a d ...)とすることが出来る. まず:でスタックは(c d b a ...)になる; Uでcは補助スタックへ移り, (... c) (d b a ...)になる. 左側にあるリストが補助スタックで, スタックトップが右に書いてある. 2番目の:でスタックは(b d a ...)になり, Uで(... c b) (d a ...)になり, 3番目の:で(a d ...)になり, NNで(... ) (c b a d ...)になるのである.
こんなことをやっている内に, このプログラム列を記憶し, 繰り返し使いたくなった. そこで (:U:U:NN)R= と入力して, プログラム列をRという名前で記憶する. Rで(d c b a ...)が(c b a d ...)になるので, RRRとすると(d c b a ...)がこの4段の回転を3回実行し, (a d c b ...)になるのである.
さらに欲が出てきて, プログラムの中で条件ジャンプがしたくなった.
G スタックのトップから2段目が負なら, スタックトップの数だけプログラムを戻る.
10から1までの和を計算するプログラムは次のようだ.
(0Ua"N+U1-"_aG^N)X=
と定義し, Xで起動する. 実行の様子は下の通り.
上の図では, 左の方に命令が縦に並べてある. 一番左の下から0,1,...とあるのは, G命令でジャンプする相対番地である. 10回目でループを抜けると, 主のスタックトップに和の55が出来ている.
ここまで来れば鬼に鉄棒である. もっと難しいプログラムの例はまた次回に.
2009年3月18日水曜日
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿