a4_0010
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* acl4のページ0010
-(by [[K]], 2026.02.06)
** (1)
#if (a_Version >= 1)
#define Preprocessor_Eval a_Preprocessor_Eval
#define Preprocessor_eval a_Preprocessor_eval
#define Preprocessor_If a_Preprocessor_If
#define Preprocessor_if0 a_Preprocessor_if0
#define Preprocessor_if2 a_Preprocessor_if2
#define Preprocessor_if3 a_Preprocessor_if3
#endif
a_class(a_Preprocessor_Eval) { char err; };
a_static intptr_t a_Preprocessor_eval(a_Preprocessor_Eva...
// この関数の利用者は、 pri=0x7fff として呼び出すことを...
{
const char *t = a_Token1_get(t0); intptr_t i = 0, j,...
if (n == 0 || c == ('/' | '/' << 8)) { w->err = 1; r...
if (c == '(') {
i = a_Preprocessor_eval(w, t0, 99);
a_Token1_get(t0);
if (t0->c != ')') w->err = 1;
goto op2;
}
if (c == '+' && pri >= 2) { i = + a_Preprocessor_eva...
if (c == '-' && pri >= 2) { i = - a_Preprocessor_eva...
if (c == '!' && pri >= 2) { i = ! a_Preprocessor_eva...
if (c == '~' && pri >= 2) { i = ~ a_Preprocessor_eva...
if ('0' <= *t && *t <= '9') {
i = strtol(t, NULL, 0);
} else if (n >= 2 && *t == 0x27) { // '...'
a_VecChr vc[1]; a_VecChr_ini(vc); a_VecChr_puts(...
a_VecChr_convEsc(vc); vc->p[vc->n] = '\0'; i = v...
a_VecChr_din(vc);
} else if (&t[n] < t0->s1 && t[n] == '(') {
// 未定義マクロの引数部分を読み飛ばす. 値は0とす...
a_Token1_get(t0);
a_VecChr dmy[1]; a_VecChr_ini(dmy);
a_parseArgs(t0, dmy);
if (t0->c != ')') w->err = 1;
a_VecChr_din(dmy);
}
// それ以外の知らないトークンは引数なし未定義マクロ...
op2:
t = a_Token1_get(t0); c = t0->c; n = t0->len;
// if (n == 0) { w->err = 1; return i; }
if (c == '*' && pri >= 4) { i = i * a...
if (c == '+' && pri >= 5) { i = i + a...
if (c == '-' && pri >= 5) { i = i - a...
if (c == ('<' | '<' << 8) && pri >= 6) { i = i << a...
if (c == ('>' | '>' << 8) && pri >= 6) { i = i >> a...
if (c == ('<' | '=' << 8) && pri >= 7) { i = i <= a...
if (c == '<' && pri >= 7) { i = i < a...
if (c == ('>' | '=' << 8) && pri >= 7) { i = i >= a...
if (c == '>' && pri >= 7) { i = i > a...
if (c == ('=' | '=' << 8) && pri >= 8) { i = i == a...
if (c == ('!' | '=' << 8) && pri >= 8) { i = i != a...
if (c == '&' && pri >= 9) { i = i & a...
if (c == '^' && pri >= 10) { i = i ^ a...
if (c == '|' && pri >= 11) { i = i | a...
if (c == ('&' | '&' << 8) && pri >= 12) { i = i && a...
if (c == ('|' | '|' << 8) && pri >= 13) { i = i || a...
if (c == '/' && pri >= 4) {
j = a_Preprocessor_eval(w, t0, 3);
if (j != 0) { i = i / j; } else { w->err = 1; i ...
goto op2;
}
if (c == '%' && pri >= 4) {
j = a_Preprocessor_eval(w, t0, 3);
if (j != 0) { i = i % j; } else { w->err = 1; i ...
goto op2;
}
t0->s = t; return i; // 一度読み込んだ未解釈の演算子...
}
a_class(a_Preprocessor_If) {
a_VecChr stk[1];
char phase;
int (*eval)(a_Preprocessor_Eval *, a_Token0 *, int);
a_Preprocessor_Eval *w_eval;
};
a_static void a_Preprocessor_if0(a_Preprocessor_If *w)
{
a_VecChr_ini(w->stk); a_VecChr_reserve(w->stk, 16); ...
w->phase = 1;
}
a_static int a_Preprocessor_if2(a_Preprocessor_If *w, a_...
{
intptr_t n = t0->len; (void) linBuf;
w->w_eval->err = 0;
if (n == 2 && memcmp(t, "if", 2) == 0) {
a_VecChr_resizeDiff(_arg_ w->stk, 1); char *sp ...
if ((sp[-1] & 1) != 0 && w->eval(w->w_eval, t0, ...
a_Token1_get(t0);
if ((t0->c != 0 && t0->c != ('/' | '/' << 8)) ||...
if ((sp[-1] & 1) != 0) *sp = 5;
w->phase = *sp & 1; return 0;
}
w->phase = *sp & 1;
return 1;
// *spの値の説明: bit0-2に意味がある.
// bit0: phaseの値.
// bit1: 今はthen節の中にいるのか?それともels...
// bit2: if~elif~elif~...~else~endif のか...
// このbit2は意外に重要で、なぜならどこかで...
}
if (n == 4 && memcmp(t, "elif", 4) == 0 && w->stk->n...
char *sp = &(w->stk->p[w->stk->n - 1]);
if ((*sp & 2) != 0) return 0; // elseのあとにeli...
*sp &= 6;
if ((sp[-1] & 1) != 0 && (*sp & 4) == 0 && w->ev...
a_Token1_get(t0);
if ((t0->c != 0 && t0->c != ('/' | '/' << 8)) ||...
if ((sp[-1] & 1) != 0) *sp = 5;
w->phase = *sp & 1; return 0;
}
w->phase = *sp & 1;
return 1;
}
if (n == 4 && memcmp(t, "else", 4) == 0 && w->stk->n...
char *sp = &(w->stk->p[w->stk->n - 1]);
if ((*sp & 2) != 0) return 0; // elseのあとにels...
*sp |= 2; *sp &= 6;
if ((sp[-1] & 1) != 0 && (*sp & 4) == 0) *sp = 7;
w->phase = *sp & 1;
return 1;
}
if (n == 5 && memcmp(t, "endif", 5) == 0 && w->stk->...
char *sp = &(w->stk->p[--(w->stk->n) - 1]);
w->phase = *sp & 1;
return 1;
}
return 0;
}
a_static void a_Preprocessor_if3(a_Preprocessor_If *w) {...
** (2) 説明
-Preprocessor_eval:
--プリプロセッサの #if のために作られた評価関数で、整数演...
-Preprocessor_if0:
--Preprocessor_Ifオブジェクトを初期化します。
-Preprocessor_if1:
--この関数に1行と#以降のトークンをgetした値を渡せば、ifde...
--書き換えを行った場合は 1 を返すので、この行の処理を最初...
--この関数は不要になったので削除しました。
-Preprocessor_if2:
--if, elif, else, endifの処理を行います。これらが該当した...
--現在の処理が #if によって無効化されているかどうかは、オ...
-Preprocessor_if3:
--Preprocessor_Ifオブジェクトの解放処理をします。
** (3) サンプルプログラム: t0010a.c (簡易的なプリプロセ...
#define a_Version 1
#include <acl4.c>
void preprocessor_t0010a(VecChr *src, VecChr *dst, Token...
{
VecChr linBuf[1], tmp[1]; VecChr_ini4(linBuf, tmp, 0...
Set0 set[1]; Set0_ini(set); dst->n = 0;
Preprocessor_If ppIf[1]; Preprocessor_if0(ppIf);
Preprocessor_Eval ppEv[1];
ppIf->eval = (void *) Preprocessor_eval; ppIf->w_eva...
int defC = 1;
char *s = src->p, *s1 = src->p + src->n, *t;
for (;;) {
s = VecChr_gets(linBuf, s, s1); // 1行をlinBufに...
if (linBuf->n == 0) break;
for (;;) { // 末尾が "\\\n"であれば、後続行を接続.
char *p1 = linBuf->p + linBuf->n;
if (!(linBuf->n >= 2 && p1[-2] == '\\' && p1...
s = VecChr_gets(tmp, s, s1);
VecChr_replace(linBuf, linBuf->n - 2, 2, tmp...
}
t0->s = linBuf->p; t0->s1 = linBuf->p + linBuf->n;
t = Token1_get(t0);
if (t0->c == '#') {
t = Token1_get(t0);
if (t0->len < 16) {
char ttmp[16]; memcpy(ttmp, t, t0->len);...
if (strstr(ttmp, "def") == NULL && strst...
while (Preprocessor_define2(set, t0,...
t0->s = linBuf->p; t0->s1 = linBuf->...
Token1_get(t0);
t = Token1_get(t0);
}
}
if (Preprocessor_if2(ppIf, linBuf, t0, t) !=...
if (ppIf->phase != 0) {
if (t0->len == 6 && memcmp(t, "define", ...
Preprocessor_define0(set, t0, linBuf...
}
}
} else {
if (ppIf->phase != 0) {
while (Preprocessor_define2(set, t0, lin...
VecChr_puts(dst, linBuf->p, linBuf->p + ...
}
}
}
Preprocessor_define3(set);
Preprocessor_if3(ppIf);
VecChr_din4(linBuf, tmp, 0, 0);
}
int main(int argc, const char **argv)
{
VecChr src[1], dst[1]; VecChr_ini(dst);
VecChr_iniArg(src, argc, argv, 1, 2);
Token0 t0[1]; Token0_ini1(t0);
preprocessor_t0010a(src, dst, t0);
printf("%.*s\n", (int) dst->n, dst->p);
VecChr_din4(src, dst, 0, 0);
a_malloc_debugList(_arg);
}
-include, undef は処理できませんが、それ以外は一通りでき...
--[註] 最初のバージョンでは ifdef 系もできたんですが、今...
-なお、標準的なプリプロセッサとは異なり、同じマクロ名でも...
-t0010a.exe は 17.5KB でした(初期バージョンでは 16.0KB ...
** (99) 更新履歴
-2026.02.06(金) 初版
-2026.02.11(水) エラーチェック機能を強化、 Preprocessor_i...
-2026.02.15(日) a_Preprocessor_eval に '...' の処理が抜け...
終了行:
* acl4のページ0010
-(by [[K]], 2026.02.06)
** (1)
#if (a_Version >= 1)
#define Preprocessor_Eval a_Preprocessor_Eval
#define Preprocessor_eval a_Preprocessor_eval
#define Preprocessor_If a_Preprocessor_If
#define Preprocessor_if0 a_Preprocessor_if0
#define Preprocessor_if2 a_Preprocessor_if2
#define Preprocessor_if3 a_Preprocessor_if3
#endif
a_class(a_Preprocessor_Eval) { char err; };
a_static intptr_t a_Preprocessor_eval(a_Preprocessor_Eva...
// この関数の利用者は、 pri=0x7fff として呼び出すことを...
{
const char *t = a_Token1_get(t0); intptr_t i = 0, j,...
if (n == 0 || c == ('/' | '/' << 8)) { w->err = 1; r...
if (c == '(') {
i = a_Preprocessor_eval(w, t0, 99);
a_Token1_get(t0);
if (t0->c != ')') w->err = 1;
goto op2;
}
if (c == '+' && pri >= 2) { i = + a_Preprocessor_eva...
if (c == '-' && pri >= 2) { i = - a_Preprocessor_eva...
if (c == '!' && pri >= 2) { i = ! a_Preprocessor_eva...
if (c == '~' && pri >= 2) { i = ~ a_Preprocessor_eva...
if ('0' <= *t && *t <= '9') {
i = strtol(t, NULL, 0);
} else if (n >= 2 && *t == 0x27) { // '...'
a_VecChr vc[1]; a_VecChr_ini(vc); a_VecChr_puts(...
a_VecChr_convEsc(vc); vc->p[vc->n] = '\0'; i = v...
a_VecChr_din(vc);
} else if (&t[n] < t0->s1 && t[n] == '(') {
// 未定義マクロの引数部分を読み飛ばす. 値は0とす...
a_Token1_get(t0);
a_VecChr dmy[1]; a_VecChr_ini(dmy);
a_parseArgs(t0, dmy);
if (t0->c != ')') w->err = 1;
a_VecChr_din(dmy);
}
// それ以外の知らないトークンは引数なし未定義マクロ...
op2:
t = a_Token1_get(t0); c = t0->c; n = t0->len;
// if (n == 0) { w->err = 1; return i; }
if (c == '*' && pri >= 4) { i = i * a...
if (c == '+' && pri >= 5) { i = i + a...
if (c == '-' && pri >= 5) { i = i - a...
if (c == ('<' | '<' << 8) && pri >= 6) { i = i << a...
if (c == ('>' | '>' << 8) && pri >= 6) { i = i >> a...
if (c == ('<' | '=' << 8) && pri >= 7) { i = i <= a...
if (c == '<' && pri >= 7) { i = i < a...
if (c == ('>' | '=' << 8) && pri >= 7) { i = i >= a...
if (c == '>' && pri >= 7) { i = i > a...
if (c == ('=' | '=' << 8) && pri >= 8) { i = i == a...
if (c == ('!' | '=' << 8) && pri >= 8) { i = i != a...
if (c == '&' && pri >= 9) { i = i & a...
if (c == '^' && pri >= 10) { i = i ^ a...
if (c == '|' && pri >= 11) { i = i | a...
if (c == ('&' | '&' << 8) && pri >= 12) { i = i && a...
if (c == ('|' | '|' << 8) && pri >= 13) { i = i || a...
if (c == '/' && pri >= 4) {
j = a_Preprocessor_eval(w, t0, 3);
if (j != 0) { i = i / j; } else { w->err = 1; i ...
goto op2;
}
if (c == '%' && pri >= 4) {
j = a_Preprocessor_eval(w, t0, 3);
if (j != 0) { i = i % j; } else { w->err = 1; i ...
goto op2;
}
t0->s = t; return i; // 一度読み込んだ未解釈の演算子...
}
a_class(a_Preprocessor_If) {
a_VecChr stk[1];
char phase;
int (*eval)(a_Preprocessor_Eval *, a_Token0 *, int);
a_Preprocessor_Eval *w_eval;
};
a_static void a_Preprocessor_if0(a_Preprocessor_If *w)
{
a_VecChr_ini(w->stk); a_VecChr_reserve(w->stk, 16); ...
w->phase = 1;
}
a_static int a_Preprocessor_if2(a_Preprocessor_If *w, a_...
{
intptr_t n = t0->len; (void) linBuf;
w->w_eval->err = 0;
if (n == 2 && memcmp(t, "if", 2) == 0) {
a_VecChr_resizeDiff(_arg_ w->stk, 1); char *sp ...
if ((sp[-1] & 1) != 0 && w->eval(w->w_eval, t0, ...
a_Token1_get(t0);
if ((t0->c != 0 && t0->c != ('/' | '/' << 8)) ||...
if ((sp[-1] & 1) != 0) *sp = 5;
w->phase = *sp & 1; return 0;
}
w->phase = *sp & 1;
return 1;
// *spの値の説明: bit0-2に意味がある.
// bit0: phaseの値.
// bit1: 今はthen節の中にいるのか?それともels...
// bit2: if~elif~elif~...~else~endif のか...
// このbit2は意外に重要で、なぜならどこかで...
}
if (n == 4 && memcmp(t, "elif", 4) == 0 && w->stk->n...
char *sp = &(w->stk->p[w->stk->n - 1]);
if ((*sp & 2) != 0) return 0; // elseのあとにeli...
*sp &= 6;
if ((sp[-1] & 1) != 0 && (*sp & 4) == 0 && w->ev...
a_Token1_get(t0);
if ((t0->c != 0 && t0->c != ('/' | '/' << 8)) ||...
if ((sp[-1] & 1) != 0) *sp = 5;
w->phase = *sp & 1; return 0;
}
w->phase = *sp & 1;
return 1;
}
if (n == 4 && memcmp(t, "else", 4) == 0 && w->stk->n...
char *sp = &(w->stk->p[w->stk->n - 1]);
if ((*sp & 2) != 0) return 0; // elseのあとにels...
*sp |= 2; *sp &= 6;
if ((sp[-1] & 1) != 0 && (*sp & 4) == 0) *sp = 7;
w->phase = *sp & 1;
return 1;
}
if (n == 5 && memcmp(t, "endif", 5) == 0 && w->stk->...
char *sp = &(w->stk->p[--(w->stk->n) - 1]);
w->phase = *sp & 1;
return 1;
}
return 0;
}
a_static void a_Preprocessor_if3(a_Preprocessor_If *w) {...
** (2) 説明
-Preprocessor_eval:
--プリプロセッサの #if のために作られた評価関数で、整数演...
-Preprocessor_if0:
--Preprocessor_Ifオブジェクトを初期化します。
-Preprocessor_if1:
--この関数に1行と#以降のトークンをgetした値を渡せば、ifde...
--書き換えを行った場合は 1 を返すので、この行の処理を最初...
--この関数は不要になったので削除しました。
-Preprocessor_if2:
--if, elif, else, endifの処理を行います。これらが該当した...
--現在の処理が #if によって無効化されているかどうかは、オ...
-Preprocessor_if3:
--Preprocessor_Ifオブジェクトの解放処理をします。
** (3) サンプルプログラム: t0010a.c (簡易的なプリプロセ...
#define a_Version 1
#include <acl4.c>
void preprocessor_t0010a(VecChr *src, VecChr *dst, Token...
{
VecChr linBuf[1], tmp[1]; VecChr_ini4(linBuf, tmp, 0...
Set0 set[1]; Set0_ini(set); dst->n = 0;
Preprocessor_If ppIf[1]; Preprocessor_if0(ppIf);
Preprocessor_Eval ppEv[1];
ppIf->eval = (void *) Preprocessor_eval; ppIf->w_eva...
int defC = 1;
char *s = src->p, *s1 = src->p + src->n, *t;
for (;;) {
s = VecChr_gets(linBuf, s, s1); // 1行をlinBufに...
if (linBuf->n == 0) break;
for (;;) { // 末尾が "\\\n"であれば、後続行を接続.
char *p1 = linBuf->p + linBuf->n;
if (!(linBuf->n >= 2 && p1[-2] == '\\' && p1...
s = VecChr_gets(tmp, s, s1);
VecChr_replace(linBuf, linBuf->n - 2, 2, tmp...
}
t0->s = linBuf->p; t0->s1 = linBuf->p + linBuf->n;
t = Token1_get(t0);
if (t0->c == '#') {
t = Token1_get(t0);
if (t0->len < 16) {
char ttmp[16]; memcpy(ttmp, t, t0->len);...
if (strstr(ttmp, "def") == NULL && strst...
while (Preprocessor_define2(set, t0,...
t0->s = linBuf->p; t0->s1 = linBuf->...
Token1_get(t0);
t = Token1_get(t0);
}
}
if (Preprocessor_if2(ppIf, linBuf, t0, t) !=...
if (ppIf->phase != 0) {
if (t0->len == 6 && memcmp(t, "define", ...
Preprocessor_define0(set, t0, linBuf...
}
}
} else {
if (ppIf->phase != 0) {
while (Preprocessor_define2(set, t0, lin...
VecChr_puts(dst, linBuf->p, linBuf->p + ...
}
}
}
Preprocessor_define3(set);
Preprocessor_if3(ppIf);
VecChr_din4(linBuf, tmp, 0, 0);
}
int main(int argc, const char **argv)
{
VecChr src[1], dst[1]; VecChr_ini(dst);
VecChr_iniArg(src, argc, argv, 1, 2);
Token0 t0[1]; Token0_ini1(t0);
preprocessor_t0010a(src, dst, t0);
printf("%.*s\n", (int) dst->n, dst->p);
VecChr_din4(src, dst, 0, 0);
a_malloc_debugList(_arg);
}
-include, undef は処理できませんが、それ以外は一通りでき...
--[註] 最初のバージョンでは ifdef 系もできたんですが、今...
-なお、標準的なプリプロセッサとは異なり、同じマクロ名でも...
-t0010a.exe は 17.5KB でした(初期バージョンでは 16.0KB ...
** (99) 更新履歴
-2026.02.06(金) 初版
-2026.02.11(水) エラーチェック機能を強化、 Preprocessor_i...
-2026.02.15(日) a_Preprocessor_eval に '...' の処理が抜け...
ページ名: