text0010
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* 川合のプログラミング言語自作のためのテキスト第二版#0001
-(by [[K]], 2019.06.29)
** (1) はじめに
-「プログラミング言語を作ってみたい」と思ったことがある人...
-おそらくは、多く人にとってプログラミング言語を作るのは難...
-私はプログラミング言語は(世間の人が思っているよりは)ず...
-この時点では「本当にプログラミング言語を作るのは簡単なの...
----
-このシリーズが主張していること:
--''[1] プログラミング言語を作るのは難しくない!''
--''[2] JITコンパイラはとても高速。しかも難しくない!''
--''[3] うまくライブラリを作ると、有用な言語を自作するの...
----
-1億回ループでのベンチマーク
|言語処理系|行数|タイプ|説明|実行時間(gccの-O3を1.00とし...
|TL-3c|119行|単純インタプリタ|代入・加算・減算・print・wh...
|TL-3d|123行|単純インタプリタ|TL-3cを高速化したもの|RIGHT...
|TJ-03a|185行|JITコンパイラ|TL-3dをJITコンパイラ化したも...
|TJ-03b|224行|JITコンパイラ|TJ-03aにレジスタ変数を追加し...
|TJ-03c|247行|JITコンパイラ|TJ-03bにdo~whileを追加して高...
--JITコンパイラ(註:JITコンパイラはインタプリタ実行のた...
----
-ライブラリの威力
|言語処理系|行数|削減率|実行時間(gccの-O3を1.00としての...
|TL-1k(TL-1c相当)|RIGHT:52行→''31行''|40.4%削減||[[text...
|TL-2k(TL-2c相当)|104行→''31行''|70.2%削減||[[text0018]]|
|TL-3k(TL-3d相当)|123行→''45行''|63.4%削減|RIGHT:46.00...
|TJ-03x(TJ-03a相当)|185行→''61行''|67.0%削減|RIGHT:6.78...
|TJ-03y(TJ-03b相当)|224行→''78行''|65.2%削減|RIGHT:1.70...
|TJ-03z(TJ-03c相当)|247行→''88行''|64.3%削減|RIGHT:1.00...
--仮に言語を自作としたとして「私の自作言語を使うことで、...
--一般にライブラリを作るのは言語を作るよりもずっと楽です...
--ちなみにJITコンパイラが100行未満で作れちゃうのは、「か...
** (2) インタプリタかコンパイラか
-プログラミング言語は、大きく分けるとインタプリタ型とコン...
-一方でインタプリタ型は、ソースコードを実行前にコンパイル...
-こう書くとなんだかコンパイラ型がとてもよさそうに思えます...
-eval命令というのは、プログラムの中で "i = 3;"みたいな文...
-eval命令はそんなに重要でしょうか?・・・その話をする前に...
-どうしてそんな魔法みたいなことができるのかと言えば、つま...
-ここで既存のプログラミング言語で新しいJITコンパイラを作...
-evalがない言語でJITコンパイラを書こうと思ったら、機械語...
-そして今まではインタプリタは遅いとバカにされてきましたが...
-いろいろ書きましたが、つまり川合はJITコンパイラで作った...
--コンパイラは好きじゃないとか言いつつ、組み込み向けとか...
--要するにここで作り方を説明していないことに対するいいわ...
** (3) TL-1c
-うざい説明はこれくらいにして、とにかく言語を作ってみよう...
#include <stdio.h>
#include <stdlib.h>
void loadText(int argc, const char **argv, unsigned char...
{
FILE *fp;
int i;
if (argc < 2) { // 引数が少ないのでエラー表示して終...
printf("usage>%s program-file\n", argv[0]);
exit(1);
}
fp = fopen(argv[1], "rt"); // テキストモードでファイ...
if (fp == 0) { // ファイルを開けなかった.
printf("fopen error : %s\n", argv[1]);
exit(1);
}
i = fread(t, 1, siz - 1, fp);
fclose(fp);
t[i] = 0; // 終端マークを書いておく.
}
int main(int argc, const char **argv)
{
unsigned char txt[10000]; // ソースコード.
int i, pc, var[256]; // varは変数.
loadText(argc, argv, txt, 10000);
for (i = 0; i < 10; i++)
var['0' + i] = i; // テクニック#1.
for (pc = 0; txt[pc] != 0; pc++) {
if (txt[pc] == '\n' || txt[pc] == ' ' || 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[tx...
} else if (txt[pc + 3] == '-' && txt[pc + 5]...
var[txt[pc]] = var[txt[pc + 2]] - var[tx...
} else
goto err;
} else if (txt[pc] == 'p' && txt[pc + 1] == 'r' ...
printf("%d\n", var[txt[pc + 6]]);
} else
goto err;
while (txt[pc] != ';')
pc++;
}
exit(0);
err:
printf("syntax error : %.10s\n", &txt[pc]);
exit(1);
}
-はいこれだけです。C言語でたったの''52行''です。もちろん...
--変数名は半角一文字のみ。
--数値定数は整数で一桁のみ。
--「a=3;」みたいにスペースを入れずに書かなければいけない。
--ひとまず足し算と引き算とprintができればいい。
-ええ本当にひどい仕様だと思います。・・・かつてのタイニー...
-しかも<stdio.h>と<stdlib.h>しか使っていません。それでも5...
-このTL-1cは以下のプログラムを問題なく実行する能力があり...
a=1;
b=2;
c=a+b;
print c;
-今は足し算と引き算しかないですが、掛け算や割り算を追加す...
-この先で、最初に課した制約を少しずつ減らしていきます。い...
** (4) TL-1cの簡単な説明
-関数:
--loadText() : コマンドライン引数で指定されたソースファイ...
--main() : 言語処理の本体。
-変数:
--var[] : 変数の値を記憶しておくための変数。
--txt[] : ソースコードを記憶しておくための変数。
--pc : 現在プログラムのどこを実行しているのかを記憶するた...
-プログラム中で「テクニック#1」と書かれた部分があります。...
--こうすることで、プログラムでは以降変数と定数を区別する...
-C言語での文字列の扱いに不慣れな人のために、簡単な説明ペ...
-[隠れたこだわり]
--このTL-1cやそれ以降のプログラムは、C言語が得意じゃない...
--ポインタはやむをえないときは使ってもいいが、ポインタに...
--文字列を扱うときは極力標準関数で扱える形式にする。
** 次回に続く
-次回: [[text0011]]
*こめんと欄
-(2)の内容について、コンパイラが上級者向けで、インタプリ...
#comment
終了行:
* 川合のプログラミング言語自作のためのテキスト第二版#0001
-(by [[K]], 2019.06.29)
** (1) はじめに
-「プログラミング言語を作ってみたい」と思ったことがある人...
-おそらくは、多く人にとってプログラミング言語を作るのは難...
-私はプログラミング言語は(世間の人が思っているよりは)ず...
-この時点では「本当にプログラミング言語を作るのは簡単なの...
----
-このシリーズが主張していること:
--''[1] プログラミング言語を作るのは難しくない!''
--''[2] JITコンパイラはとても高速。しかも難しくない!''
--''[3] うまくライブラリを作ると、有用な言語を自作するの...
----
-1億回ループでのベンチマーク
|言語処理系|行数|タイプ|説明|実行時間(gccの-O3を1.00とし...
|TL-3c|119行|単純インタプリタ|代入・加算・減算・print・wh...
|TL-3d|123行|単純インタプリタ|TL-3cを高速化したもの|RIGHT...
|TJ-03a|185行|JITコンパイラ|TL-3dをJITコンパイラ化したも...
|TJ-03b|224行|JITコンパイラ|TJ-03aにレジスタ変数を追加し...
|TJ-03c|247行|JITコンパイラ|TJ-03bにdo~whileを追加して高...
--JITコンパイラ(註:JITコンパイラはインタプリタ実行のた...
----
-ライブラリの威力
|言語処理系|行数|削減率|実行時間(gccの-O3を1.00としての...
|TL-1k(TL-1c相当)|RIGHT:52行→''31行''|40.4%削減||[[text...
|TL-2k(TL-2c相当)|104行→''31行''|70.2%削減||[[text0018]]|
|TL-3k(TL-3d相当)|123行→''45行''|63.4%削減|RIGHT:46.00...
|TJ-03x(TJ-03a相当)|185行→''61行''|67.0%削減|RIGHT:6.78...
|TJ-03y(TJ-03b相当)|224行→''78行''|65.2%削減|RIGHT:1.70...
|TJ-03z(TJ-03c相当)|247行→''88行''|64.3%削減|RIGHT:1.00...
--仮に言語を自作としたとして「私の自作言語を使うことで、...
--一般にライブラリを作るのは言語を作るよりもずっと楽です...
--ちなみにJITコンパイラが100行未満で作れちゃうのは、「か...
** (2) インタプリタかコンパイラか
-プログラミング言語は、大きく分けるとインタプリタ型とコン...
-一方でインタプリタ型は、ソースコードを実行前にコンパイル...
-こう書くとなんだかコンパイラ型がとてもよさそうに思えます...
-eval命令というのは、プログラムの中で "i = 3;"みたいな文...
-eval命令はそんなに重要でしょうか?・・・その話をする前に...
-どうしてそんな魔法みたいなことができるのかと言えば、つま...
-ここで既存のプログラミング言語で新しいJITコンパイラを作...
-evalがない言語でJITコンパイラを書こうと思ったら、機械語...
-そして今まではインタプリタは遅いとバカにされてきましたが...
-いろいろ書きましたが、つまり川合はJITコンパイラで作った...
--コンパイラは好きじゃないとか言いつつ、組み込み向けとか...
--要するにここで作り方を説明していないことに対するいいわ...
** (3) TL-1c
-うざい説明はこれくらいにして、とにかく言語を作ってみよう...
#include <stdio.h>
#include <stdlib.h>
void loadText(int argc, const char **argv, unsigned char...
{
FILE *fp;
int i;
if (argc < 2) { // 引数が少ないのでエラー表示して終...
printf("usage>%s program-file\n", argv[0]);
exit(1);
}
fp = fopen(argv[1], "rt"); // テキストモードでファイ...
if (fp == 0) { // ファイルを開けなかった.
printf("fopen error : %s\n", argv[1]);
exit(1);
}
i = fread(t, 1, siz - 1, fp);
fclose(fp);
t[i] = 0; // 終端マークを書いておく.
}
int main(int argc, const char **argv)
{
unsigned char txt[10000]; // ソースコード.
int i, pc, var[256]; // varは変数.
loadText(argc, argv, txt, 10000);
for (i = 0; i < 10; i++)
var['0' + i] = i; // テクニック#1.
for (pc = 0; txt[pc] != 0; pc++) {
if (txt[pc] == '\n' || txt[pc] == ' ' || 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[tx...
} else if (txt[pc + 3] == '-' && txt[pc + 5]...
var[txt[pc]] = var[txt[pc + 2]] - var[tx...
} else
goto err;
} else if (txt[pc] == 'p' && txt[pc + 1] == 'r' ...
printf("%d\n", var[txt[pc + 6]]);
} else
goto err;
while (txt[pc] != ';')
pc++;
}
exit(0);
err:
printf("syntax error : %.10s\n", &txt[pc]);
exit(1);
}
-はいこれだけです。C言語でたったの''52行''です。もちろん...
--変数名は半角一文字のみ。
--数値定数は整数で一桁のみ。
--「a=3;」みたいにスペースを入れずに書かなければいけない。
--ひとまず足し算と引き算とprintができればいい。
-ええ本当にひどい仕様だと思います。・・・かつてのタイニー...
-しかも<stdio.h>と<stdlib.h>しか使っていません。それでも5...
-このTL-1cは以下のプログラムを問題なく実行する能力があり...
a=1;
b=2;
c=a+b;
print c;
-今は足し算と引き算しかないですが、掛け算や割り算を追加す...
-この先で、最初に課した制約を少しずつ減らしていきます。い...
** (4) TL-1cの簡単な説明
-関数:
--loadText() : コマンドライン引数で指定されたソースファイ...
--main() : 言語処理の本体。
-変数:
--var[] : 変数の値を記憶しておくための変数。
--txt[] : ソースコードを記憶しておくための変数。
--pc : 現在プログラムのどこを実行しているのかを記憶するた...
-プログラム中で「テクニック#1」と書かれた部分があります。...
--こうすることで、プログラムでは以降変数と定数を区別する...
-C言語での文字列の扱いに不慣れな人のために、簡単な説明ペ...
-[隠れたこだわり]
--このTL-1cやそれ以降のプログラムは、C言語が得意じゃない...
--ポインタはやむをえないときは使ってもいいが、ポインタに...
--文字列を扱うときは極力標準関数で扱える形式にする。
** 次回に続く
-次回: [[text0011]]
*こめんと欄
-(2)の内容について、コンパイラが上級者向けで、インタプリ...
#comment
ページ名: