a4_log
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* acl4の開発ログ
-(by [[K]], 2026.03.14)
-''acl4開発のもくじ → [[a4_i01]]''
-開発ログの過去ログのもくじ → [[a4_log00]]
-最近の過去ログ:
//-[[a4_log08]](2026.03.14(土)#0~2026.03.17(火)#2): プリ...
-[[a4_log09]](2026.03.18(水)#0~2026.03.26(木)#5): 有理数...
-[[a4_log10]](2026.03.27(金)#0~2026.04.10(金)#3): プリプ...
-[[a4_log11]](2026.04.11(土)#0~2026.04.18(土)#0): acl4 →...
** 2026.04.20(月) #0
-mallocでメモリを確保したり、reallocでメモリを拡張したり...
-とりあえず簡単のためにmemset()で塗りつぶすことにして、で...
--0x00: これで塗りつぶすと明らかに「何も書いてない」感じ...
--0xff: 0x00が一番きれいなのだとしたら、じゃあ一番汚いの...
--0x80: では符号付きの整数で、0x00から最も遠い値にしたら...
--0x87: それでは、この1バイトの中の「0」のビットと「1」の...
** 2026.04.20(月) #1
-acl4v1でもdefine機能が使えるようになりました。でもまだty...
** 2026.04.20(月) #2
-なんか最近このwikiが不安定な気がします。よしxreaからcore...
** 2026.04.21(火) #0
-ほかのドメインで練習中です。
** 2026.04.21(火) #1
-移行できたと思います。無事に安定して表示できるといいなあ。
** 2026.04.21(火) #2
-さっきバグって、ポインタが変な値になっていました。当然、...
-・・・うお、いきなりこれかー(笑)。つまり初期化してない...
-ということで30秒くらい、くくく・・・と笑ってしまいました。
-[註] 2026.04.20(月)#0 で自分が仕掛けたバグ発見用のトラッ...
-いや、これに限らず、私は毎日何度も自分の仕込んだデバッグ...
-まあなんとも情けないわけですが、でもそのうちの多くはデバ...
-ただなんというか、私のデバッグトラップたちが優秀すぎて(...
-ありがたい!! acl4 は私に合っている!!
** 2026.04.22(水) #0
-a4_0001~a4_0014のリファクタリングが完了しました。次はミ...
** 2026.04.24(金) #0
-やっと、何を作ったらプリプロセッサの良さが伝わるかが分か...
** 2026.04.25(土) #0
-できました!
--[[a4_p0007]]: プリプロセッサ処理をする関数を作ったら、...
-[[a4_i01]]のページを改装中です。
** 2026.04.26(日) #0
-[[a4_0016]]~[[a4_0023]]と[[a4_t0002]]のページを作りまし...
-これで acl4v1 は旧 acl4 に追いつきました。
** 2026.04.27(月) #0
-[[a4_p0007]]のページにダウンロード用のzipファイルを追加...
-x86-32でコンパイルしないと、35.0KBにはなりません。あと /...
-さて、次にやるべきは配列変数のサポートです。配列変数が使...
-とにかくこの「プリプロセッサで置換する方式」でどこまで行...
** 2026.04.28(火) #0
-[[a4_t0002]] は Windows 専用になっていますが、かつて X11...
--[[a24_raspberrypi01]], [[a24_raspberrypi02]]
** 2026.04.30(木) #0
-考えがうまくまとまらないので、とりあえずシンプルにやりま...
-たぶん設計がまとまらないのは、それを設計するだけの知識が...
** 2026.05.01(金) #0
-A4vm_eval0()のEnter命令の仕様:
-Ent_III(i, j, k)
--i: 整数レジスタ数, j: 浮動小数点数レジスタ数, k: 関数呼...
-今回追加する引数:
-Ent_IIIII(i, j, k, l, m)
--l: ポインタレジスタ数, m: スタック変数のための領域サイズ
** 2026.05.01(金) #1
-そうかー! 構造体をどうしたらいいかなって考えるよりも先...
-もしうまくできたら、「これでもう将来どんなCPUが主流にな...
** 2026.05.01(金) #2
-これが動くようになりました!
>p0008a "src:inline: DB(0x68); DD(\"hello\\n\"); DB(0xe8...
-PUSH(imm32)の機械語を 6A だと誤解して、それに気づかなく...
** 2026.05.01(金) #3
-こう書けるようになりました。これで機械語を間違えるバグは...
>p0008a "src:inline: PUSH_I(\"hello\\n\"); CALL_I(printf...
-これが機械語になってすぐに動くので、「JITアセンブラ」と...
-ちなみに p0008a.c は50行のプログラムです。50行でJITアセ...
** 2026.05.01(金) #4
-まだ printf しかできないですが、とにかくJITコンパイラは...
-[追記] その後、for文もできました。簡単すぎて楽しいです。
-[追記] さらに1時間くらいやったら、 p0007h.txt が動くくら...
-やっぱりプリプロセッサは偉大だなあー。
** 2026.05.03(日) #0
-今、 p0008a.c っていうJITコンパイラを作っているのですが...
-そのアセンブラ部分は、 #define RET() DB(0xC3) みたいな...
-でもなあ、複数の引数をサポートするのは面倒だよなあ、まあ...
-でもさっき、思いつきました。あれ?もしかして、 #define D...
-その通りでした。こうして DB() 命令は複数の引数に対応でき...
-こんなに楽していいのかな?(笑)
-上記で、平気なふりして「#define を50行くらい書くだけで、...
-まあ進歩ってそういうものですよね。
** 2026.05.04(月) #0
-この欄の 2026.04.04.11(土)#1 に、プリプロセッサだと、a,b...
#define c a+b
#define b 2
#define a 1
printf("%d\n", c);
-これに対して、printf()が最後にある必要はあるけど、それ以...
-今回プリプロセッサを改良したので、以下のような書き方でも...
printf("%d\n", c);
#define c a+b
#define b 2
#define a 1
-つまり私の自作プリプロセッサなら define は後出しじゃんけ...
** 2026.05.04(月) #1
-[[a4_t0003]] を書きました。現行のミニコンパイラを補助ラ...
-ちょっと実験したのでメモしておきます。
8.0KB : printf("hello, world\n"); のみの.exeファイル
23.5KB : p0008a.c で pp のみ(Mode=0)
28.0KB : p0008a.c で pp+cc (Mode=1)
30.0KB : p0008a.c で pp+cc+cjit (Mode=2)
35.5KB : p0008a.c で pp+cc+cjit+clang (Mode=3)
37.5KB : p0008a.c で pp+cc+cjit+clang+calc+graphic (Mod...
-pp(プリプロセッサ)は実質的には 15.5KB 。
-cc(Cコンパイラ)は pp+4.5KB (でも実装している機能が少...
-JITコンパイラは +2.0KB 程度。
-a4vm を入れると +5.5KB 程度。
-[[a4_t0002]]程度のグラフィック機能であれば +2.0KB 程度。
** 2026.05.04(月) #2
-[[a4_p0008]] を書きました。JITコンパイラを試せます。
** 2026.05.06(水) #0
-「新しい言語の作り方」という12ページのスライド資料をなん...
--https://essen.osask.jp/files/pr20260506a_acl4.pdf
--今のところ発表予定はありません。
--[追記] 資料を更新しました → https://essen.osask.jp/file...
** 2026.05.10(日) #0
-運よくプレゼン機会があったので、上記の「新しい言語の作り...
-好評でたくさんコメントをもらえたので、それを加筆したバー...
-ちなみにここで発表してきました。
--「第51回 自作OSもくもく発表作業会」 https://osdev-jp.c...
--(ここの発表枠5で)
** 2026.05.13(水) #0
-ここまでの開発を振り返っています。
-[1] 第1層([[a4_0016]])
--デバッグに便利な機能が付いた malloc/realloc/free を整備。
-[2] 第2層([[a4_0017]]~[[a4_0019]])
--第1層の成果を使って、vector<char> を参考にして作った Ve...
--さらにトークンを切り出す Token0/Token1 クラス、かっこで...
-[3] 第3層([[a4_0020]])
--第2層の成果を使って、式の評価クラスを整備。文字列で式を...
-[4] 第4層([[a4_0021]]~[[a4_0022]])
--第3層までの成果を使って、プリプロセッサ関数を整備。
-[5] 第5層([[a4_0023]]~)
--第4層で作ったプリプロセッサ関数を使って、アセンブラやC...
--JITコンパイラも難なく成功。ついでにa4vmという仮想マシン...
--概要 → https://essen.osask.jp/files/pr20260505b_acl4.pdf
--実装 → [[a4_p0008]]
-ということで、まずAを作り、そのAを利用してBを作り、そのB...
** 2026.05.16(土) #0
-何となく自分が納得できる程度の memmem() ができたのでここ...
-まず memmem() が何かというと strstr() の仲間みたいなもの...
--https://manpages.ubuntu.com/manpages/focal/ja/man3/memm...
-GNU拡張なので、標準の <string.h> には入っていません。私...
-普通に作っても面白くないので、ちょっとだけ工夫をして高速...
-説明用のバージョン:
a_static char *a_memmem0(const char *t, intptr_t tn, con...
{
if (pn <= 0) return (char *) t;
if (tn < pn) return NULL;
intptr_t i = pn - 1;
const char *t1 = t + tn - pn, c0 = p[0];
for (t--;;) {
nxt:
t = memchr(t + 1, c0, t1 - t);
if (t == NULL) return NULL;
if (t[i] == p[i]) {
for (i = 1; i < pn; i++) {
if (t[i] != p[i]) goto nxt;
}
return (char *) t;
}
}
}
--まず memchr() で0バイト目が一致している場所を見つけてき...
--全部比較するときに memcmp() を使えばいいし、比較だけな...
--普通、この手のストリング検索では、 Boyer–Moore の有名な...
--最初に t--; して、次に t+1 から memchr() するのは一見す...
-でもこのバージョンをそのまま使うと、 memchr() があまり速...
-ちゃんと高速化したバージョン:
a_static char *a_memmem(const char *t, intptr_t tn, cons...
{
if (pn <= 0) return (char *) t;
if (tn < pn) return NULL;
intptr_t i = pn - 1;
const char *t1 = t + tn - pn, *t16 = t1 - 16, c0 = p...
for (t--;;) {
nxt:
t++;
for (;;) {
if (t <= t16) {
if (t[0] == c0) goto t0;
if (t[1] == c0) goto t1;
if (t[2] == c0) goto t2;
if (t[3] == c0) goto t3;
if (t[4] == c0) goto t4;
if (t[5] == c0) goto t5;
if (t[6] == c0) goto t6;
if (t[7] == c0) goto t7;
if (t[8] == c0) goto t8;
if (t[9] == c0) goto t9;
if (t[10] == c0) goto t10;
if (t[11] == c0) goto t11;
if (t[12] == c0) goto t12;
if (t[13] == c0) goto t13;
if (t[14] == c0) goto t14;
if (t[15] == c0) goto t15;
t += 16;
continue;
}
if (t > t1) return NULL;
if (t[0] == c0) goto t0;
t++;
}
t15: t++;
t14: t++;
t13: t++;
t12: t += 12; goto t0;
t11: t++;
t10: t++;
t9: t++;
t8: t += 8; goto t0;
t7: t++;
t6: t++;
t5: t++;
t4: t += 4; goto t0;
t3: t++;
t2: t++;
t1: t++;
t0:
if (t[i] == p[i]) {
for (i = 1; i < pn; i++) {
if (t[i] != p[i]) goto nxt;
}
return (char *) t;
}
}
}
--さあ、久しぶりに「キモイい」プログラムになりました。
--この改造の趣旨は、とにかくtを加算したり、tnとの比較をし...
--それで一致した場所が見つかった場合は、tをその分だけ加算...
--やっていることはそれだけです。
-そしてお楽しみのベンチマークです。
-芸のないベンチマーク:
#include <acl4v1.c>
#include "t0003a.c" // ここにa_memmem()があります.
int main(void)
{
char *s = malloc(900 * 1024 * 1024); // 900MB.
int i, j = 0;
for (i = 0; i <= 100000000; i++) // とりあえず1億.
j += sprintf(s + j, "%d ", i);
printf("j=%d\n", j);
clock_t t0, t1, t2;
t0 = clock();
int rs = (int) strstr(s, " 100000000");
t1 = clock();
int rm = (int) a_memmem(s, j, " 100000000", 10);
t2 = clock();
printf("strstr=%x\n", rs);
printf("a_memmem=%x\n", rm);
printf("t1-t0=%d t2-t1=%d\n", t1-t0, t2-t1);
return 0;
}
--まあいろいろ雑ですが、とりあえずこれでもベンチマークに...
--3回やってみると、こんな感じでした。まあ標準関数のstrstr...
t1-t0=321 t2-t1=292
t1-t0=272 t2-t1=272
t1-t0=278 t2-t1=273
--ちなみに今回の malloc() は acl4 の malloc_() ではなく、...
-次に、 a_memmem() が少し有利になりそうなベンチマークです...
#include <acl4v1.c>
#include "t0003a.c"
int main(void)
{
char *s = malloc(140 * 1024 * 1024); // 140MB.
int i, j = 0;
for (i = 0; i <= 10000000; i++) // とりあえず100万.
j += sprintf(s + j, "count=%d ", i);
printf("j=%d\n", j);
clock_t t0, t1, t2;
t0 = clock();
int rs = (int) strstr(s, "count=10000000");
t1 = clock();
int rm = (int) a_memmem(s, j, "count=10000000", 14);
t2 = clock();
printf("strstr=%x\n", rs);
printf("a_memmem=%x\n", rm);
printf("t1-t0=%d t2-t1=%d\n", t1 - t0, t2 - t1);
return 0;
}
--3回やってみるとこんな感じでした。
t1-t0=101 t2-t1=46
t1-t0=96 t2-t1=45
t1-t0=97 t2-t1=42
--やったね!
** 2026.05.22(金) #0
-最近は、SecHack365の選考に忙殺されていて、acl4があまり進...
-あ、でも、昨日は buntan-pc のuchanさんと、CPUにこんな命...
-考えていた内容は、たとえば整数演算でゼロ割しても例外を起...
-この命令体系だとプログラミングのパラダイムが変わるかもし...
** 2026.05.26(火) #0
-hh4みたいな多倍長の形式について思索。
-4bitあれば 0000~1111 の16通りの表現があります。これをA...
-Bパターンが来たら、そこで終了です。これで 0~(b-1) を表...
-Aパターンが来たら、Bパターンが来るまで繰り返してから終了...
-hh4の単純形式の場合、a=b=8になっていて、だから 8/64/512....
-拡張形式として、10+6=16 みたいなものを考えることができま...
-表にしてみます。
|8+8=16型|8|64|512|4096|
|10+6=16型|6|60|600|6000|
|7+9=16型|9|63|441|3087|
|6+10=16型|10|60|360|2160|
|5+11=16型|11|55|275|1375|
|4+12=16型|12|48|192|768|
-この中だと4+12=16はかなり魅力的に見えます。
** 2026.05.27(水) #0
-[[a26_txt03]](川合のプログラミング言語自作のためのテキ...
** 2026.05.30(土) #0
-説明を平易にしようとすると、ポインタとかはあまり使えない...
-だから言い訳を考えているのですが、結局ライブラリは「どん...
** 2026.05.31(日) #0
-まあまあいいものができた予感!
** 2026.06.01(月) #0
-メモリ管理とかデバイス管理など、プログラミングでは〇〇管...
-ところが、ふと「なぜ私は Manager を Man と略すのだろうか...
-不安は的中します。Google検索で調べていたらGeminiに、プロ...
-Geminiのちょっと微妙な受け答えはともかくとして、Man派は...
-とまあ、それはそれでよいとして、ではなぜ私は今まで Man ...
-私が最初に学んだのは・・・OS-9/6809です。それで昔読んだ...
** 2026.06.01(月) #0
-[[a26_txt03_001]](川合のプログラミング言語自作のための...
-このログページの一部を切り出して[[a4_log11]]を作って、そ...
** 2026.06.02(火) #0
-「デバッグ支援機能はこれが最後です」なんて書いたら、「う...
** 2026.06.09(火) #0
-ここしばらく、SecHack365関係で気が散って、あまり進んでい...
** 2026.06.10(水) #0
-C言語の標準ライブラリのqsort()関数は、配列をソートできて...
-この目的のためにqsortを使う場合は、a[i]の値とiの値を構造...
int (*iqsor_cmpF)(void *, int, int);
void *iqsor_cmpW;
int iqsort_cmp(const void *a, const void *b)
{
int ai = *(const int *) a;
int bi = *(const int *) b;
return iqsor_cmpF(iqsor_cmpW, ai, bi);
}
void iqsort(int *a, int n, int (*cmpF)(void *, int, int)...
{
int i;
for (i = 0; i < n; i++)
a[i] = i;
iqsor_cmpF = cmpF;
iqsor_cmpW = cmpW;
qsort(a, n, sizeof (int), iqsort_cmp);
}
// ここからサンプルコード.
int cmp(void *w, int i, int j)
{
const char **s = w;
return strcmp(s[i], s[j]);
}
int main()
{
char *name[5] = { "Tanaka", "Yamada", "Kawai", "Sato...
int idx[5], i;
iqsort(idx, 5, cmp, name); // これで idx[] を得る.
for (i = 0; i < 5; i++) { printf("%d ", idx[i]); } p...
for (i = 0; i < 5; i++) { printf("%d: %s\n", i, name...
return 0;
}
-これを実行すると、以下のようになります。
2 3 4 0 1
0: Kawai
1: Sato
2: Suzuki
3: Tanaka
4: Yamada
-最初にidx[i]の値が表示されています。idx[0]は2なので、一...
-要点は、name[]は全く並べ替えられることなくそのままになっ...
-私はこの仕様のほうが使いやすいなーと思いました。
-いやその別に全然大したことはないのですが・・・。
* こめんと欄
#comment
終了行:
* acl4の開発ログ
-(by [[K]], 2026.03.14)
-''acl4開発のもくじ → [[a4_i01]]''
-開発ログの過去ログのもくじ → [[a4_log00]]
-最近の過去ログ:
//-[[a4_log08]](2026.03.14(土)#0~2026.03.17(火)#2): プリ...
-[[a4_log09]](2026.03.18(水)#0~2026.03.26(木)#5): 有理数...
-[[a4_log10]](2026.03.27(金)#0~2026.04.10(金)#3): プリプ...
-[[a4_log11]](2026.04.11(土)#0~2026.04.18(土)#0): acl4 →...
** 2026.04.20(月) #0
-mallocでメモリを確保したり、reallocでメモリを拡張したり...
-とりあえず簡単のためにmemset()で塗りつぶすことにして、で...
--0x00: これで塗りつぶすと明らかに「何も書いてない」感じ...
--0xff: 0x00が一番きれいなのだとしたら、じゃあ一番汚いの...
--0x80: では符号付きの整数で、0x00から最も遠い値にしたら...
--0x87: それでは、この1バイトの中の「0」のビットと「1」の...
** 2026.04.20(月) #1
-acl4v1でもdefine機能が使えるようになりました。でもまだty...
** 2026.04.20(月) #2
-なんか最近このwikiが不安定な気がします。よしxreaからcore...
** 2026.04.21(火) #0
-ほかのドメインで練習中です。
** 2026.04.21(火) #1
-移行できたと思います。無事に安定して表示できるといいなあ。
** 2026.04.21(火) #2
-さっきバグって、ポインタが変な値になっていました。当然、...
-・・・うお、いきなりこれかー(笑)。つまり初期化してない...
-ということで30秒くらい、くくく・・・と笑ってしまいました。
-[註] 2026.04.20(月)#0 で自分が仕掛けたバグ発見用のトラッ...
-いや、これに限らず、私は毎日何度も自分の仕込んだデバッグ...
-まあなんとも情けないわけですが、でもそのうちの多くはデバ...
-ただなんというか、私のデバッグトラップたちが優秀すぎて(...
-ありがたい!! acl4 は私に合っている!!
** 2026.04.22(水) #0
-a4_0001~a4_0014のリファクタリングが完了しました。次はミ...
** 2026.04.24(金) #0
-やっと、何を作ったらプリプロセッサの良さが伝わるかが分か...
** 2026.04.25(土) #0
-できました!
--[[a4_p0007]]: プリプロセッサ処理をする関数を作ったら、...
-[[a4_i01]]のページを改装中です。
** 2026.04.26(日) #0
-[[a4_0016]]~[[a4_0023]]と[[a4_t0002]]のページを作りまし...
-これで acl4v1 は旧 acl4 に追いつきました。
** 2026.04.27(月) #0
-[[a4_p0007]]のページにダウンロード用のzipファイルを追加...
-x86-32でコンパイルしないと、35.0KBにはなりません。あと /...
-さて、次にやるべきは配列変数のサポートです。配列変数が使...
-とにかくこの「プリプロセッサで置換する方式」でどこまで行...
** 2026.04.28(火) #0
-[[a4_t0002]] は Windows 専用になっていますが、かつて X11...
--[[a24_raspberrypi01]], [[a24_raspberrypi02]]
** 2026.04.30(木) #0
-考えがうまくまとまらないので、とりあえずシンプルにやりま...
-たぶん設計がまとまらないのは、それを設計するだけの知識が...
** 2026.05.01(金) #0
-A4vm_eval0()のEnter命令の仕様:
-Ent_III(i, j, k)
--i: 整数レジスタ数, j: 浮動小数点数レジスタ数, k: 関数呼...
-今回追加する引数:
-Ent_IIIII(i, j, k, l, m)
--l: ポインタレジスタ数, m: スタック変数のための領域サイズ
** 2026.05.01(金) #1
-そうかー! 構造体をどうしたらいいかなって考えるよりも先...
-もしうまくできたら、「これでもう将来どんなCPUが主流にな...
** 2026.05.01(金) #2
-これが動くようになりました!
>p0008a "src:inline: DB(0x68); DD(\"hello\\n\"); DB(0xe8...
-PUSH(imm32)の機械語を 6A だと誤解して、それに気づかなく...
** 2026.05.01(金) #3
-こう書けるようになりました。これで機械語を間違えるバグは...
>p0008a "src:inline: PUSH_I(\"hello\\n\"); CALL_I(printf...
-これが機械語になってすぐに動くので、「JITアセンブラ」と...
-ちなみに p0008a.c は50行のプログラムです。50行でJITアセ...
** 2026.05.01(金) #4
-まだ printf しかできないですが、とにかくJITコンパイラは...
-[追記] その後、for文もできました。簡単すぎて楽しいです。
-[追記] さらに1時間くらいやったら、 p0007h.txt が動くくら...
-やっぱりプリプロセッサは偉大だなあー。
** 2026.05.03(日) #0
-今、 p0008a.c っていうJITコンパイラを作っているのですが...
-そのアセンブラ部分は、 #define RET() DB(0xC3) みたいな...
-でもなあ、複数の引数をサポートするのは面倒だよなあ、まあ...
-でもさっき、思いつきました。あれ?もしかして、 #define D...
-その通りでした。こうして DB() 命令は複数の引数に対応でき...
-こんなに楽していいのかな?(笑)
-上記で、平気なふりして「#define を50行くらい書くだけで、...
-まあ進歩ってそういうものですよね。
** 2026.05.04(月) #0
-この欄の 2026.04.04.11(土)#1 に、プリプロセッサだと、a,b...
#define c a+b
#define b 2
#define a 1
printf("%d\n", c);
-これに対して、printf()が最後にある必要はあるけど、それ以...
-今回プリプロセッサを改良したので、以下のような書き方でも...
printf("%d\n", c);
#define c a+b
#define b 2
#define a 1
-つまり私の自作プリプロセッサなら define は後出しじゃんけ...
** 2026.05.04(月) #1
-[[a4_t0003]] を書きました。現行のミニコンパイラを補助ラ...
-ちょっと実験したのでメモしておきます。
8.0KB : printf("hello, world\n"); のみの.exeファイル
23.5KB : p0008a.c で pp のみ(Mode=0)
28.0KB : p0008a.c で pp+cc (Mode=1)
30.0KB : p0008a.c で pp+cc+cjit (Mode=2)
35.5KB : p0008a.c で pp+cc+cjit+clang (Mode=3)
37.5KB : p0008a.c で pp+cc+cjit+clang+calc+graphic (Mod...
-pp(プリプロセッサ)は実質的には 15.5KB 。
-cc(Cコンパイラ)は pp+4.5KB (でも実装している機能が少...
-JITコンパイラは +2.0KB 程度。
-a4vm を入れると +5.5KB 程度。
-[[a4_t0002]]程度のグラフィック機能であれば +2.0KB 程度。
** 2026.05.04(月) #2
-[[a4_p0008]] を書きました。JITコンパイラを試せます。
** 2026.05.06(水) #0
-「新しい言語の作り方」という12ページのスライド資料をなん...
--https://essen.osask.jp/files/pr20260506a_acl4.pdf
--今のところ発表予定はありません。
--[追記] 資料を更新しました → https://essen.osask.jp/file...
** 2026.05.10(日) #0
-運よくプレゼン機会があったので、上記の「新しい言語の作り...
-好評でたくさんコメントをもらえたので、それを加筆したバー...
-ちなみにここで発表してきました。
--「第51回 自作OSもくもく発表作業会」 https://osdev-jp.c...
--(ここの発表枠5で)
** 2026.05.13(水) #0
-ここまでの開発を振り返っています。
-[1] 第1層([[a4_0016]])
--デバッグに便利な機能が付いた malloc/realloc/free を整備。
-[2] 第2層([[a4_0017]]~[[a4_0019]])
--第1層の成果を使って、vector<char> を参考にして作った Ve...
--さらにトークンを切り出す Token0/Token1 クラス、かっこで...
-[3] 第3層([[a4_0020]])
--第2層の成果を使って、式の評価クラスを整備。文字列で式を...
-[4] 第4層([[a4_0021]]~[[a4_0022]])
--第3層までの成果を使って、プリプロセッサ関数を整備。
-[5] 第5層([[a4_0023]]~)
--第4層で作ったプリプロセッサ関数を使って、アセンブラやC...
--JITコンパイラも難なく成功。ついでにa4vmという仮想マシン...
--概要 → https://essen.osask.jp/files/pr20260505b_acl4.pdf
--実装 → [[a4_p0008]]
-ということで、まずAを作り、そのAを利用してBを作り、そのB...
** 2026.05.16(土) #0
-何となく自分が納得できる程度の memmem() ができたのでここ...
-まず memmem() が何かというと strstr() の仲間みたいなもの...
--https://manpages.ubuntu.com/manpages/focal/ja/man3/memm...
-GNU拡張なので、標準の <string.h> には入っていません。私...
-普通に作っても面白くないので、ちょっとだけ工夫をして高速...
-説明用のバージョン:
a_static char *a_memmem0(const char *t, intptr_t tn, con...
{
if (pn <= 0) return (char *) t;
if (tn < pn) return NULL;
intptr_t i = pn - 1;
const char *t1 = t + tn - pn, c0 = p[0];
for (t--;;) {
nxt:
t = memchr(t + 1, c0, t1 - t);
if (t == NULL) return NULL;
if (t[i] == p[i]) {
for (i = 1; i < pn; i++) {
if (t[i] != p[i]) goto nxt;
}
return (char *) t;
}
}
}
--まず memchr() で0バイト目が一致している場所を見つけてき...
--全部比較するときに memcmp() を使えばいいし、比較だけな...
--普通、この手のストリング検索では、 Boyer–Moore の有名な...
--最初に t--; して、次に t+1 から memchr() するのは一見す...
-でもこのバージョンをそのまま使うと、 memchr() があまり速...
-ちゃんと高速化したバージョン:
a_static char *a_memmem(const char *t, intptr_t tn, cons...
{
if (pn <= 0) return (char *) t;
if (tn < pn) return NULL;
intptr_t i = pn - 1;
const char *t1 = t + tn - pn, *t16 = t1 - 16, c0 = p...
for (t--;;) {
nxt:
t++;
for (;;) {
if (t <= t16) {
if (t[0] == c0) goto t0;
if (t[1] == c0) goto t1;
if (t[2] == c0) goto t2;
if (t[3] == c0) goto t3;
if (t[4] == c0) goto t4;
if (t[5] == c0) goto t5;
if (t[6] == c0) goto t6;
if (t[7] == c0) goto t7;
if (t[8] == c0) goto t8;
if (t[9] == c0) goto t9;
if (t[10] == c0) goto t10;
if (t[11] == c0) goto t11;
if (t[12] == c0) goto t12;
if (t[13] == c0) goto t13;
if (t[14] == c0) goto t14;
if (t[15] == c0) goto t15;
t += 16;
continue;
}
if (t > t1) return NULL;
if (t[0] == c0) goto t0;
t++;
}
t15: t++;
t14: t++;
t13: t++;
t12: t += 12; goto t0;
t11: t++;
t10: t++;
t9: t++;
t8: t += 8; goto t0;
t7: t++;
t6: t++;
t5: t++;
t4: t += 4; goto t0;
t3: t++;
t2: t++;
t1: t++;
t0:
if (t[i] == p[i]) {
for (i = 1; i < pn; i++) {
if (t[i] != p[i]) goto nxt;
}
return (char *) t;
}
}
}
--さあ、久しぶりに「キモイい」プログラムになりました。
--この改造の趣旨は、とにかくtを加算したり、tnとの比較をし...
--それで一致した場所が見つかった場合は、tをその分だけ加算...
--やっていることはそれだけです。
-そしてお楽しみのベンチマークです。
-芸のないベンチマーク:
#include <acl4v1.c>
#include "t0003a.c" // ここにa_memmem()があります.
int main(void)
{
char *s = malloc(900 * 1024 * 1024); // 900MB.
int i, j = 0;
for (i = 0; i <= 100000000; i++) // とりあえず1億.
j += sprintf(s + j, "%d ", i);
printf("j=%d\n", j);
clock_t t0, t1, t2;
t0 = clock();
int rs = (int) strstr(s, " 100000000");
t1 = clock();
int rm = (int) a_memmem(s, j, " 100000000", 10);
t2 = clock();
printf("strstr=%x\n", rs);
printf("a_memmem=%x\n", rm);
printf("t1-t0=%d t2-t1=%d\n", t1-t0, t2-t1);
return 0;
}
--まあいろいろ雑ですが、とりあえずこれでもベンチマークに...
--3回やってみると、こんな感じでした。まあ標準関数のstrstr...
t1-t0=321 t2-t1=292
t1-t0=272 t2-t1=272
t1-t0=278 t2-t1=273
--ちなみに今回の malloc() は acl4 の malloc_() ではなく、...
-次に、 a_memmem() が少し有利になりそうなベンチマークです...
#include <acl4v1.c>
#include "t0003a.c"
int main(void)
{
char *s = malloc(140 * 1024 * 1024); // 140MB.
int i, j = 0;
for (i = 0; i <= 10000000; i++) // とりあえず100万.
j += sprintf(s + j, "count=%d ", i);
printf("j=%d\n", j);
clock_t t0, t1, t2;
t0 = clock();
int rs = (int) strstr(s, "count=10000000");
t1 = clock();
int rm = (int) a_memmem(s, j, "count=10000000", 14);
t2 = clock();
printf("strstr=%x\n", rs);
printf("a_memmem=%x\n", rm);
printf("t1-t0=%d t2-t1=%d\n", t1 - t0, t2 - t1);
return 0;
}
--3回やってみるとこんな感じでした。
t1-t0=101 t2-t1=46
t1-t0=96 t2-t1=45
t1-t0=97 t2-t1=42
--やったね!
** 2026.05.22(金) #0
-最近は、SecHack365の選考に忙殺されていて、acl4があまり進...
-あ、でも、昨日は buntan-pc のuchanさんと、CPUにこんな命...
-考えていた内容は、たとえば整数演算でゼロ割しても例外を起...
-この命令体系だとプログラミングのパラダイムが変わるかもし...
** 2026.05.26(火) #0
-hh4みたいな多倍長の形式について思索。
-4bitあれば 0000~1111 の16通りの表現があります。これをA...
-Bパターンが来たら、そこで終了です。これで 0~(b-1) を表...
-Aパターンが来たら、Bパターンが来るまで繰り返してから終了...
-hh4の単純形式の場合、a=b=8になっていて、だから 8/64/512....
-拡張形式として、10+6=16 みたいなものを考えることができま...
-表にしてみます。
|8+8=16型|8|64|512|4096|
|10+6=16型|6|60|600|6000|
|7+9=16型|9|63|441|3087|
|6+10=16型|10|60|360|2160|
|5+11=16型|11|55|275|1375|
|4+12=16型|12|48|192|768|
-この中だと4+12=16はかなり魅力的に見えます。
** 2026.05.27(水) #0
-[[a26_txt03]](川合のプログラミング言語自作のためのテキ...
** 2026.05.30(土) #0
-説明を平易にしようとすると、ポインタとかはあまり使えない...
-だから言い訳を考えているのですが、結局ライブラリは「どん...
** 2026.05.31(日) #0
-まあまあいいものができた予感!
** 2026.06.01(月) #0
-メモリ管理とかデバイス管理など、プログラミングでは〇〇管...
-ところが、ふと「なぜ私は Manager を Man と略すのだろうか...
-不安は的中します。Google検索で調べていたらGeminiに、プロ...
-Geminiのちょっと微妙な受け答えはともかくとして、Man派は...
-とまあ、それはそれでよいとして、ではなぜ私は今まで Man ...
-私が最初に学んだのは・・・OS-9/6809です。それで昔読んだ...
** 2026.06.01(月) #0
-[[a26_txt03_001]](川合のプログラミング言語自作のための...
-このログページの一部を切り出して[[a4_log11]]を作って、そ...
** 2026.06.02(火) #0
-「デバッグ支援機能はこれが最後です」なんて書いたら、「う...
** 2026.06.09(火) #0
-ここしばらく、SecHack365関係で気が散って、あまり進んでい...
** 2026.06.10(水) #0
-C言語の標準ライブラリのqsort()関数は、配列をソートできて...
-この目的のためにqsortを使う場合は、a[i]の値とiの値を構造...
int (*iqsor_cmpF)(void *, int, int);
void *iqsor_cmpW;
int iqsort_cmp(const void *a, const void *b)
{
int ai = *(const int *) a;
int bi = *(const int *) b;
return iqsor_cmpF(iqsor_cmpW, ai, bi);
}
void iqsort(int *a, int n, int (*cmpF)(void *, int, int)...
{
int i;
for (i = 0; i < n; i++)
a[i] = i;
iqsor_cmpF = cmpF;
iqsor_cmpW = cmpW;
qsort(a, n, sizeof (int), iqsort_cmp);
}
// ここからサンプルコード.
int cmp(void *w, int i, int j)
{
const char **s = w;
return strcmp(s[i], s[j]);
}
int main()
{
char *name[5] = { "Tanaka", "Yamada", "Kawai", "Sato...
int idx[5], i;
iqsort(idx, 5, cmp, name); // これで idx[] を得る.
for (i = 0; i < 5; i++) { printf("%d ", idx[i]); } p...
for (i = 0; i < 5; i++) { printf("%d: %s\n", i, name...
return 0;
}
-これを実行すると、以下のようになります。
2 3 4 0 1
0: Kawai
1: Sato
2: Suzuki
3: Tanaka
4: Yamada
-最初にidx[i]の値が表示されています。idx[0]は2なので、一...
-要点は、name[]は全く並べ替えられることなくそのままになっ...
-私はこの仕様のほうが使いやすいなーと思いました。
-いやその別に全然大したことはないのですが・・・。
* こめんと欄
#comment
ページ名: