* 川合のプログラミング言語自作のためのテキスト第二版#0008
-(by [[K]], 2019.06.30)
** (15) TL-1k
-ここからの話題は単に言語を作るという話ではなく、ライブラリを開発することでいかにプログラミングが変わって生産性が向上するかという話を書きます。
-ここからはC言語ではなくC++を使いますが、C++固有の難しいことはほとんど利用しないので心配はいりません。
-以下に示すプログラムは、TL-1cを川合の自作ライブラリ kll0 を使って書き直したものです。
-kll0 はまだ公開していないので、以下のプログラムを簡単に試すことはできないのですが、しかしライブラリをどういう方針で作ったのかは伝わるはずです。
#include "kll0.h"
int main(int argc, const char **argv)
{
int i, pc = 0, var[256]; // 変数.
unsigned char *txt = (unsigned char *) kerrorExitP0(kreadFileA(argv[1], "rt", 2), "usage>%s program-file", argv[0]);
for (i = 0; i < 10; i++)
var['0' + i] = i;
for (; txt[pc] != 0; pc++) {
if (txt[pc] == '\n' || txt[pc] == ' ' || txt[pc] == '\t' || txt[pc] == ';') // 空行など.
continue;
if (txt[pc + 1] == '=') { // 2文字目が"=".
if (txt[pc + 3] == ';') { // 単純代入.
var[txt[pc]] = var[txt[pc + 2]];
} else if (txt[pc + 3] == '+' && txt[pc + 5] == ';') { // 加算.
var[txt[pc]] = var[txt[pc + 2]] + var[txt[pc + 4]];
} else if (txt[pc + 3] == '-' && txt[pc + 5] == ';') { // 減算.
var[txt[pc]] = var[txt[pc + 2]] - var[txt[pc + 4]];
} else
goto err;
} else if (txt[pc] == 'p' && txt[pc + 1] == 'r' && txt[pc + 5] == ' ' && txt[pc + 7] == ';') { // 最初の2文字しか調べてない(手抜き).
printf("%d\n", var[txt[pc + 6]]);
} else
goto err;
while (txt[pc] != ';')
pc++;
}
exit(0); // ファイル終端.
err:
kerrorExit("syntax error : %.30s", &txt[pc]);
}
-TL-1c(参照:[[text0010]])と比較すると、最初のloadText()の部分がなくなっているだけで、あとはおおむねそのままです。
-kll0 は、言語開発を支援することを目指したライブラリで、言語そのものの部分にはタッチしません。そこが普通の言語系のライブラリとは違います。
-支援が充実しているおかげで、言語そのものの記述に集中できる感じです。本質だけを書けばいい、という感じです。
-void *kreadFileA(char *path, char *mode1, int mode2)
--ファイルをオープンしてメモリに読み込みます。mode1はfopenに渡すためのモードで、mode2はそのほかのオプションです。メモリはファイルを読み込むのに必要な量を自動で確保します。
--mode2= 1:fopenでエラーが生じたら、適当なエラーメッセージを出力して終了する。 2:メモリ読み込んだ後、末尾に 0 を付与する。
--mode2で1が指定されていないのにfopenがエラーになった場合は、ファイル読み込みはしないで、ヌルポインタを返します。
--なおkreadFileが確保したメモリはmain()から抜ける時に自動で解放されるので、ユーザは解放のことを気にする必要はありません。
-void kerrorExit(char *s, ...)
--文字列をstderrにprintfした後、exit(1)します。そんなのライブラリを使うほどのことなのかと思うわけですが、2行を1行にすることができるわけで、そういう些細なところから支援していくのが kll0 の考え方です。
-void *kerrorExitP0(void *p, char *s, ...)
--もしpが0であれば、s以降を使ってkerrorExit()します。もしpが0でなければ、kerrorExitはしないでpの値をそのまま返します。
--これだってif文を一つ書けば済むことなのでありますが、少しでも楽をするために用意されています。
-こうしてTL-1kは31行で書けているわけです。
** 次回に続く
-次回: [[text0018]]
*こめんと欄
#comment