Linux上のBASICインタプリタ

いまさらBASIC?

いまさらBASICのプログラムを書こうと思ったわけではなくて、昔書いたN88-BASICのプログラムを読む前に動かしてみれば読む必要があるかどうかの判断が早いかとちょっと調べてみました。

BASICはシステムごとの仕様の差が大きいのです。でも今回動かしてみようというプログラムはグラフィック部分が必要ないので、そう面倒ではないだろうと予想しました。

LINUX上なのは、2009年からメインのデスクトップ環境がLINUX(Debian)だからです。

Debianパッケージの一覧から

DebianのパッケージにあったBASICの説明文とgoogleの検索から探し出したマニュアルへのリンクです。

十進BASICはパッケージにはありませんが、以前お世話になったのでこれも調べました。

basic256 (1.1.4.0-2)
educational BASIC programming environment for children
BASIC-256 Language Documentation
brandy (1.20.1-1+b1)
BBC BASIC V インタプリタ
Brandy は BBC Basic 用インタプリタです。RISC OS の BASIC V インタプリタ とソースコード互換性があり、数多くの異なる OS で起動できます。
BBC BASIC for Windows/Table of Contents
BBC BASIC for Windows
bwbasic (2.20pl2-11+b2)
Bywater BASIC インタプリタ
Bywater BASIC インタプリタ (bwBASIC) は、Minimal BASIC に関する ANSI 規格 (X3.60-1978) の巨大なスーパーセットと、Full BASIC に関する ANSI 規格 (X-3.113-1987) の重要なサブセットを C で実装しています。さらに BASIC の拡張として、シェルプログラミング機能も提供されます。bwBASIC は、 可能な限り移植性に優れていることを狙っています。
Bywater BASIC Interpreter/Shell, version 1.10
gambas3 (3.9.1-3)
Complete visual development environment for Gambas
Gambas is a free development environment based on a Basic interpreter with object extensions, like Visual Basic(tm) (but it is NOT a clone!).
yabasic (2.78.0-1)
もう一つの BASIC インタプリタ
yabasic は、BASIC 言語の共通し、シンプルな要素のほとんどを実装 しています。for ループや while ループと合わせた goto 命令、そして 手続きが付属します。yabasic はモノクロの線画をサポートし、 特別な操作無しで印刷をサポートします。yabasic は、Unix や Windows で動作します。サイズが小さく (200 kB 以下) 、フリーです。
Yabasic
十進BASIC (8.0.1.3 (Linux 64bit))
(仮称)十進BASICによる/JIS Full BASIC入門

目的から、gambas3は重すぎるので避けました。

bwbasic->yabasic->十進BASICと試して、もう一度戻って、bwbasicがよいということになりました。残る3つは試していません。

BwBasic

単に起動すると、昔ながらのプログラミング環境になります。

debian:~$ は端末のプロンプト、bwBASIC:はBASICのプロンプト。

debian:~$ bwbasic 
Bywater BASIC Interpreter/Shell, version 2.20 patch level 2
Copyright (c) 1993, Ted A. Campbell
Copyright (c) 1995-1997, Jon B. Volkoff
 
bwBASIC:

直接実行もできるし、行番号をつけるとプログラムとして保存され、runで起動するしlistでリストが取れます。

bwBASIC: print "hello"
hello
bwBASIC: 100 print "hoge"
bwBASIC: run
hoge
bwBASIC: list
    100: print "hoge"

PC-8001(NEC)で始まるマイクロコンピュータは起動するとROMに格納されているBASICインタプリタが起動してこの状態になりました。とても懐かしい。この状態というのはBASICコマンドを実行するシェルとプログラムのエディタを兼ねた状態です。このエディタは一種のラインエディタで、行頭にある数値を元に行を訂正したり挿入したりします。

プログラムを2行にします。

bwBASIC: 110 print 2+3
bwBASIC: run
hoge
 5
bwBASIC: list
    100: print "hoge"
    110: print 2+3

保存します。

bwBASIC: save "bw1"

一旦プログラムを削除して、再度保存したものをloadします。

bwBASIC: delete 100-110
bwBASIC: list
bwBASIC: load "bw1"       
bwBASIC: list
    100: print "hoge"
    110: print 2+3
bwBASIC: 

行番号を使っての編集は流石に今は耐えられないので、別のエディタで編集して、実行してみます。

bwBASIC: load "bw2.bas"
bwBASIC: list
    100: print "Edited by another editor"
    120: print "110はなくなりましたか? (この上に 5 はありますか?)"
    130: for i=1 to 5
    140:     print i;
    150: next i
       : 
bwBASIC: run
Edited by another editor
110はなくなりましたか? (この上に 5 はありますか?)
 1 2 3 4 5bwBASIC: 

おっと、間違えてloadしてしまいましたが、これでloadするときにはメモリ上のプログラムはクリアされることが確認されました。print後改行なしの手法や数値の前に1桁空く(多分+印の省略のため)ことはN88-BAISCと一緒です。

端末から直接実行してみます。プログラムファイル名を引数にしてコマンドで実行します。

debian:~$ bwbasic bw2.bas
Bywater BASIC Interpreter/Shell, version 2.20 patch level 2
Copyright (c) 1993, Ted A. Campbell
Copyright (c) 1995-1997, Jon B. Volkoff
 
Edited by another editor
110はなくなりましたか? (この上に 5 はありますか?)
 1 2 3 4 5bwBASIC: 

実行後はプログラムがloadされた状態でインタプリタ内に残ります。プログラムにsystemを書いておけばインタプリタも終了します。

行番号のない行を混ぜても問題ありません。行番号があれば、行番号の順序に整頓して読み込まれます。

bwbasicとN88-BASICの違い

