GAME言語インタプリタ in C
昔懐かしのGAME言語のインタプリタをCで書いてみました。
基本的なシステムコールしか使ってないので、Cの動くシステムだったら全て動作すると思います。
GAME言語は今は廃れてしまいましたが、1980年前後にマイコンで手軽に使える処理系として一世を風靡しました。当時は、僕もGAME言語を参考に独自のインタプリタ・コンパイラを作って遊んでいたものです。
このプログラムはまだエラーチェックなどが十分ではないです。一応制御構文などは全部動きます。
コンパイル、インストール、実行
カレントディレクトリにgamec.cと、makefileを置き、makeとして下さい。
実行は、gamec [file.gm]として動かして下さい。
行末が0xa(LF)で終わるテキストを読み込みます。
makefile
gamec: gamec.c
cc -o gamec gamec.c
sudo cp gamec /usr/bin/
履歴
・2023年1月31日 16ビット配列の取得の所にバグがあったので訂正。
・2023年2月1日 マイナーチェンジ&名前をgamelinuxにする。
・2023年2月2日 バグ修正 ver 0.9
・2023年2月3日 getch()関数を内包 ver 0.9.1
・2023年2月4日 for文修正 ver 0.9.2
・2023年2月8日 for文の普通の言語モードで動作するのを FM 1に、GAME言語モードで動作するのをFM 0にする。 ver 0.9.3
・2024年7月24日 数のサポートをushortからshortにする ver 1.0.0
・2024年8月24日 1文字入力をハードgetcharから、getcharにする。名前をgamecにする ver 1.0.1
文法
・Jun Mizutani氏のGAME言語の文法を修正してアップします
<行番号> 1 〜 32767
<10進定数> -32768 〜 32767
<16進定数> $0000 〜 $FFFF
<文字定数> "文字"
<変数名> A 〜 Z または冗長形(ABC等 先頭1文字が有効)
<2バイト配列> ::= 変数名 ( <式> )
変数の値 + 2 * 式の値 のアドレスの内容を値とする.
<1バイト配列> ::= 変数名 : <式> )
変数の値 + 式の値 のアドレスの内容を値とする.
<定数> ::= <10進定数> | <16進定数> | <文字定数>
<変数> ::= <変数名> | <1バイト配列> | <2バイト配列>
<式> ::= <項> | <項> <二項演算子> <項>
<項> ::= <定数> | <変数> | <配列> |( <式> )| <単項演算子> <項> | $ | ?
$ は一文字入力、? は数値入力
<二項演算子> ::= + | - | * | / | = | <> | < | > | <= | >=
比較演算 は 真:1, 偽:0の値を取る.
<単項演算子> ::= - | + | % | ' | #
+ は絶対値, % は直前に実行した除算の余り,
' は乱数, #は否定.
<行> ::= <行番号> スペース <文> [ 空白 <文> ] 改行
| <行番号> スペース以外の文字 コメント 改行
<文>
*AB オプショナルコマンド この場合はABというコマンド
<変数>=<式> 変数への代入
#=<式> <式>の値の行番号の文にジャンプ(GOTO)
式の行番号がなければsより大きい最初の行へジャンプ
#=-1 プログラムの終了(END)
!=<式> <式>の値の行番号のサブルーチンへジャンプ(GOSUB)
] サブルーチンから戻る(RETURN)
;=<式> 式の値が真の場合は次の文に進み,
偽の場合は次の行を実行.
@ DO
@=(式) UNTIL
変数=初期値,終値 FOR
@=式 NEXT
/ 改行出力
"文字列" 文字列出力
?=<式> <式>の結果を数値出力 左詰め
??=<式> <式>の結果を数値出力 16進4桁
?$=<式> <式>の結果の下位1バイトを数値出力 16進2桁
?(n)=<式> <式>の値の数値出力 n桁で右詰め
$=<式> <式>の値の下位バイトを文字コードとする1文字を出力
.=<式> <式>の値の下位バイトの数だけ空白を出力
'=<式> <式>の値で乱数シードを設定
GAME言語についてはこのサイトが詳しいようです。
GAME言語コンパイラ
本体 'gamec.c'
サンプルプログラム
test1
#!/usr/bin/gamelinux
10"***comment ***"
100 "line 100 running " !=10000
110 "line 110 running " !=10000
120 "line 120 running " !=10000
130 "line 130 running " !=10000
9990 "end" /// #=-1
10000 "sub "
10010 A=1,10 ?=A " " @=a+1 /
11000 ]
サンプルプログラム実行結果
line 100 running sub 1 2 3 4 5 6 7 8 9 10
line 110 running sub 1 2 3 4 5 6 7 8 9 10
line 120 running sub 1 2 3 4 5 6 7 8 9 10
line 130 running sub 1 2 3 4 5 6 7 8 9 10
end