言語作り日記1
静的型付けスクリプト言語 Metro を作る毎日です。
https://github.com/sutoru/metro
・字句解析
これに関してはもう完全にお手の物。(?)
std::list<Token> とかってする必要はなくて、Token* Token::next を用意しておけばいいだけ。必要であれば back も用意すればいいし。
なぜかっていうのは特に無いんだけど、強いて言うなら std::list<T>::iterator とか使わなくて済むし、なんてったって生ポインタを操作するわけだから、高速。
std::list を使っても高速ではあるんだけど、「塵も積もれば山となる」という考え方が俺のプログラミング。
ここでいうチリっていうのは、「ポインタと std::list の速度の差」です。
こんなの、ほんとにただのチリでしかない。もうまじで切った爪より目立たないくらいだと思う。でも、ありそうではあるじゃん・・・?(実際に計測してないのでわからないけどw)
だからもう半分こだわりとか思い込みとかそういうのもあるかもしれない。
でもそれでもし困ったことがあっても困るのは作る側だし。
「だからいいよね」っていうスタイル。
まーもちろん、この考え方のせいで GDB を使うことになったり、alart; とか printf(... とかめちゃくちゃ書きまくったりすることはある。
ただ、あくまでもこれは「開発者側の苦労」である。「ユーザー」が気にすることではないし、よほど非現実的でない限りは、デバッグにかかる時間は全然気にしない。
(まあイライラすることはあるけども。。。w)
この考え方は同じく C++ をやってる友達からいろいろと・・・おっと、長いのでこれは後で話すとしよう。
・構文解析
これはもう、しばらく前から「ほんとにただ単純に ”構文解析” 以外はしない!」っていうやり方で作ってます。
たとえば以下のスクリプトね。
let a = let b + { xx - loop { 1; } };
これ、まず変数 b を定義する場所があまりにもおかしいんだけど、つまり何が言いたいのかって言うと、「構文は正しい」っていうことなんです。
ほんとに、ただひたすら、構文解析以外は何も余計なことをしない。
・Evaluater
日本語でどうやって書くんだろうこれ。
こいつの仕事内容としては、「構文の意味や場所 (?) が適切かどうか、正しいかどうかを確認する」というものです。
だからさっきの let a = let b = ... っていう AST は、この段階に来てエラーになります。
いつから自作言語に Evaluater を導入したのかは覚えてないけど、概念とか考え方はもうだいぶ前からできていた。
しっかり作ることができて満足。
・run_node
構文木を実行します。
いろんな枝やら葉やらを、あちこちにぐるぐる、ぐーるぐる、行ったり来たり、、、そういうやつです。
まあこれはちょっと賛否両論あるだろうね。
だって、まずこれ「自作言語に goto を導入しよう!」とかっていうのが通用しないもん。
内部でも実際に再帰処理を使ってるわけだし、愚直にそのまま実装してる。(ソースコードはここを参照のこと
https://github.com/sutoru/metro/blob/main/run_node.cc )
ただ、内部で独自のアセンブリ言語的なものを生成するよりも、だいぶ楽なんですよね。だからこうしてる。
というか「goto を導入したい!」ってまずなくね?w
「try-catch を導入したい!」ならまだわかるけど、「じゃあ AST インタプリタでもできるように別の形で実現しよう」って俺ならする。
てか実際に try-catch を一回導入しようとしたことあったけどねw
つーわけで、困ることってそんなに無いんですよね。
おそらくスタックマシンぽいことにはなるけども、プログラミングがしやすいから、run_node でやってます。
・僕のプログラミングについて(おまけ)
もう 90% くらいは Rui Ueyama 先生の影響を受けています。
#include "metro.h" というのも mold のソースを見て知ったやり方だし、make -j を使えば一瞬でコンパイルできる。
metro.h にはおそらく標準ライブラリヘッダのインクルードが 15 行以上?はあると思うけど、余裕。全く問題ない。
それに、あんまクラスも使わない。構造体はよく使うけど、関数はほとんどグローバル。
なんなら、metro.h にはグローバル変数の extern 宣言があるっていうくらいだし。
楽ちんでいいわ〜。。
・・・はい、ここです。やっとです。「長いからあとにしよう」って最初の方で言いましたよね?
まじでこれなんですよ。
#include "プロジェクト名.h" っていうやり方はなぜかめっちゃ嫌われている。
「実際に半年以上それでやってから言えよ?!」って言いたいね。
まあこれだけじゃなくて、グローバル関数とか変数とかが批判されたり自分はあったけど、そういうのを批判するやつは「デバッグ能力」がゴミカスなんです。
結構これガチだと思ってる。自分の書いたコードを把握できていないがゆえに保険をかけまくったプログラミングをずっとあいつらはしてるわけだし。
gdb 使え!
alart マクロも使え!
printf たくさん挿入しろ!
はい。もうここまでにしとこう、なんか言われたら面倒なので()