a4_p0007
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* acl4のプログラムのページ0007
-(by [[K]], 2026.04.25) ([[a4_i01]]: acl4 の目次...
** (1) プリプロセッサは善か悪か?
-私はかつてC言語のプリプロセッサのマクロが嫌いでした。関...
#define Square(x) (x)*(x)
-みたいなのがあると、xは二度評価されて、副作用があったり...
-こんなのやるくらいなら inline 関数を書いたほうがマシです。
-そもそも x * x って書けないところからして、許せないんで...
-まあ最適化が強くないコンパイラでも、関数呼び出しコードを...
~
-私は今はプリプロセッサが大好きです。プリプロセッサは世界...
** (2) プログラム p0007a.c について #0 (プリプロセッサ)
-acl4 ライブラリを使って、プリプロセッサを作りました。acl...
-''[p0007b.txt]:''
#define Square(x) (x)*(x)
#define One 1
#define Two 2
#define Three 3
#define Four 4
#define Five 5
#define Six 6
#define Seven 7
#define Eight 8
#define Nine 9
#define Ten 10
#define Eleven 11
#define Twelve 12
#if (Square(2+3)!=11)
Square(Three + Seven)
#endif
-これをプリプロセッサにかけるとこうなります。
>p0007a prepro:1 src:p0007b.txt
#line 14 "p0007b.txt"
(3 + 7)*(3 + 7)
-もし #line を出力しないでほしければ、こうします。
>p0007a prepro:1 src:p0007b.txt mod:2
(3 + 7)*(3 + 7)
-このプリプロセッサの実行ファイル( p0007a.exe )は 35.0K...
** (3) プログラム p0007a.c について #1 (コマンドライン計...
-プリプロセッサでは #if で式の値を計算する必要があります...
-せっかくなので、それを使ってやろうと考えました。ファイル...
>p0007a calc:1 src:inline:1+2+3+4+5+6+7+8+9+10
55
-結局中身はプリプロセッサなので、#defineとかが混ざってい...
>p0007a calc:1 src:p0007b.txt
100
-だから計算機プログラムとしては、ちょっと多機能です(笑)。
** (4) プログラム p0007a.c について #2 (x86-16のアセンブ...
-さてここからが本気です(笑)。
-実は自作プリプロセッサである p0007a は、普通のプリプロセ...
-これは acl4 ライブラリのプリプロセッサ関数が標準で持って...
-これを使って何ができるかと考えて、アセンブラが作れそうだ...
-''[p0007c.txt]:''
MOV(AH,0x02);
MOV(DL,0x20);
LBL(lp);
INT(0x21);
INC(DX);
CMP(DL,0x7E);
JBE_SHORT(lp);
RET();
-これは MS-DOS 用の「 !"#$%&'()...」を表示するプログラム...
-すべての命令をマクロとして書いて、それを変換していくこと...
-アセンブルしてみます。
>p0007a x86asm:1 src:p0007c.txt
[B4 02 B2 20 CD 21 42 80 FA 7E 76 F8 C3 ]
-今はとりあえずアセンブル結果を16進数で画面に出しています...
-このアセンブラ結果を得るために用意したインクルードファイ...
-''[x86asm.h]:''
#define AL R8:0
#define CL R8:1
#define DL R8:2
#define BL R8:3
#define AH R8:4
#define CH R8:5
#define DH R8:6
#define BH R8:7
#define AX R16:0
#define CX R16:1
#define DX R16:2
#define BX R16:3
#define SP R16:4
#define BP R16:5
#define SI R16:6
#define DI R16:7
#define RET() DB(0xC3)
#define INT(i) DB(0xCD); DB(i)
#define JBE_SHORT(l) DB(0x76); DB_L(l, 1, -1)
#define JBE_NEAR(l) DB(0x0F); DB(0x86); DW_L(l, 1, -2)
#typedDef MOV(R8:,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0xB0...
#typedDef MOV(R16:,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0xB8...
#typedDef INC(R16:,r) DB(0x40...
#typedDef DEC(R16:,r) DB(0x48...
#typedDef CMP(R8:,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0x80...
#typedDef CMP(R16:,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0x81...
#typedDef CMP(R8:0,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0x3C...
#typedDef CMP(R16:0,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0x3D...
-こんなものを見せられても全くぴんと来ないと思いますが、こ...
-中には見慣れない記述もありますが、でもなんか簡単に書けそ...
-ちなみに p0007a にはデバッグモードというのもあって、それ...
>p0007a x86asm:1 src:p0007c.txt dbg:1
DB(0xB0+4); DB(0x02);
DB(0xB0+2); DB(0x20);
LBL(2);
DB(0xCD); DB(0x21);
DB(0x40+2);
DB(0x80); DB(0xF8+2); DB(0x7E);
DB(0x76); DB_L(2, 1, -1);
DB(0xC3);
[B4 02 B2 20 CD 21 42 80 FA 7E 76 F8 C3 ]
-このアセンブラは、もちろん純粋なプリプロセッサだけではで...
-x86では、ALやAXレジスタを使うときのために、短い機械語を...
>p0007a x86asm:1 src:inline:CMP(CL,123);
[80 F9 7B ]
>p0007a x86asm:1 src:inline:CMP(AL,123);
[3C 7B ]
** (5) プログラム p0007a.c について #3 (C言語インタプリ...
-アセンブラはバックエンドで活躍すればいいので不格好な構文...
-となると、C言語はプリプロセッサを使って簡単に作ることは...
-それで、まずC言語の「a=b+c;」を「Add(a,b,c);」へ変換して...
-ということでそういう変換だけをするプログラムを「ミニコン...
-p0007a.c は全部で 317 行なので、この半分をミニコンパイラ...
-いっぽうで、 acl4 ライブラリ側には a4vm_exec0() という17...
-別にこれじゃなくてもいいのですが、これなら変換後に関数を...
-まずは hello, world からやってみます。
-''[p0007d.txt]:''
printf("hello, world\n");
-実行結果はこうなります。まあ当たり前ですね。
>p0007a clang:1 src:p0007d.txt
hello, world
-ちなみにミニコンパイラの出力はこうなっています( dbg:1 ...
Let(tmp0, CInt:"hello, world\n");
printf(tmp0);
-これがプリプロセッサによって何度も変換されて、最後にこう...
0x003e, 256, 256, 0, 0x2, 0, 0, 0;
0x0004, 128, "hello, world\n", 0;
0x003d, printf, 3, 0, 0x2, 128, 0, 0;
0x003f, 256, 256, 0, 0x2, 0, 0, 0;
-これが a4vm_exec0() に送られて、上記のような出力結果にな...
~
-素数を表示するプログラムを書きました。まだ配列変数が使え...
-''[p0007e.txt]:''
int i, j;
for (i = 2; i < 100; i++) {
for (j = 2; j * j <= i; j++) {
if (i % j == 0) goto skip;
}
printf("%d ", i);
skip: ;
}
printf("\n");
-実行結果はこうなります。もちろんあっています。
>p0007a clang:1 src:p0007e.txt
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 ...
-ちなみにミニコンパイラの出力は以下の通りでした( dbg:1 ...
#defineX skip defEnum(1)
#defineX i Int:defEnum(0)
#defineX j Int:defEnum(0)
Let(i, CInt:2);
Jmp_T(LT0002);
Lbl_T(LT0000);
Let(j, CInt:2);
Jmp_T(LT0006);
Lbl_T(LT0004);
Mod(tmp0, i, j);
Ceq(tmp1, tmp0, CInt:0);
Jne(tmp1, CInt:0, Txt:skip);
Let(tmp2, j); Add(j, j, CInt:1);
Lbl_T(LT0006);
Mul(tmp0, j, j);
Cle(tmp1, tmp0, i);
Jne(tmp1, CInt:0, Txt:LT0004);
Let(tmp0, CInt:"%d ");
Let(tmp1, i);
printf(tmp0,tmp1);
Lbl_T(skip);
Let(tmp1, i); Add(i, i, CInt:1);
Lbl_T(LT0002);
Clt(tmp0, i, CInt:100);
Jne(tmp0, CInt:0, Txt:LT0000);
Let(tmp0, CInt:"\n");
printf(tmp0);
~
-こんなに遊べるなら、 printf() だけではなくグラフィック関...
-''[p0007f.txt]:''
int x, y, c; c = 0;
openWin(256, 256);
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
setPix(x, y, c);
c = c + 0x100;
}
}
waitInf(); // これがないとウィンドウが一瞬で閉じられてし...
-実行すると毎度のこれが出ます(最後は無限ループで止まって...
--https://essen.osask.jp/files/pic20260331a.png
~
-次はこれです。
-''[p0007g.txt]:''
int x, y;
openWin(256, 256);
for (y = 0; y < 256; y++)
for (x = 0; x < 256; x++)
setPix(x, y, (x ^ y) * 0x10101);
waitInf(); // これがないとウィンドウが一瞬で閉じられてし...
-実行するとこれが出ます。大満足です(最後は無限ループで止...
--https://essen.osask.jp/files/pic20260331b.png
~
-ここまで来たら、 mandel もやってみたくなるわけです。
-''[p0007h.txt]:''
int x, y, c, sx, sy, cx, cy, zx, zy, xx, yy, n, sn;
openWin(512, 384);
for (y = 0; y < 384; y++) {
for (x = 0; x < 512; x++) {
sn = 0;
for (sx = 0; sx < 4; sx++) {
cx = (x * 4 + sx) * 56 + 4673536;
for (sy = 0; sy < 4; sy++) {
cy = (y * 4 + sy) * -56 - 124928;
zx = cx; zy = cy;
for (n = 1; n < 447; n++) {
Mul64Shr_RRRI(dR(xx), dR(zx), dR(zx)...
Mul64Shr_RRRI(dR(yy), dR(zy), dR(zy)...
if (xx + yy > 0x4000000) goto sk0;
Mul64Shr_RRRI(dR(zy), dR(zy), dR(zx)...
zx = xx + cx - yy;
zy = zy + cy;
}
sk0:
sn = sn + n;
}
}
sn = sn >> 4;
c = sn << 8;
if (sn < 256) goto sk1;
c = 0;
if (sn >= 447) goto sk1;
c = sn + 0xfe01;
sk1:
setPix(x, y, c << 8);
}
}
waitInf();
-実行結果はこうなります(最後は無限ループで止まっているだ...
--https://essen.osask.jp/files/pic20260331c.png
** (6) 主張のまとめ
-プリプロセッサ関数があれば、プログラミング言語はこんなに...
-今回アセンブラについては不格好な例を出しましたが、C言語...
-今回はアセンブラもC言語も最後まで作り切ったわけではあり...
-C言語の標準のプリプロセッサは #typedDef に相当する機能が...
-typedDef は以下のような仕様です。見た目はややこしそうで...
#typedDef INC(R16:,r) DB(0x40+defRight(r,:))
こう書いたときは、INC(r)のrが、"R16:"という書き出しにな...
#typedDef MOV(R8:,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0xB0...
こう書いたときは、MOV(r, i)のrが"R8:"という書きだしにな...
defRight(r,:)
rの中にコロンがあれば、その右側だけを取り出す。
-ということで、typedDefがプリプロセッサ活用の決め手かもし...
-Macro(...)の形式を超えてマクロが適用できるようになったら...
-プログラムの実行ファイルサイズについてもう一度説明してお...
-もちろんグラフィック機能も入った状態です。
-''[プリプロセッサ]+[計算機]+[簡易x86アセンブラ]+[簡易C言...
--それぞれがバラバラに入っているのではなく、それぞれがプ...
** (7) ダウンロード
-https://essen.osask.jp/files/a4_p0007.zip (51,375バイト)...
--ソースコード、サンプルプログラム、35.0KBの実行ファイル...
** (8) p0007a.c のソースコード
-1日でやっつけで作ったのできれいではありません。
-これは acl4v1 がないとビルドできないので、これから acl4v...
#define UseGraph 1
#define a_Version 1
#include <acl4v1.c>
#if (UseGraph != 0)
#include <windows.h>
#include "a4_t0002.c"
a_Win *win;
void openWin(intptr_t x, intptr_t y) { win = a_malloc(_a...
void setPix(intptr_t x, intptr_t y, intptr_t c) { win->b...
void flushWin() { a_Win_flushAll0(win); }
void waitInf() { if (win != NULL) { flushWin(); } for (;...
#endif
a_class(MiniCompiler_Sub) {
int mod;
int lb; VecChr vc[2];
// mod=0: for文.
// lb+0:continue0, lb+1:continue, lb+2:continue2, ...
// vc0:繰り返し条件, vc1:cotinue時のインクリメント...
};
a_class(MiniCompiler) {
a_Token0 *t0;
a_BufFree bf[1];
a_VecChr *vc;
a_VecChr stk[1], lbl[1];
int tmpNo, tmpLb, autoClose;
};
int eval_hook1(a_Preprocessor_Eval *w, a_Token0 *t0, int...
a_static void MiniCompiler_ini(MiniCompiler *w);
a_static void MiniCompiler_din(MiniCompiler *w);
a_static char *MiniCompiler_compile(MiniCompiler *w, int...
int main(int argc, const char **argv)
{
const char *src = getArg(argc, argv, "src:", ""); ch...
VecChr vc0[1], vc1[1], vc2[1], vc3[1]; VecChr_ini4(_...
BufFree bf[1]; a_BufFree_ini(_a_ bf); Token0 t0[1]; ...
Preprocessor_Eval ev[1]; Preprocessor_Eval_ini(_a_ e...
ev->hook1 = eval_hook1; ev->v[0] = bf; ev->v[1] = vc3;
if (strtol(getArg(argc, argv, "prepro:", "0"), NULL,...
int mod = strtol(getArg(argc, argv, "mod:", "1")...
a_Preprocessor_ini1(src, -1, mod, vc0);
puts(vc0->p);
}
if (strtol(getArg(argc, argv, "calc:", "0"), NULL, 0...
a_Preprocessor_ini1(src, -1, 2, vc0);
t0->s = vc0->p; t0->s1 = vc0->p + VecChr_N(vc0);
for (;;) {
t = Token1_get(t0);
if (t0->c == ',' || t0->c == ';') { printf("...
if (t0->c == 0) break;
t0->s = t; intptr_t i = Preprocessor_eval(ev...
if (ev->err != 0) break;
printf("%d", (int) i);
}
printf("\n");
}
if (strtol(getArg(argc, argv, "x86asm:", "0"), NULL,...
a_VecChr_iniArg(_a_ vc0, src, 2+16);
for (t = vc0->p;;) {
tt = strstr(t, "LBL("); if (tt == NULL) break;
t = strchr(tt, ')'); if (t == NULL) break;
VecChr_printf(vc1, "#defineX %.*s defEnum(0...
}
VecChr_printf(vc2, "imm<sys>:#include \"x86asm.h...
VecChr_N(vc0) = 0; a_Preprocessor_ini1(vc2->p, -...
if (strtol(getArg(argc, argv, "dbg:", "0"), NULL...
intptr_t pass, lbl[999];
for (pass = 0; pass < 2; pass++) {
t0->s = vc0->p; t0->s1 = vc0->p + VecChr_N(v...
VecChr_N(vc1) = 0;
for (;;) {
t = Token1_get(t0); intptr_t n = t0->len...
if (t0->c == ',' || t0->c == ';') contin...
if (t0->c == 0) break;
if (n == 3 && memcmp(t, "LBL", 3) == 0) {
i = Preprocessor_eval(ev, t0, 0x7fff);
if (0 <= i && i < 999) lbl[i] = VecC...
}
m = 0;
if (n == 4 && memcmp(t, "DB_L", 4) == 0)...
if (n == 4 && memcmp(t, "DW_L", 4) == 0)...
if (n == 4 && memcmp(t, "DD_L", 4) == 0)...
if (m > 0) {
Token1_get(t0); i = Preprocessor_eva...
Token1_get(t0); j = Preprocessor_eva...
Token1_get(t0); k = Preprocessor_eva...
if (i == 1) { i = VecChr_N(vc1); } e...
if (j == 1) { j = VecChr_N(vc1); } e...
i = i - j + k;
goto db_i;
}
m = 0;
if (n == 2 && memcmp(t, "DB", 2) == 0...
if (n == 2 && memcmp(t, "DW", 2) == 0...
if (n == 2 && memcmp(t, "DD", 2) == 0...
if (m > 0) {
i = Preprocessor_eval(ev, t0, 0x7fff);
db_i:
*(char *)VecChr_stkAdd(vc...
if (m > 1) *(char *)VecChr_stkAdd(vc...
if (m > 2) *(char *)VecChr_stkAdd(vc...
if (m > 3) *(char *)VecChr_stkAdd(vc...
}
}
}
hexDump(vc1->p, VecChr_N(vc1), stdout);
}
if (strtol(getArg(argc, argv, "clang:", "0"), NULL, ...
a_Preprocessor_ini1(src, -1, 2, vc0);
t0->s = vc0->p; t0->s1 = vc0->p + a_VecChr_N(vc0);
MiniCompiler mc[1]; MiniCompiler_ini(mc); mc->t0...
MiniCompiler_compile(mc, 99); a_VecChr_replace(v...
MiniCompiler_din(mc); a_VecChr_reserve0(vc1);
if (strtol(getArg(argc, argv, "dbg:", "0"), NULL...
a_VecChr_printf(vc2, "imm<sys>:#include \"a4vm-c...
VecChr_N(vc0) = 0; a_Preprocessor_ini1(vc2->p, -...
if (strtol(getArg(argc, argv, "dbg:", "0"), NULL...
VecChr_N(vc1) = 0; t0->s = vc0->p; t0->s1 = vc0-...
for (;;) {
t = Token1_get(t0);
if (t0->c == ',' || t0->c == ';') continue;
if (t0->c == 0) break;
t0->s = t;
intptr_t i = Preprocessor_eval(ev, t0, 0x7ff...
if (ev->err != 0) break;
*(intptr_t *)VecChr_stkAdd(vc1, sizeof (intp...
if (strtol(getArg(argc, argv, "dbg:", "0"), ...
}
if (strtol(getArg(argc, argv, "dbg:", "0"), NULL...
intptr_t *bp = (intptr_t *) vc1->p, bn = VecChr_...
intptr_t a4arg[10]; a4arg[0] = 0; A4vm_exec0(bp,...
}
Preprocessor_Eval_din(_a_ ev);
VecChr_din4(_a_ vc0, vc1, vc2, vc3); BufFree_flush(_...
a_malloc_debugList(_a);
a_DbgObjInfTbl_debugList(_a);
return 0;
}
int eval_hook1(a_Preprocessor_Eval *w, a_Token0 *t0, int...
{
BufFree *bf = w->v[0];
VecChr *vcTmp = w->v[1];
intptr_t n = t0->len; (void) pri;
if (n >= 2 && t[0] == 0x22) {
char *s;
VecChr_N(vcTmp) = 0; VecChr_puts(vcTmp, t + 1, n...
VecChr_convEsc(vcTmp);
*pi = (intptr_t) (s = BufFree_malloc(_a_ bf, Vec...
memcpy(s, vcTmp->p, VecChr_N(vcTmp) + 1);
return 1;
}
if (n == 6 && memcmp(t, "printf", 6) == 0) { *pi ...
#if (UseGraph != 0)
if (n == 7 && memcmp(t, "openWin", 7) == 0) { *pi ...
if (n == 6 && memcmp(t, "setPix", 6) == 0) { *pi ...
if (n == 8 && memcmp(t, "flushWin", 8) == 0) { *pi ...
if (n == 7 && memcmp(t, "waitInf", 7) == 0) { *pi ...
#endif
return 0;
}
a_static void MiniCompiler_ini(MiniCompiler *w)
{
a_BufFree_ini(_a_ w->bf); a_VecChr_ini4(_a_ w->stk, ...
}
a_static void MiniCompiler_din(MiniCompiler *w)
{
a_BufFree_flush(_a_ w->bf); a_BufFree_din(_a_ w->bf)...
}
a_static char *MiniCompiler_newTmp(MiniCompiler *w)
{
char s[256];
intptr_t n = sprintf(s, "tmp%d", w->tmpNo++);
char *v = a_BufFree_malloc(_a_ w->bf, n + 1);
memcpy(v, s, n + 1);
return v;
}
#define MiniCompiler_compile_Macro0(pri, fmt) vv = Min...
a_static char *MiniCompiler_compile(MiniCompiler *w, int...
{
char *v, *tv, *vv;
op1:
const char *tt, *t = a_Token1_get(w->t0); intptr_t n...
if (w->autoClose > 0) { w->t0->s = t; c = '}'; w->au...
if (c == '}') {
MiniCompiler_Sub *sb = VecChr_stkTop(w->stk, siz...
if (sb->mod == 0) {
a_VecChr_printf(w->vc, "Lbl_T(LT%04d);\n%s%s...
a_VecChr_din4(_a_ &sb->vc[0], &sb->vc[1], 0,...
}
w->t0->s = t; return NULL;
}
if (n == 0) return NULL;
if (c == '-') {
tv = MiniCompiler_compile(w, 1); v = MiniCompile...
a_VecChr_printf(w->vc, "Mul(%s, %s, CInt:-1);\n"...
}
if (c == ';') { if (pri == 98) { w->t0->s = t; retu...
if (c == '(') { v = MiniCompiler_compile(w, 99); a_T...
tt = Token1_get(w->t0); if (w->t0->c == ':') { // コ...
a_VecChr_printf(w->vc, "Lbl_T(%.*s);\n", n, t);
a_VecChr_printf(w->lbl, "#defineX %.*s defEnum(...
goto op1;
}
if (n == 2 && memcmp(t, "if", 2) == 0 && w->t0->c ==...
v = MiniCompiler_compile(w, 99); a_Token1_get(w-...
tt = a_Token1_get(w->t0);
if (w->t0->len == 4 && memcmp(tt, "goto", 4) == ...
tt = a_Token1_get(w->t0); a_VecChr_printf(w-...
}
w->t0->s = t; return NULL;
}
if (n == 3 && memcmp(t, "for", 2) == 0 && w->t0->c =...
MiniCompiler_compile(w, 98); Token1_get(w->t0);
MiniCompiler_Sub *sb = a_VecChr_stkAdd(w->stk, s...
sb->mod = 0;
sb->lb = w->tmpLb; w->tmpLb += 4;
a_VecChr_ini4(_a_ &sb->vc[0], &sb->vc[1], 0, 0);
a_VecChr_printf(w->vc, "Jmp_T(LT%04d);\n", sb->l...
a_VecChr_printf(w->vc, "Lbl_T(LT%04d);\n", sb->l...
a_VecChr *vc0 = w->vc; w->vc = &sb->vc[0];
a_VecChr_printf(w->vc, "Lbl_T(LT%04d);\n", sb->l...
v = MiniCompiler_compile(w, 98); Token1_get(w->t...
if (v == NULL) { a_VecChr_printf(w->vc, "Jmp_T(L...
else { a_VecChr_printf(w->vc, "Jne(%s, CInt:0, T...
w->vc = &sb->vc[1];
v = MiniCompiler_compile(w, 98); Token1_get(w->t...
w->vc = vc0; w->tmpNo = 0;
tt = a_Token1_get(w->t0); if (w->t0->c != '{') {...
goto op1;
}
if (n == 13 && memcmp(t, "Mul64Shr_RRRI", 13) == 0) {
for (;;) {
Token1_get(w->t0); if (w->t0->c == ';') break;
}
a_VecChr_printf(w->vc, "%.*s\n", w->t0->s - t, t);
goto op1;
}
if (n == 7 && memcmp(t, "openWin", 7) == 0) goto cF...
if (n == 6 && memcmp(t, "setPix", 6) == 0) goto cF...
if (n == 8 && memcmp(t, "flushWin", 8) == 0) goto cF...
if (n == 7 && memcmp(t, "waitInf", 7) == 0) goto cF...
if (n == 6 && memcmp(t, "printf", 6) == 0) {
cFunc:
a_VecChr vc0[1]; a_VecChr_ini(_a_ vc0); a_VecChr...
for (;;) {
t = Token1_get(w->t0); if (w->t0->c == ')') ...
if (w->t0->c == ',') continue;
w->t0->s = t; v = MiniCompiler_compile(w, 98...
a_VecChr_printf(w->vc, "Let(%s, %s);\n", tt,...
a_VecChr_printf(vc0, "%s,", tt);
}
n = a_VecChr_N(vc0); if (vc0->p[n - 1] == ',') n...
a_VecChr_printf(w->vc, "%.*s);\n", n, vc0->p); a...
}
w->t0->s = tt; // 一度読み込んだ未解釈の演算子をt0に...
if (n == 3 && memcmp(t, "int", 3) == 0) {
for (;;) {
t = a_Token1_get(w->t0); if (*t == ';') break;
if (*t == ',') continue;
a_VecChr_printf(w->vc, "#defineX %.*s Int:d...
}
w->t0->s = t; goto op1;
}
if (('0' <= *t && *t <= '9') || *t == 0x22) {
v = a_BufFree_malloc(_a_ w->bf, n + 1 + 5);
memcpy(v, "CInt:", 5); memcpy(v + 5, t, n); v[n ...
} else {
v = a_BufFree_malloc(_a_ w->bf, n + 1);
memcpy(v, t, n); v[n] = '\0';
}
op2:
t = Token1_get(w->t0); c = w->t0->c; n = w->t0->len;
if (n == 0) return v;
if (c == ('+' | '+' << 8) && pri >= 1) {
tv = MiniCompiler_newTmp(w);
a_VecChr_printf(w->vc, "Let(%s, %s); Add(%s, %s,...
v = tv; goto op2;
}
if (c == '*' && pri >= 4) { MiniCompil...
if (c == '/' && pri >= 4) { MiniCompil...
if (c == '%' && pri >= 4) { MiniCompil...
if (c == '+' && pri >= 5) { MiniCompil...
if (c == '-' && pri >= 5) { MiniCompil...
if (c == ('<' | '<' << 8) && pri >= 6) { MiniCompil...
if (c == ('>' | '>' << 8) && pri >= 6) { MiniCompil...
if (c == ('<' | '=' << 8) && pri >= 7) { MiniCompil...
if (c == '<' && pri >= 7) { MiniCompil...
if (c == ('>' | '=' << 8) && pri >= 7) { MiniCompil...
if (c == '>' && pri >= 7) { MiniCompil...
if (c == ('=' | '=' << 8) && pri >= 8) { MiniCompil...
if (c == ('!' | '=' << 8) && pri >= 8) { MiniCompil...
if (c == '&' && pri >= 9) { MiniCompil...
if (c == '^' && pri >= 10) { MiniCompil...
if (c == '|' && pri >= 11) { MiniCompil...
if (c == '=' && pri >= 15) { a_VecChr_printf(w->vc,...
if (c == ';' && pri >= 98) { if (pri == 98) { w->t0...
w->t0->s = t; return v; // 一度読み込んだ未解釈の演...
}
** (99) 更新履歴
-2026.04.25(土) 初版
-2026.04.27(月) 誤記修正
終了行:
* acl4のプログラムのページ0007
-(by [[K]], 2026.04.25) ([[a4_i01]]: acl4 の目次...
** (1) プリプロセッサは善か悪か?
-私はかつてC言語のプリプロセッサのマクロが嫌いでした。関...
#define Square(x) (x)*(x)
-みたいなのがあると、xは二度評価されて、副作用があったり...
-こんなのやるくらいなら inline 関数を書いたほうがマシです。
-そもそも x * x って書けないところからして、許せないんで...
-まあ最適化が強くないコンパイラでも、関数呼び出しコードを...
~
-私は今はプリプロセッサが大好きです。プリプロセッサは世界...
** (2) プログラム p0007a.c について #0 (プリプロセッサ)
-acl4 ライブラリを使って、プリプロセッサを作りました。acl...
-''[p0007b.txt]:''
#define Square(x) (x)*(x)
#define One 1
#define Two 2
#define Three 3
#define Four 4
#define Five 5
#define Six 6
#define Seven 7
#define Eight 8
#define Nine 9
#define Ten 10
#define Eleven 11
#define Twelve 12
#if (Square(2+3)!=11)
Square(Three + Seven)
#endif
-これをプリプロセッサにかけるとこうなります。
>p0007a prepro:1 src:p0007b.txt
#line 14 "p0007b.txt"
(3 + 7)*(3 + 7)
-もし #line を出力しないでほしければ、こうします。
>p0007a prepro:1 src:p0007b.txt mod:2
(3 + 7)*(3 + 7)
-このプリプロセッサの実行ファイル( p0007a.exe )は 35.0K...
** (3) プログラム p0007a.c について #1 (コマンドライン計...
-プリプロセッサでは #if で式の値を計算する必要があります...
-せっかくなので、それを使ってやろうと考えました。ファイル...
>p0007a calc:1 src:inline:1+2+3+4+5+6+7+8+9+10
55
-結局中身はプリプロセッサなので、#defineとかが混ざってい...
>p0007a calc:1 src:p0007b.txt
100
-だから計算機プログラムとしては、ちょっと多機能です(笑)。
** (4) プログラム p0007a.c について #2 (x86-16のアセンブ...
-さてここからが本気です(笑)。
-実は自作プリプロセッサである p0007a は、普通のプリプロセ...
-これは acl4 ライブラリのプリプロセッサ関数が標準で持って...
-これを使って何ができるかと考えて、アセンブラが作れそうだ...
-''[p0007c.txt]:''
MOV(AH,0x02);
MOV(DL,0x20);
LBL(lp);
INT(0x21);
INC(DX);
CMP(DL,0x7E);
JBE_SHORT(lp);
RET();
-これは MS-DOS 用の「 !"#$%&'()...」を表示するプログラム...
-すべての命令をマクロとして書いて、それを変換していくこと...
-アセンブルしてみます。
>p0007a x86asm:1 src:p0007c.txt
[B4 02 B2 20 CD 21 42 80 FA 7E 76 F8 C3 ]
-今はとりあえずアセンブル結果を16進数で画面に出しています...
-このアセンブラ結果を得るために用意したインクルードファイ...
-''[x86asm.h]:''
#define AL R8:0
#define CL R8:1
#define DL R8:2
#define BL R8:3
#define AH R8:4
#define CH R8:5
#define DH R8:6
#define BH R8:7
#define AX R16:0
#define CX R16:1
#define DX R16:2
#define BX R16:3
#define SP R16:4
#define BP R16:5
#define SI R16:6
#define DI R16:7
#define RET() DB(0xC3)
#define INT(i) DB(0xCD); DB(i)
#define JBE_SHORT(l) DB(0x76); DB_L(l, 1, -1)
#define JBE_NEAR(l) DB(0x0F); DB(0x86); DW_L(l, 1, -2)
#typedDef MOV(R8:,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0xB0...
#typedDef MOV(R16:,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0xB8...
#typedDef INC(R16:,r) DB(0x40...
#typedDef DEC(R16:,r) DB(0x48...
#typedDef CMP(R8:,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0x80...
#typedDef CMP(R16:,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0x81...
#typedDef CMP(R8:0,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0x3C...
#typedDef CMP(R16:0,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0x3D...
-こんなものを見せられても全くぴんと来ないと思いますが、こ...
-中には見慣れない記述もありますが、でもなんか簡単に書けそ...
-ちなみに p0007a にはデバッグモードというのもあって、それ...
>p0007a x86asm:1 src:p0007c.txt dbg:1
DB(0xB0+4); DB(0x02);
DB(0xB0+2); DB(0x20);
LBL(2);
DB(0xCD); DB(0x21);
DB(0x40+2);
DB(0x80); DB(0xF8+2); DB(0x7E);
DB(0x76); DB_L(2, 1, -1);
DB(0xC3);
[B4 02 B2 20 CD 21 42 80 FA 7E 76 F8 C3 ]
-このアセンブラは、もちろん純粋なプリプロセッサだけではで...
-x86では、ALやAXレジスタを使うときのために、短い機械語を...
>p0007a x86asm:1 src:inline:CMP(CL,123);
[80 F9 7B ]
>p0007a x86asm:1 src:inline:CMP(AL,123);
[3C 7B ]
** (5) プログラム p0007a.c について #3 (C言語インタプリ...
-アセンブラはバックエンドで活躍すればいいので不格好な構文...
-となると、C言語はプリプロセッサを使って簡単に作ることは...
-それで、まずC言語の「a=b+c;」を「Add(a,b,c);」へ変換して...
-ということでそういう変換だけをするプログラムを「ミニコン...
-p0007a.c は全部で 317 行なので、この半分をミニコンパイラ...
-いっぽうで、 acl4 ライブラリ側には a4vm_exec0() という17...
-別にこれじゃなくてもいいのですが、これなら変換後に関数を...
-まずは hello, world からやってみます。
-''[p0007d.txt]:''
printf("hello, world\n");
-実行結果はこうなります。まあ当たり前ですね。
>p0007a clang:1 src:p0007d.txt
hello, world
-ちなみにミニコンパイラの出力はこうなっています( dbg:1 ...
Let(tmp0, CInt:"hello, world\n");
printf(tmp0);
-これがプリプロセッサによって何度も変換されて、最後にこう...
0x003e, 256, 256, 0, 0x2, 0, 0, 0;
0x0004, 128, "hello, world\n", 0;
0x003d, printf, 3, 0, 0x2, 128, 0, 0;
0x003f, 256, 256, 0, 0x2, 0, 0, 0;
-これが a4vm_exec0() に送られて、上記のような出力結果にな...
~
-素数を表示するプログラムを書きました。まだ配列変数が使え...
-''[p0007e.txt]:''
int i, j;
for (i = 2; i < 100; i++) {
for (j = 2; j * j <= i; j++) {
if (i % j == 0) goto skip;
}
printf("%d ", i);
skip: ;
}
printf("\n");
-実行結果はこうなります。もちろんあっています。
>p0007a clang:1 src:p0007e.txt
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 ...
-ちなみにミニコンパイラの出力は以下の通りでした( dbg:1 ...
#defineX skip defEnum(1)
#defineX i Int:defEnum(0)
#defineX j Int:defEnum(0)
Let(i, CInt:2);
Jmp_T(LT0002);
Lbl_T(LT0000);
Let(j, CInt:2);
Jmp_T(LT0006);
Lbl_T(LT0004);
Mod(tmp0, i, j);
Ceq(tmp1, tmp0, CInt:0);
Jne(tmp1, CInt:0, Txt:skip);
Let(tmp2, j); Add(j, j, CInt:1);
Lbl_T(LT0006);
Mul(tmp0, j, j);
Cle(tmp1, tmp0, i);
Jne(tmp1, CInt:0, Txt:LT0004);
Let(tmp0, CInt:"%d ");
Let(tmp1, i);
printf(tmp0,tmp1);
Lbl_T(skip);
Let(tmp1, i); Add(i, i, CInt:1);
Lbl_T(LT0002);
Clt(tmp0, i, CInt:100);
Jne(tmp0, CInt:0, Txt:LT0000);
Let(tmp0, CInt:"\n");
printf(tmp0);
~
-こんなに遊べるなら、 printf() だけではなくグラフィック関...
-''[p0007f.txt]:''
int x, y, c; c = 0;
openWin(256, 256);
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
setPix(x, y, c);
c = c + 0x100;
}
}
waitInf(); // これがないとウィンドウが一瞬で閉じられてし...
-実行すると毎度のこれが出ます(最後は無限ループで止まって...
--https://essen.osask.jp/files/pic20260331a.png
~
-次はこれです。
-''[p0007g.txt]:''
int x, y;
openWin(256, 256);
for (y = 0; y < 256; y++)
for (x = 0; x < 256; x++)
setPix(x, y, (x ^ y) * 0x10101);
waitInf(); // これがないとウィンドウが一瞬で閉じられてし...
-実行するとこれが出ます。大満足です(最後は無限ループで止...
--https://essen.osask.jp/files/pic20260331b.png
~
-ここまで来たら、 mandel もやってみたくなるわけです。
-''[p0007h.txt]:''
int x, y, c, sx, sy, cx, cy, zx, zy, xx, yy, n, sn;
openWin(512, 384);
for (y = 0; y < 384; y++) {
for (x = 0; x < 512; x++) {
sn = 0;
for (sx = 0; sx < 4; sx++) {
cx = (x * 4 + sx) * 56 + 4673536;
for (sy = 0; sy < 4; sy++) {
cy = (y * 4 + sy) * -56 - 124928;
zx = cx; zy = cy;
for (n = 1; n < 447; n++) {
Mul64Shr_RRRI(dR(xx), dR(zx), dR(zx)...
Mul64Shr_RRRI(dR(yy), dR(zy), dR(zy)...
if (xx + yy > 0x4000000) goto sk0;
Mul64Shr_RRRI(dR(zy), dR(zy), dR(zx)...
zx = xx + cx - yy;
zy = zy + cy;
}
sk0:
sn = sn + n;
}
}
sn = sn >> 4;
c = sn << 8;
if (sn < 256) goto sk1;
c = 0;
if (sn >= 447) goto sk1;
c = sn + 0xfe01;
sk1:
setPix(x, y, c << 8);
}
}
waitInf();
-実行結果はこうなります(最後は無限ループで止まっているだ...
--https://essen.osask.jp/files/pic20260331c.png
** (6) 主張のまとめ
-プリプロセッサ関数があれば、プログラミング言語はこんなに...
-今回アセンブラについては不格好な例を出しましたが、C言語...
-今回はアセンブラもC言語も最後まで作り切ったわけではあり...
-C言語の標準のプリプロセッサは #typedDef に相当する機能が...
-typedDef は以下のような仕様です。見た目はややこしそうで...
#typedDef INC(R16:,r) DB(0x40+defRight(r,:))
こう書いたときは、INC(r)のrが、"R16:"という書き出しにな...
#typedDef MOV(R8:,r, (0,1,2,3,4,5,6,7,8,9),i) DB(0xB0...
こう書いたときは、MOV(r, i)のrが"R8:"という書きだしにな...
defRight(r,:)
rの中にコロンがあれば、その右側だけを取り出す。
-ということで、typedDefがプリプロセッサ活用の決め手かもし...
-Macro(...)の形式を超えてマクロが適用できるようになったら...
-プログラムの実行ファイルサイズについてもう一度説明してお...
-もちろんグラフィック機能も入った状態です。
-''[プリプロセッサ]+[計算機]+[簡易x86アセンブラ]+[簡易C言...
--それぞれがバラバラに入っているのではなく、それぞれがプ...
** (7) ダウンロード
-https://essen.osask.jp/files/a4_p0007.zip (51,375バイト)...
--ソースコード、サンプルプログラム、35.0KBの実行ファイル...
** (8) p0007a.c のソースコード
-1日でやっつけで作ったのできれいではありません。
-これは acl4v1 がないとビルドできないので、これから acl4v...
#define UseGraph 1
#define a_Version 1
#include <acl4v1.c>
#if (UseGraph != 0)
#include <windows.h>
#include "a4_t0002.c"
a_Win *win;
void openWin(intptr_t x, intptr_t y) { win = a_malloc(_a...
void setPix(intptr_t x, intptr_t y, intptr_t c) { win->b...
void flushWin() { a_Win_flushAll0(win); }
void waitInf() { if (win != NULL) { flushWin(); } for (;...
#endif
a_class(MiniCompiler_Sub) {
int mod;
int lb; VecChr vc[2];
// mod=0: for文.
// lb+0:continue0, lb+1:continue, lb+2:continue2, ...
// vc0:繰り返し条件, vc1:cotinue時のインクリメント...
};
a_class(MiniCompiler) {
a_Token0 *t0;
a_BufFree bf[1];
a_VecChr *vc;
a_VecChr stk[1], lbl[1];
int tmpNo, tmpLb, autoClose;
};
int eval_hook1(a_Preprocessor_Eval *w, a_Token0 *t0, int...
a_static void MiniCompiler_ini(MiniCompiler *w);
a_static void MiniCompiler_din(MiniCompiler *w);
a_static char *MiniCompiler_compile(MiniCompiler *w, int...
int main(int argc, const char **argv)
{
const char *src = getArg(argc, argv, "src:", ""); ch...
VecChr vc0[1], vc1[1], vc2[1], vc3[1]; VecChr_ini4(_...
BufFree bf[1]; a_BufFree_ini(_a_ bf); Token0 t0[1]; ...
Preprocessor_Eval ev[1]; Preprocessor_Eval_ini(_a_ e...
ev->hook1 = eval_hook1; ev->v[0] = bf; ev->v[1] = vc3;
if (strtol(getArg(argc, argv, "prepro:", "0"), NULL,...
int mod = strtol(getArg(argc, argv, "mod:", "1")...
a_Preprocessor_ini1(src, -1, mod, vc0);
puts(vc0->p);
}
if (strtol(getArg(argc, argv, "calc:", "0"), NULL, 0...
a_Preprocessor_ini1(src, -1, 2, vc0);
t0->s = vc0->p; t0->s1 = vc0->p + VecChr_N(vc0);
for (;;) {
t = Token1_get(t0);
if (t0->c == ',' || t0->c == ';') { printf("...
if (t0->c == 0) break;
t0->s = t; intptr_t i = Preprocessor_eval(ev...
if (ev->err != 0) break;
printf("%d", (int) i);
}
printf("\n");
}
if (strtol(getArg(argc, argv, "x86asm:", "0"), NULL,...
a_VecChr_iniArg(_a_ vc0, src, 2+16);
for (t = vc0->p;;) {
tt = strstr(t, "LBL("); if (tt == NULL) break;
t = strchr(tt, ')'); if (t == NULL) break;
VecChr_printf(vc1, "#defineX %.*s defEnum(0...
}
VecChr_printf(vc2, "imm<sys>:#include \"x86asm.h...
VecChr_N(vc0) = 0; a_Preprocessor_ini1(vc2->p, -...
if (strtol(getArg(argc, argv, "dbg:", "0"), NULL...
intptr_t pass, lbl[999];
for (pass = 0; pass < 2; pass++) {
t0->s = vc0->p; t0->s1 = vc0->p + VecChr_N(v...
VecChr_N(vc1) = 0;
for (;;) {
t = Token1_get(t0); intptr_t n = t0->len...
if (t0->c == ',' || t0->c == ';') contin...
if (t0->c == 0) break;
if (n == 3 && memcmp(t, "LBL", 3) == 0) {
i = Preprocessor_eval(ev, t0, 0x7fff);
if (0 <= i && i < 999) lbl[i] = VecC...
}
m = 0;
if (n == 4 && memcmp(t, "DB_L", 4) == 0)...
if (n == 4 && memcmp(t, "DW_L", 4) == 0)...
if (n == 4 && memcmp(t, "DD_L", 4) == 0)...
if (m > 0) {
Token1_get(t0); i = Preprocessor_eva...
Token1_get(t0); j = Preprocessor_eva...
Token1_get(t0); k = Preprocessor_eva...
if (i == 1) { i = VecChr_N(vc1); } e...
if (j == 1) { j = VecChr_N(vc1); } e...
i = i - j + k;
goto db_i;
}
m = 0;
if (n == 2 && memcmp(t, "DB", 2) == 0...
if (n == 2 && memcmp(t, "DW", 2) == 0...
if (n == 2 && memcmp(t, "DD", 2) == 0...
if (m > 0) {
i = Preprocessor_eval(ev, t0, 0x7fff);
db_i:
*(char *)VecChr_stkAdd(vc...
if (m > 1) *(char *)VecChr_stkAdd(vc...
if (m > 2) *(char *)VecChr_stkAdd(vc...
if (m > 3) *(char *)VecChr_stkAdd(vc...
}
}
}
hexDump(vc1->p, VecChr_N(vc1), stdout);
}
if (strtol(getArg(argc, argv, "clang:", "0"), NULL, ...
a_Preprocessor_ini1(src, -1, 2, vc0);
t0->s = vc0->p; t0->s1 = vc0->p + a_VecChr_N(vc0);
MiniCompiler mc[1]; MiniCompiler_ini(mc); mc->t0...
MiniCompiler_compile(mc, 99); a_VecChr_replace(v...
MiniCompiler_din(mc); a_VecChr_reserve0(vc1);
if (strtol(getArg(argc, argv, "dbg:", "0"), NULL...
a_VecChr_printf(vc2, "imm<sys>:#include \"a4vm-c...
VecChr_N(vc0) = 0; a_Preprocessor_ini1(vc2->p, -...
if (strtol(getArg(argc, argv, "dbg:", "0"), NULL...
VecChr_N(vc1) = 0; t0->s = vc0->p; t0->s1 = vc0-...
for (;;) {
t = Token1_get(t0);
if (t0->c == ',' || t0->c == ';') continue;
if (t0->c == 0) break;
t0->s = t;
intptr_t i = Preprocessor_eval(ev, t0, 0x7ff...
if (ev->err != 0) break;
*(intptr_t *)VecChr_stkAdd(vc1, sizeof (intp...
if (strtol(getArg(argc, argv, "dbg:", "0"), ...
}
if (strtol(getArg(argc, argv, "dbg:", "0"), NULL...
intptr_t *bp = (intptr_t *) vc1->p, bn = VecChr_...
intptr_t a4arg[10]; a4arg[0] = 0; A4vm_exec0(bp,...
}
Preprocessor_Eval_din(_a_ ev);
VecChr_din4(_a_ vc0, vc1, vc2, vc3); BufFree_flush(_...
a_malloc_debugList(_a);
a_DbgObjInfTbl_debugList(_a);
return 0;
}
int eval_hook1(a_Preprocessor_Eval *w, a_Token0 *t0, int...
{
BufFree *bf = w->v[0];
VecChr *vcTmp = w->v[1];
intptr_t n = t0->len; (void) pri;
if (n >= 2 && t[0] == 0x22) {
char *s;
VecChr_N(vcTmp) = 0; VecChr_puts(vcTmp, t + 1, n...
VecChr_convEsc(vcTmp);
*pi = (intptr_t) (s = BufFree_malloc(_a_ bf, Vec...
memcpy(s, vcTmp->p, VecChr_N(vcTmp) + 1);
return 1;
}
if (n == 6 && memcmp(t, "printf", 6) == 0) { *pi ...
#if (UseGraph != 0)
if (n == 7 && memcmp(t, "openWin", 7) == 0) { *pi ...
if (n == 6 && memcmp(t, "setPix", 6) == 0) { *pi ...
if (n == 8 && memcmp(t, "flushWin", 8) == 0) { *pi ...
if (n == 7 && memcmp(t, "waitInf", 7) == 0) { *pi ...
#endif
return 0;
}
a_static void MiniCompiler_ini(MiniCompiler *w)
{
a_BufFree_ini(_a_ w->bf); a_VecChr_ini4(_a_ w->stk, ...
}
a_static void MiniCompiler_din(MiniCompiler *w)
{
a_BufFree_flush(_a_ w->bf); a_BufFree_din(_a_ w->bf)...
}
a_static char *MiniCompiler_newTmp(MiniCompiler *w)
{
char s[256];
intptr_t n = sprintf(s, "tmp%d", w->tmpNo++);
char *v = a_BufFree_malloc(_a_ w->bf, n + 1);
memcpy(v, s, n + 1);
return v;
}
#define MiniCompiler_compile_Macro0(pri, fmt) vv = Min...
a_static char *MiniCompiler_compile(MiniCompiler *w, int...
{
char *v, *tv, *vv;
op1:
const char *tt, *t = a_Token1_get(w->t0); intptr_t n...
if (w->autoClose > 0) { w->t0->s = t; c = '}'; w->au...
if (c == '}') {
MiniCompiler_Sub *sb = VecChr_stkTop(w->stk, siz...
if (sb->mod == 0) {
a_VecChr_printf(w->vc, "Lbl_T(LT%04d);\n%s%s...
a_VecChr_din4(_a_ &sb->vc[0], &sb->vc[1], 0,...
}
w->t0->s = t; return NULL;
}
if (n == 0) return NULL;
if (c == '-') {
tv = MiniCompiler_compile(w, 1); v = MiniCompile...
a_VecChr_printf(w->vc, "Mul(%s, %s, CInt:-1);\n"...
}
if (c == ';') { if (pri == 98) { w->t0->s = t; retu...
if (c == '(') { v = MiniCompiler_compile(w, 99); a_T...
tt = Token1_get(w->t0); if (w->t0->c == ':') { // コ...
a_VecChr_printf(w->vc, "Lbl_T(%.*s);\n", n, t);
a_VecChr_printf(w->lbl, "#defineX %.*s defEnum(...
goto op1;
}
if (n == 2 && memcmp(t, "if", 2) == 0 && w->t0->c ==...
v = MiniCompiler_compile(w, 99); a_Token1_get(w-...
tt = a_Token1_get(w->t0);
if (w->t0->len == 4 && memcmp(tt, "goto", 4) == ...
tt = a_Token1_get(w->t0); a_VecChr_printf(w-...
}
w->t0->s = t; return NULL;
}
if (n == 3 && memcmp(t, "for", 2) == 0 && w->t0->c =...
MiniCompiler_compile(w, 98); Token1_get(w->t0);
MiniCompiler_Sub *sb = a_VecChr_stkAdd(w->stk, s...
sb->mod = 0;
sb->lb = w->tmpLb; w->tmpLb += 4;
a_VecChr_ini4(_a_ &sb->vc[0], &sb->vc[1], 0, 0);
a_VecChr_printf(w->vc, "Jmp_T(LT%04d);\n", sb->l...
a_VecChr_printf(w->vc, "Lbl_T(LT%04d);\n", sb->l...
a_VecChr *vc0 = w->vc; w->vc = &sb->vc[0];
a_VecChr_printf(w->vc, "Lbl_T(LT%04d);\n", sb->l...
v = MiniCompiler_compile(w, 98); Token1_get(w->t...
if (v == NULL) { a_VecChr_printf(w->vc, "Jmp_T(L...
else { a_VecChr_printf(w->vc, "Jne(%s, CInt:0, T...
w->vc = &sb->vc[1];
v = MiniCompiler_compile(w, 98); Token1_get(w->t...
w->vc = vc0; w->tmpNo = 0;
tt = a_Token1_get(w->t0); if (w->t0->c != '{') {...
goto op1;
}
if (n == 13 && memcmp(t, "Mul64Shr_RRRI", 13) == 0) {
for (;;) {
Token1_get(w->t0); if (w->t0->c == ';') break;
}
a_VecChr_printf(w->vc, "%.*s\n", w->t0->s - t, t);
goto op1;
}
if (n == 7 && memcmp(t, "openWin", 7) == 0) goto cF...
if (n == 6 && memcmp(t, "setPix", 6) == 0) goto cF...
if (n == 8 && memcmp(t, "flushWin", 8) == 0) goto cF...
if (n == 7 && memcmp(t, "waitInf", 7) == 0) goto cF...
if (n == 6 && memcmp(t, "printf", 6) == 0) {
cFunc:
a_VecChr vc0[1]; a_VecChr_ini(_a_ vc0); a_VecChr...
for (;;) {
t = Token1_get(w->t0); if (w->t0->c == ')') ...
if (w->t0->c == ',') continue;
w->t0->s = t; v = MiniCompiler_compile(w, 98...
a_VecChr_printf(w->vc, "Let(%s, %s);\n", tt,...
a_VecChr_printf(vc0, "%s,", tt);
}
n = a_VecChr_N(vc0); if (vc0->p[n - 1] == ',') n...
a_VecChr_printf(w->vc, "%.*s);\n", n, vc0->p); a...
}
w->t0->s = tt; // 一度読み込んだ未解釈の演算子をt0に...
if (n == 3 && memcmp(t, "int", 3) == 0) {
for (;;) {
t = a_Token1_get(w->t0); if (*t == ';') break;
if (*t == ',') continue;
a_VecChr_printf(w->vc, "#defineX %.*s Int:d...
}
w->t0->s = t; goto op1;
}
if (('0' <= *t && *t <= '9') || *t == 0x22) {
v = a_BufFree_malloc(_a_ w->bf, n + 1 + 5);
memcpy(v, "CInt:", 5); memcpy(v + 5, t, n); v[n ...
} else {
v = a_BufFree_malloc(_a_ w->bf, n + 1);
memcpy(v, t, n); v[n] = '\0';
}
op2:
t = Token1_get(w->t0); c = w->t0->c; n = w->t0->len;
if (n == 0) return v;
if (c == ('+' | '+' << 8) && pri >= 1) {
tv = MiniCompiler_newTmp(w);
a_VecChr_printf(w->vc, "Let(%s, %s); Add(%s, %s,...
v = tv; goto op2;
}
if (c == '*' && pri >= 4) { MiniCompil...
if (c == '/' && pri >= 4) { MiniCompil...
if (c == '%' && pri >= 4) { MiniCompil...
if (c == '+' && pri >= 5) { MiniCompil...
if (c == '-' && pri >= 5) { MiniCompil...
if (c == ('<' | '<' << 8) && pri >= 6) { MiniCompil...
if (c == ('>' | '>' << 8) && pri >= 6) { MiniCompil...
if (c == ('<' | '=' << 8) && pri >= 7) { MiniCompil...
if (c == '<' && pri >= 7) { MiniCompil...
if (c == ('>' | '=' << 8) && pri >= 7) { MiniCompil...
if (c == '>' && pri >= 7) { MiniCompil...
if (c == ('=' | '=' << 8) && pri >= 8) { MiniCompil...
if (c == ('!' | '=' << 8) && pri >= 8) { MiniCompil...
if (c == '&' && pri >= 9) { MiniCompil...
if (c == '^' && pri >= 10) { MiniCompil...
if (c == '|' && pri >= 11) { MiniCompil...
if (c == '=' && pri >= 15) { a_VecChr_printf(w->vc,...
if (c == ';' && pri >= 98) { if (pri == 98) { w->t0...
w->t0->s = t; return v; // 一度読み込んだ未解釈の演...
}
** (99) 更新履歴
-2026.04.25(土) 初版
-2026.04.27(月) 誤記修正
ページ名: