* ここまでの開発速度について -(by [[K]], 2026.02.11) ** (1) -2026.01.23(金) - [[a4_0001]] - 60行 -2026.01.24(土) - [[a4_0002]] - 160行 -2026.01.28(水) - [[a4_0003]] - 95行 -2026.01.28(水) - [[a4_0004]] - 120行 -2026.01.30(金) - [[a4_0005]] - 112行 -2026.02.02(月) - [[a4_0006]] - 174行 -2026.02.02(月) - [[a4_0007]] - 93行 -2026.02.03(火) - [[a4_0008]] - 92行 -2026.02.04(水) - [[a4_0009]] - 229行 -2026.02.06(金) - [[a4_0010]] - 133行 -2026.02.11(水) - [[a4_0011]] - 124行 -2026.02.11(水) - [[a4_0012]] - 164行 -2026.02.11(水) - [[a4_0013]] - 174行 -20日間で合計1730行 -a4_0001~0010はほぼ一定速度で書いていて、そこから少し止まって一気に02.11(水)に書いたように見えるかもしれませんが、実際はそうではありません。 -a4_0011~0013は適当なサンプルコードが書けないせいで充分にテストできなくて、それで公開を保留にしていたのです。 -a4_0013までできて、やっとテストができるようになって、それで一気にためていた分を公開することになったのです。 -20日間の中には、もちろん忙しくて開発どころではなかった日もあります。それも勘案すれば、まあ1日当たり100行程度でしょうか。 -これはライブラリがどのくらいの速さで大きくなったのかを測ったもので、ライブラリ以外のサンプルコードやテストコードについては、行数に含まれていません。 -上記の1730行のうち、a4_0001~0008の906行(12日間)は一般的な用途に使える関数群で、a4_0009~a4_0013の824行(8日間)がプリプロセッサを構成する関数群です。 -ということで、いい感じにライブラリ自作をやっておけば、プリプロセッサは850行くらいで作れてしまうというわけです。 -(実は昨年もプリプロセッサを作っています。その時は500行未満で書けましたが、#lineや__LINE__などには対応できていませんでしたし、 #.def / #.undef などもサポートしていませんでした。) -ライブラリ駆動開発ってなかなかいい方法だっていうことが、うまく伝わりますように・・・。 ** (2) -acl4ライブラリは、最初は malloc/free を安全にするための仕組みから作り始めました([[a4_0002]])。 --こんなところから作るのは遠回りで、さっさと必要なところから作り始めるべきだったかもしれないと思いつつ、しかし最初に作っておけば、あとでデバッグが楽になるかもしれないと思って、ここから始めることにしたのです。 -次に作ったのは VecChr つまり vector<char> もどきを作ることでした([[a4_0003]]~[[a4_0004]])。 --可変長配列があれば、バッファファイズが足りなくなるかもしれないと心配しなくてよくなりますし、「もし足りなくなったらエラー」みたいな記述もしなくてよくなるので、早くほしいなと思っていたのです。 -その次には Set0 つまり連想記憶の仕組みを作りました([[a4_0005]])。 --ソート済みの配列を維持して、二分探索で探すだけのものなので、追加や削除はあまり速くないのです。検索は十分に速いです。 --でも大事なのは速度よりもこの先の開発でシンプルに書けるようになることなので、そこは割り切って書きました。 -次は Token1_get を作りました([[a4_0006]])。 --とりあえず最初は何らかの言語を作りたいなと思っていました。それならば、まあどんな言語を作るにしても、ソースコードをトークンに切り分ける処理は必要だろうと思い、今作っておけば無駄にはならないだろう、くらいに思っていました。 -次は parseArgs などの雑関数を作りました([[a4_0007]])。 --VecChr_replace → 文字列の一部を別の文字列に置き換えるというただそれだけの関数で、関数はたったの4行でしかないのですが、これがとても便利で、のちに多用することになりました。 ---置換元の文字長を0にすれば挿入に使えるし、置換先の文字長を0にすれば部分削除にも使えるし、文字列全体を置換対象にすればただの上書きとしても使えます。 ---もちろん可変長配列の大きさを調整してから memcpy/memmove すれば、こんな関数はなくてもいいのですが、でもそれを1文でできるというのが便利ポイントでした。 ---こういう些細な関数が大事だとしみじみ思いました。 --VecChr_gets → VecChrに一気にファイル全体を読み込んだ後、1行ごとに切り出すためには fgets みたいな関数があったらいいなと思って付けました。 --VecChr_puts → getsがあるならputsも必要だろうと思って付けました。 --Set0_findKn → Set0 で検索するために要素オブジェクトを作るのが面倒に感じてきたので、キーだけ渡せば検索できるようにしたものです。 --parseArgs → 言語処理系を考えるとき、かっこでくくられたコンマ区切りの引数リストを適当にパースして、引数は全部でいくつあったか、i番目の引数はどこにあるのか、みたいなことを返すだけの関数です。 ---なんかこう書くと難しそうに聞こえるのですが、ただかっこのネストを数えながらテキストを読んでいき、コンマとかっこ閉じが来るたびにその位置を記録しているだけです。36行程度の簡単な処理です。 -ここまで作って、「 Set0 と parseArgs があれば、プリプロセッサの #define くらいは作れるんじゃないか?」と思って、試しに少し書いてみました([[a4_p0001]])。 --183行でそれっぽいことができたので、おおこれはいいなと思いました。 -一般に言語を作るときは、適当なテキストファイルにテスト用のコードを書いて、それを読み込ませてテスト実行をします。 --それで5行程度の短いテキストファイルをたくさん作ることになるのですが、実にうっとうしいです。 --そんなことをしなくてもいいように、コマンドラインでファイル内容を記述できる仕組みを考えました([[a4_0008]])。 -言語と言えば「式の評価」だよなーとなんとなく思って、試しに書いてみました([[a4_p0002]])。 --たった45行で式の評価は書けたので、これいいなと思いました。 -これで #if の式の評価もできそうだと思ったので、以降はプリプロセッサ処理を書いていくことになりました([[a4_0009]]~[[a4_0013]])。 -これで #if の式の評価もできそうだと思ったので、以降は残りのプリプロセッサ処理を書いていくことになりました([[a4_0009]]~[[a4_0013]])。 --このころから、 malloc/free のチェック機構に助けられるようになって、作っておいてよかったなと思いました。 --VecChr や Set0 も多用しています。 * こめんと欄 #comment