1980年前後に流行した言語GAME(General Algorithmic Micro Expressions) のMS-DOS用のコンパイラです. GAMEで記述されたソースから COM形式の 実行ファイルを生成します.ランタイムライブラリ以外はGAME80コンパイラ をTurboPascalに書きなおし,8086のコードを生成するように変更したも のです.短いプログラムでは,1Kバイト程度と非常にコンパクトな実行フ ァイルが生成できます.
GAME-IIIは1978年7月号の月刊アスキーで6800用のインタプリタ(機能的に はBASIC)として大西博氏によってアセンブラソースとともに公開されまし た.バイナリのサイズが約1.5Kバイトと小さく,サイズの割に高機能でソ ースがあることから,8080, z80, 6809, 6502と多くのCPUに移植されまし た.さらに中島 聡氏によってGAME自身で記述された 8080用のGAMEコンパイラがアスキー誌上で発表され, コンパイラも多くの機種で動作するようになりました.
GAMEは,ALTAIR 680b用のたった768バイトで書かれたTinyBASICであるVTL の文法を拡張した記号言語です. ほとんどの機能が代入文で実現されて いるため,言語の解析部(parser)が非常に簡単になることから拡張機能も 容易に組み込むことが(ソースレベルで)出来ます.
GAME86 Compiler for MS-DOS 1.00C ではランタイムライブラリだけで *768バイトも* 使ってしまいました ;-)
1999年現在,TinyBASIC系のDOS用の言語処理系の実用的な価値はほとんど ないと思いますが,1980年代の「趣味」で言語処理系を作成するブームを 作るきっかけになった「小さな言語処理系のサンプル」として歴史的な価 値があると思います.私は日本で言語処理系の作成に関する書籍の発行は 1980年代が最も多かったのではないかと思っています.(統計をとったわ けではありませんが) もしかすると,今でも「小さな言語処理系」にも活用できるアイデアが生 まれるかも知れないと思って公開してみました.
DOS用GAME86コンパイラ1.00Bは1989年に書いたものですが,MS-Windows で実行しやすいように少し手を加えてバージョンは 1.00Cとしています.
GAMEソースファイルの拡張子は .GM としてください.
GAMEソースファイルが sieve.gm の場合の実行例:
E:\GAME86>game86 sieve.gm
GAME86 Compiler MS-DOS v.1.00C by Jun 4/4/99
Load 300 byte
Line No: 220 Address. = 1079
PROGRAM SIZE: 1105
---> E:\GAME86\SIEVE.COM
END
またはWindowsでsieve.gmのアイコンをGAME86.EXEのアイコンにドラッグ アンドドロップします.
E:\GAME86>sieve START 1894PRIMES END
ここで生成された SIEVE.COM は単独で実行可能です. SIEVE.COMは,80286@8MHzのときは49.7秒かかっていましたが, Celeron300A@450MHz では 0.15秒程度です.330倍!!
オリジナルの GAME-III のうちインタプリタ特有の命令(編集,リスト,プログ ラムのロードやセーブ)はサポートしていません.
以下にGAME86の文法を簡単に示します. 文法的には基本的に代入文しかありません.システム変数に値を代入,読み出し することで入出力, 制御文の機能を実現します. 演算には優先順位がありません.左から順に計算されます.
<行番号> 1 〜 32767
<10進定数> 0 〜 65535
<16進定数> $0000 〜 $FFFF
<文字定数> "文字"
<変数名> A 〜 Z または冗長形(ABC等 先頭1文字が有効)
<1バイト配列> ::= 変数名 ( <式> )
変数の値 + 2 * 式の値 のアドレスの内容を値とする.
<2バイト配列> ::= 変数名 : <式> )
変数の値 + 式の値 のアドレスの内容を値とする.
<定数> ::= <10進定数> | <16進定数> | <文字定数>
<変数> ::= <変数名> | <1バイト配列> | <2バイト配列>
<式> ::= <項> | <項> <二項演算子> <項>
<項> ::= <定数> | <変数> | <配列> |( <式> )| <単項演算子> <項>
<二項演算子> ::= + | - | * | / | = | <> | < | > | <= | >=
比較演算 は 真:1, 偽:0の値を取る.
<単項演算子> ::= - | + | % | ' | #
+ は絶対値, % は直前に実行した除算の余り,
' は乱数, #は否定.
<行> ::= <行番号> スペース <文> [ 空白 <文> ] 改行
| <行番号> スペース以外の文字 コメント 改行
<文>
<変数>=<項> 変数への代入
#=<項> <項>の値の行番号の文にジャンプ(GOTO)
行番号がなければ行番号より大きい最初の行へジャンプ
#=-1 プログラムの終了(END)
!=<項> <項>の値の行番号のサブルーチンへジャンプ(GOSUB)
] サブルーチンから戻る(RETURN)
;=式 式の値が真の場合は次の文に進み,
偽の場合は次の行を実行.
@ DO
@=(式) UNTIL
変数=初期値,ステップ FOR
@=式 NEXT
/ 改行出力
"文字列" 文字列出力
?=<項> <項>の結果を数値出力 左詰め
??=<項> <項>の結果を数値出力 16進4桁
?$=<項> <項>の結果の下位1バイトを数値出力 16進2桁
?(n)=<項> <項>の値の数値出力 n桁で右詰め
$=<項> <項>の値の下位バイトを文字コードとする1文字を出力
.=<項> <項>の値の下位バイトの数だけ空白を出力
'=<項> <項>の値で乱数シードを設定
<変数>=? 10進数値を入力して変数に代入
<変数>=$ 1文字を入力して変数に代入
本ソフトウェアの配布と改変に特に制限はありません. 万一,本ソフトウェアを使用したことで損害が発生した場合でも,私(水谷 純, mizutani.jun@nifty.or.jp)に責任を負う義務はありません.