Sharp MZ-2000
いま、99BASIC であそんでいる。もう、めっちゃ、楽しいぜよ!
やっぱり、あの時代(小学5年から中1)に戻った様で夢があるよなあ。今、Visual C++ .NET でまともなプログラム作ろうとしても多分楽しめないしなぁ。やっぱり、コーディング環境と実行環境がシームレスなのが良いな!! CP/M に MACRO80 が動く環境ないかなあ? 僕が、X-1 turbo III で CP/M と MACRO80 を使っていたときは RAM ドライブだったからかなり快適だった。シャープさん、MZ-2000 Legend 作ってくれないかなあ〜? ディスプレイは液晶で良いし、記憶媒体は SD メモリカードで良い。US 配列、と言いたい所だが、JIS 配列でもウェルカムだよ! X-1 turbo III も良かったけれど MZ-2000 は憧れだったからなぁ。今、下の様なプログラムであそんでいた。
10 LET X = RND(80)
20 LET Y = RND(20)
30 CLS
40 LOCATE X, Y
50 PRINT "*** HELLO! ***"
60 FOR Z = 0 TO 99999
70 NEXT Z
80 GOTO 10
8行で書けるスクリーンセーバーだ。GNU Emacs LISP でこれを俺が作ったのと同じ時間で作れる奴がいるか?(いるかも知れないけれど……。居たとしたら変人だ!) 素晴らしいぞ! BASIC!! やっぱり、プログラミング入門は簡単に楽しめなきゃ駄目だよ!
う〜ん、別のフリーの BASIC もどき UBASIC (DOS で動く)を使ったが "LET" を理解しないぞ!(怒) 99BASIC 本当に良くできている。UBASIC をできれば HP200LX でと思ったんだが、勝手に小文字に変換するし(昔は勝手に大文字に変換された。)、"LET" を理解しないし、やーめた!! こりゃ、やっぱり、「THE BASIC」を HP200LX 向けに作るしかないか? まるで、大昔のビル・ゲイツである(苦笑)。
……今日も徹夜だ(笑)。
「THE BASIC」言語仕様の範疇内で、BASIC で用いられる標準的な演算子と関数を使うことで、2から任意の数の間に存在する、「素数」を求めることができる。これはコーディング済みだが、演習としてやってみる価値はある。「素数」が求められたら、今度は「素因数分解」ができることになる。
……さて、取りあえずの素因数分解のコーディングが済んだ。ケチっているので結果が例えば:
RUN
1534 = 2 ^ 1 * 13 ^ 1 * 59 ^ 1 * 1
OK
となってしまうが(爆)。
……、やっぱり、僕の BASIC、「THE BASIC」を実装したくなってきた。今使える C コンパイラは LSI C-86 試食版のみ。JAVA でアプレットを作ってっていうのもありか? でも、JAVA のマニュアルとか全部古本に出してしまったし。
取りあえず、「THE BASIC」が動く(ヴァーチャル)マシンを「MMX ("My Machine X")」とコードネームを付けておくか。しかし、肝心の HP200LX 用の RS232C のケーブルどこ行ったのかなあ?
LSI C-86 を試してみたが、GNUWin の bison と全く連携が取れないぞ! まあ、DLL とか付いてくるのかも知れないから、取りあえずのターゲットマシンである HP200LX では、所詮叶わぬ夢だが。よいよ、「頑張れ! ゲイツ君!!」だ!(爆)
追記:
「THE BASIC」言語仕様に置いて、「同一の変数に対する FOR のネストを認めない。」と規定したが、この条件は緩和する必要がありそうだ。例えば次のコード:
10 FOR N = 2 TO 100
20 FOR M = 2 TO N
30 LET X = N / M
40 IF X = 1 THEN GOTO 80
50 IF INT(X) - X = 0 THEN GOTO 90
60 NEXT M
70 GOTO 90
80 PRINT "PRIME NUMBER = ";N
90 NEXT N
100 END
に置いて、50行で条件を満たせば、変数 M に対する FOR ループのネストから GOTO 文により、離脱する。このコードは 100 行の END 命令で終わっているから良いが、100 行以降に、変数 M に対する FOR が、改定前の規定だと、使用出来なくなる。これはゆゆしき問題であり、また、この様な問題は深いネストからの離脱につきものなので、新しい規定を以下の様にする。
「同一の変数に対する FOR 命令文が出た場合、その変数に対する NEXT 命令文のループをより新しく実行された方の FOR ループに適応させるものとする。」
これで、今回発生した欠陥を修復出来る。いや、本気で言語(のインタープリタ)を作ろうとすると、昔は考えもしなかったことに気がつくんだなあ〜!
……。素因数分解のコードの出力をちょっとだけましにした。今のところ:
4525 = 5 ^ 2 * 181 * 1
……。最後の "* 1" を消せれば表示上の問題はお終い。しかし、公開鍵暗号の暗号化鍵に使われるだけあって、数字が大きくなると極端に演算時間が長くなる。
このコードを書いていて、FOR 命令文のもっと厳密な定義が必要なことに気がついた。
現在の仕様上は、
10 LET A = 100
20 LET B = -1
30 FOR C = 0 TO A STEP B
(snip)
50 NEXT C
60 END
と書いた場合、変数、A、B、C は整数でないと行けないと定義している。これは今のところ間違ってないと思う。
C言語の場合は、
for (a = 0; a <= 100; a += 0.3);
for (a = 100; a >= 0; a -= 0.3);
の様に記述出来、変数 a の変化値が少数であっても、「より小さい」、「より大きい」でループの存続条件を決められるが、BASIC では
10 FOR A = 0 TO 100 STEP +1
(snip)
30 NEXT A
40 FOR A = 100 TO 0 STEP -1
(snip)
60 NEXT A
70 END
の様に、ループの存続条件を「より大きい」とも「より小さい」とも規定出来ず、「等しい」と言う条件である必要がある。この事から、引数は「整数」である方が合理的と考えられる。もちろん、引数として与えた式の結果が整数であればよいのであって、演算式の内部は別に浮動小数点数値でも構わない。ただ、評価時に整数値になっていなかったらエラーを返すべきである。
99BASIC で、FOR 文の引数に浮動小数値を入れてループを回したが、エラーにはならなかった。しかし、終了条件は、TO の後に書かれた値の、整数部分が合致した場合であった。厳密に、終了条件として与えた浮動小数点値ではなかったことは言うまでもない。これは、ゲイツが作ったバグに違いない(怒)!
……。きっと、作者は、"very near *the gates*!!" って言う所でプログラミングしていたんだね。
と言っている内に素因数分解のコードが麗しく:
RUN
525 = 3 * 5 ^ 2 * 7
OK
と、表示するバージョンを作れた。後は行番号の振り直し(笑)。
……今終わった。行番号の振り直し。NOTEPAD にコードを書いてから、99BASIC で入力したから、「シームレスな開発環境」としては、ちょっと悔しい気がする。コメント付きの Ver. 0.9 として置いたが永遠の Ver. 0.9 だろう(笑)。FORTRAN なんかも古くさい言語だけれど未だに過去の蓄積の計算コード使われているから、あながち JAVA とか新しい言語知っているのが偉い訳じゃない。