N88-BASIC時代の簡単なプログラムを最小の変更で動かしてみることが目標なので、とりあえず直さねばならなかったところを列挙してみます。

コメントが'ではだめ。
remでなければならないようだ。
*ではじまるラベルを認めない。
行番号で指定はOK。ラベルは欲しい。:で終わる文字列で指定、dosubでは*なしで使える
DEFINT A-Z とすると、DIM A(30)などが宣言できない
単純な変数と配列が同じレベルで管理されているらしい。N88ではA(30)が整数の配列となったが、ここでは「単純変数を配列に拡張できない」と言っているようだ
DEFINT A-Z を外すとよい。どうやら基本的にintでの運用の様子
Requested device number is already in use. が時々出る
これは原因不明。その前の部分のエラの影響だったらしい
incremented EXEC stack past max <64>
ネストしたforで出てきたエラー。これも前の部分のエラの影響だったらしい
\が普通の割り算になる
マニュアルには integer division とあるが 10\3が3.3333333になる。int(10/3)が代用になる。
行番号はけっこう煩わしい
ちゃんとしたエディタがあるのだから行番号なしで行きたいけど、すでにある行番号を消すのは面倒。外部エディタでは混在が可能なので問題ない。

一応、動きました。2の累乗の計算です。その最後の部分。

 158456325028528675187087900672: 97
 316912650057057350374175801344: 98
 633825300114114700748351602688: 99
1267650600228229401496703205376:100

yabasic

bwBASICの扱いが当初わからなくて、yabasicも試してみました。

adachi@debian64:~$ yabasic 

This is yabasic version 2.78.0,
built on x86_64-pc-linux-gnu at Mon Jan 23 14:17:02 UTC 2017

   Copyright 1995-2016 by Marc Ihm, according to the MIT License

Enter your program and type RETURN twice when done.

Your program will execute immediately and cannot be saved;
create your program with an external editor, if you want to keep it.
Type 'man yabasic' or see the file yabasic.htm for more information,
or go to www.yabasic.de for online resources.

プロンプトのないインタープリタになります。上記にあるように、print "hoge" のあと[enter]2回でhogeと出ますが、行番号でプログラムを保存するようにはなっていない様子。そこで、素直に外部エディタで

100 print "Edited by another editor"
110 gosub LABEL1
130 for i=1 to 5
     print i;
150 next i
152 print
180 end
200 // ----------
210 label LABEL1
260 print int(10/3)
290 return

実行結果です。

debian:~$ yabasic ya2.bas 
Edited by another editor
3
1 2 3 4 5
debian:~$

yabasicとN88-BASICの違い

この例とこの後の試行錯誤でわかったこと。違いはかなり大きい。

コメントが'ではだめ。
remの他、//が使えた。/* */ は使えなかった
*ではじまるラベルを認めない。
label hoge でhogeというラベルを設定する。
行番号なしの行があってもよい
行番号による並べ替えはしないようだ
\がエラーになる
int(10/3)が代用になる。
DEFINTがない
やはりintが基本かな
NEXTの後の媒介変数は省略できないらしい
全部に入れるのはちょっと面倒
if, while の後の条件は必ず ( )でくくる
これも既存のなかなか数が多い
if の形式
if () statement
if () then statement endif
open
open "hoge" for output as #1 はだめ
open "hoge" for writing as #1 とする
print using
PRINT USING ":###" ;N がN88
PRINT N USING "###" と順序が逆で、しかも数値の形式だけで":"の文字は入れられない。
PRINT ":",N 結局こうすることに
print #1
usingとの併用ができない様子。

十進BASIC

昔から授業で使わせていただいていたBASICなので調べてみました。LINUX版のバージョンが最近上がっています。

その昔、十進で計算していることが売りだったのですが、full BASICの規格ができて、これがそもそも十進らしい。その点先見の明があったというべきか、特徴が一つ減ったというべきかちょっとむずかしいところ。

プログラムの自動訂正があったり、ステップ実行ができたり、途中で変数の値を見ながら動作を確認できたりと、教育用によく考えられた仕様です。

ただ、起動してすぐに本質でないところで問題がありました。半角のフォントが全角の幅で表示されます。debianのバージョンがlennyのときには問題なかったので、BASIC側だけの問題ではないとは思いますが、単語が認識しずらくなっています。

コメントが'ではだめ
remの他、!が使える
OPENの書式が異なる
OPEN #1:NAME filename
GOSUBでラベルが使えない
行番号を使う。サブルーチンを宣言して使うというような高度な使用法だと名前で呼べる。
WHILEの書き方が異なる
DO WHILE ... LOOP と修正する。書き換えてよいか尋ねられる。
if行の:で複数の文を入れられない
endifがあって複数行書けるので、こちらが楽だが、1行に収めなければならなかったN88では多用していたので修正は多めになる。
LETが自動で入る
代入分の冒頭に挿入される。LET A=10 とか。これは昔から、本来の文法にこだわる教育的仕様。自動なので手間ではない。

結論

試してみたのは上記3つですが、その中でN88-BASICを一番手を加えずに動かせるのは Bywater BASIC であるという結論です。

今、「BASICを使ってプログラムを組むなら」の話ではありません。昔のN88-BASICを一番手を加えずに動かせるのはどれかという話です。

というわけで、とりあえずですが、次の点を修正して端末から bwbasic ファイル名 で動かします。

コメントが'ではだめ。
remに置換する。行を開けるためなら、行番号もない空行にする。
*ではじまるラベルを認めない。
gosub *hoge の*を削除。行頭の *hoge を hoge:に修正する。
DEFINT A-Z とすると、DIM A(30)などが宣言できない
DEFINT A-Z を削除する。
\が普通の割り算になる
int(10/3)などとする。