* acl4のページt0003
-(by [[K]], 2026.05.04)

** (1) 概要
-a4_t0003 は、 acl4v1 の2番目の補助ライブラリプログラムになります。
-補助ライブラリというのは、 acl4 ライブラリに加えられるほどきちんと書いてないけど、しかしそれなりには有用なのでライブラリ化はしておきたい、くらいの意味合いです。
-提供される主な機能は、以下の通りです。
--(1-1)DB/DW/DDで構成されたソースコードを解釈し、メモリに書き込む関数(アセンブラの最終処理)
--(1-2)
--(1-1)DB/DW/DDで構成されたソースコードを解釈し、メモリに書き込む関数(アセンブラなどで使われる)
--(1-2)C言語用のミニコンパイラの最初のバージョン

** (2) デモ



** (3) ライブラリプログラム
 // #include <windows.h> してあることが前提.
 a_static void *a_mallocRWX(intptr_t siz) { return VirtualAlloc(0, siz, MEM_COMMIT, PAGE_EXECUTE_READWRITE); } // 参考: https://essen.osask.jp/?a21_txt02
 
 a_static intptr_t a_putBin(const char *s, intptr_t sn, char *b, intptr_t bn, a_Token0 *t0, a_Preprocessor_Eval *ev)
 {
     a_VecChr lbl[1]; a_VecChr_ini(_a_ lbl);
     intptr_t pass, bi, *pi, *bp = (intptr_t *) b;
     for (pass = 0; pass < 2; pass++) {
         t0->s = s; t0->s1 = s + sn; bi = 0;
         for (;;) {
             const char *t = a_Token1_get(t0); intptr_t n = t0->len, i, j, k, m;
             if (t0->c == ',' || t0->c == ';') continue;
             if (t0->c == 0) break;
             if (bn - bi < 16) { a_VecChr_din(_a_ lbl); return -1; }
             if (n == 3 && memcmp(t, "LBL",  3) == 0) {
                 i = a_Preprocessor_eval(ev, t0, 0x7fff);
                 a_VecChr_reserve(lbl, (i + 1) * sizeof (intptr_t));
                 pi = (intptr_t *) lbl->p; pi[i] = (intptr_t) &b[bi];
             }
             m = 0;
             if (n == 4 && memcmp(t, "DB_L", 4) == 0) m = 1;
             if (n == 4 && memcmp(t, "DW_L", 4) == 0) m = 2;
             if (n == 4 && memcmp(t, "DD_L", 4) == 0) m = 4;
             if (m > 0) {
                 a_Token1_get(t0); i = a_Preprocessor_eval(ev, t0, 0x7fff);
                 a_Token1_get(t0); j = a_Preprocessor_eval(ev, t0, 0x7fff);
                 a_Token1_get(t0); k = a_Preprocessor_eval(ev, t0, 0x7fff); Token1_get(t0);
                 if (i == 1) { i = (intptr_t) &b[bi]; } else { a_VecChr_reserve(lbl, (i + 1) * sizeof (intptr_t)); pi = (intptr_t *) lbl->p; i = pi[i]; }
                 if (j == 1) { j = (intptr_t) &b[bi]; } else { a_VecChr_reserve(lbl, (j + 1) * sizeof (intptr_t)); pi = (intptr_t *) lbl->p; j = pi[j]; }
                 i = i - j + k;
                 goto db_i;
             }
             m = 0;
             if (n == 4 && memcmp(t, "DB_R", 4) == 0) m = 1;
             if (n == 4 && memcmp(t, "DW_R", 4) == 0) m = 2;
             if (n == 4 && memcmp(t, "DD_R", 4) == 0) m = 4;
             if (m > 0) {
                 i = a_Preprocessor_eval(ev, t0, 0x7fff);
                 i = i - (intptr_t) &b[bi];
                 goto db_i;
             }
             m = 0;
             if (n == 2 && memcmp(t, "DB",   2)  == 0) m = 1;
             if (n == 2 && memcmp(t, "DW",   2)  == 0) m = 2;
             if (n == 2 && memcmp(t, "DD",   2)  == 0) m = 4;
             if (m > 0) {
                 i = a_Preprocessor_eval(ev, t0, 0x7fff);
 db_i:
                            b[bi++] =  i        & 0xff;
                 if (m > 1) b[bi++] = (i >>  8) & 0xff;
                 if (m > 2) b[bi++] = (i >> 16) & 0xff;
                 if (m > 3) b[bi++] = (i >> 24) & 0xff;
             }
             if (n == 2 && memcmp(t, "DP",   2)  == 0)
                 bp[bi++] = a_Preprocessor_eval(ev, t0, 0x7fff);
         }
     }
     a_VecChr_din(_a_ lbl);
     return bi;
 }
 
 a_static void a_conv_pp(const char *s, intptr_t sn, a_VecChr *dst, int flg, int dbg, const char *msg, FILE *fp, const char *incl)
 {
     a_VecChr vc[1]; a_VecChr_ini(_a_ vc);
     if ((flg & 1) != 0) a_VecChr_N(dst) = 0;
     if ((flg & 2) == 0)
         a_VecChr_printf(vc, "imm<%s>:#include \"%s.h\"\n%.*s", incl, incl, sn, s);
     else
         a_VecChr_printf(vc, "imm<%s>:%.*s", incl, sn, s);
     a_Preprocessor_ini1(vc->p, VecChr_N(vc), (flg >> 4) & 0xf, dst);
     if (dbg != 0) fprintf(fp, msg, VecChr_N(dst), dst->p);
     a_VecChr_din(_a_ vc);
 }
 
 a_static void a_convVc_pp(VecChr *src, VecChr *dst, int flg, int dbg, const char *msg, FILE *fp, const char *incl)
 {
     a_conv_pp(src->p, VecChr_N(src), dst, flg, dbg, msg, fp, incl);
 }
 
 a_class(a_AsmDbConstTable) { a_SetElm elm[1]; intptr_t v; };
 
 a_static int a_eval_hook1(a_Preprocessor_Eval *w, a_Token0 *t0, int pri, const char *t, intptr_t *pi)
 {
     a_BufFree *bf = w->v[0];
     a_VecChr *vcTmp = w->v[1];
     a_Set0 *set = w->v[2];
     intptr_t n = t0->len; (void) pri;
     if (n >= 2 && t[0] == 0x22) {
         char *s;
         a_VecChr_N(vcTmp) = 0; a_VecChr_puts(vcTmp, t + 1, n - 2);
         a_VecChr_convEsc(vcTmp);
         *pi = (intptr_t) (s = a_BufFree_malloc(_a_ bf, a_VecChr_N(vcTmp) + 1));
         memcpy(s, vcTmp->p, a_VecChr_N(vcTmp) + 1);
         return 1;
     }
     a_AsmDbConstTable *elm = a_Set0_findKn(set, t, n);
     if (elm != NULL) { *pi = elm->v; return 1; }
     return 0;
 }
 
 a_static intptr_t a_conv_asmDb_bin(const char *s, intptr_t sn, char *b, intptr_t bn1, a_AsmDbConstTable *t, intptr_t tn, a_BufFree *bf)
 {
     a_Token0 t0[1]; a_Token0_ini1(t0); a_VecChr vc[1]; a_VecChr_ini(_a_ vc);
     a_Set0 set[1]; a_Set0_ini(_a_ set, NULL); intptr_t i;
     for (i = 0; i < tn; i++) {
         t[i].elm->n = strlen(t[i].elm->k);
         a_Set0_add(set, t[i].elm);
     }
     a_Preprocessor_Eval ev[1]; a_Preprocessor_Eval_ini(_a_ ev); ev->err = 0;
     ev->hook1 = a_eval_hook1; ev->v[0] = bf; ev->v[1] = vc; ev->v[2] = set;
     intptr_t bn = a_putBin(s, sn, b, bn1, t0, ev);
     a_VecChr_din(_a_ vc); a_Set0_din(_a_ set); a_Preprocessor_Eval_din(_a_ ev);
     return bn;
 }
 
 a_class(a_MiniCompiler_Sub) {
     int mod;
     int lb; a_VecChr vc[2];
     // mod=0: for文.
     //   lb+0:continue0, lb+1:continue, lb+2:continue2, lb+3:break.
     //   vc0:繰り返し条件, vc1:cotinue時のインクリメント処理など.
 };
 
 a_class(a_MiniCompiler) {
     a_Token0 *t0;
     a_BufFree bf[1];
     a_VecChr *vc;
     a_VecChr stk[1], lbl[1];
     int tmpNo, tmpLb, autoClose;
 };
 
 a_static void a_MiniCompiler_ini(a_MiniCompiler *w)
 {
     a_BufFree_ini(_a_ w->bf); a_VecChr_ini4(_a_ w->stk, w->lbl, 0, 0); w->tmpNo = 0; w->tmpLb = 0; w->autoClose = 0;
 }
 
 a_static void a_MiniCompiler_din(a_MiniCompiler *w)
 {
     a_BufFree_flush(_a_ w->bf); a_BufFree_din(_a_ w->bf); a_VecChr_din4(_a_ w->stk, w->lbl, 0, 0);
 }
 
 a_static char *a_MiniCompiler_newTmp(a_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 a_MiniCompiler_compile_Macro0(pri, fmt)   vv = a_MiniCompiler_compile(w, pri); tv = a_MiniCompiler_newTmp(w); a_VecChr_printf(w->vc, fmt, tv, v, vv); v = tv; goto op2
 
 a_static char *a_MiniCompiler_compile(a_MiniCompiler *w, int pri)
 {
     char *v, *tv, *vv;
 op1:
     const char *tt, *t = a_Token1_get(w->t0); intptr_t n = w->t0->len; uint32_t c = w->t0->c;
     if (w->autoClose > 0) { w->t0->s = t; c = '}'; w->autoClose--; }
     if (c == '}') {
         a_MiniCompiler_Sub *sb = VecChr_stkTop(w->stk, sizeof (a_MiniCompiler_Sub));
         if (sb->mod == 0) {
             a_VecChr_printf(w->vc, "Lbl_T(LT%04d);\n%s%sLbl_T(LT%04d);\n", sb->lb + 1, sb->vc[1].p, sb->vc[0].p, sb->lb + 3);
             a_VecChr_din4(_a_ &sb->vc[0], &sb->vc[1], 0, 0); a_VecChr_stkRmv(w->stk, sizeof (a_MiniCompiler_Sub)); goto op1;
         }
         w->t0->s = t; return NULL;
     }
     if (n == 0) return NULL;
     if (c == '-') {
         tv = a_MiniCompiler_compile(w, 1); v = a_MiniCompiler_newTmp(w);
         a_VecChr_printf(w->vc, "Mul(%s, %s, CInt:-1);\n", v, tv); goto op2;
     }
     if (c ==  ';') { if (pri == 98) { w->t0->s = t; return NULL; } a_VecChr_printf(w->vc, "Semi();\n"); w->tmpNo = 0; w->autoClose *= -1; goto op1; }
     if (c == '(') { v = a_MiniCompiler_compile(w, 99); a_Token1_get(w->t0); goto op2; } // (...)
     tt = a_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(1)\n", n, t);
         goto op1;
     }
     if (n == 2 && memcmp(t, "if", 2) == 0 && w->t0->c == '(') {
         v = a_MiniCompiler_compile(w, 99); a_Token1_get(w->t0); // ')'.
         tt = a_Token1_get(w->t0);
         if (w->t0->len == 4 && memcmp(tt, "goto", 4) == 0) {
             tt = a_Token1_get(w->t0); a_VecChr_printf(w->vc, "Jne(%s, CInt:0, Txt:%.*s);\n", v, w->t0->len, tt); goto op1;
         }
         w->t0->s = t; return NULL;
     }
     if (n == 3 && memcmp(t, "for", 2) == 0 && w->t0->c == '(') {
         a_MiniCompiler_compile(w, 98); Token1_get(w->t0);
         a_MiniCompiler_Sub *sb = a_VecChr_stkAdd(w->stk, sizeof (a_MiniCompiler_Sub));
         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->lb + 2);
         a_VecChr_printf(w->vc, "Lbl_T(LT%04d);\n", sb->lb + 0);
         a_VecChr *vc0 = w->vc; w->vc = &sb->vc[0];
         a_VecChr_printf(w->vc, "Lbl_T(LT%04d);\n", sb->lb + 2);
         v = a_MiniCompiler_compile(w, 98); Token1_get(w->t0);
         if (v == NULL) { a_VecChr_printf(w->vc, "Jmp_T(LT%04d);\n", sb->lb + 0); }
         else { a_VecChr_printf(w->vc, "Jne(%s, CInt:0, Txt:LT%04d);\n", v, sb->lb + 0); }
         w->vc = &sb->vc[1];
         v = a_MiniCompiler_compile(w, 98); a_Token1_get(w->t0); // ')'
         w->vc = vc0; w->tmpNo = 0;
         tt = a_Token1_get(w->t0); if (w->t0->c != '{') { w->t0->s = tt; w->autoClose--; }
         goto op1;
     }
     if (n == 13 && memcmp(t, "Mul64Shr_RRRI", 13) == 0) {
         for (;;) {
             a_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 cFunc;
     if (n == 6 && memcmp(t, "setPix",   6) == 0) goto cFunc;
     if (n == 8 && memcmp(t, "flushWin", 8) == 0) goto cFunc;
     if (n == 7 && memcmp(t, "waitInf",  7) == 0) goto cFunc;
     if (n == 6 && memcmp(t, "printf",   6) == 0) {
 cFunc:
         a_VecChr vc0[1]; a_VecChr_ini(_a_ vc0); a_VecChr_printf(vc0, "%.*s(", n, t);
         for (;;) {
             t = Token1_get(w->t0); if (w->t0->c == ')') break;
             if (w->t0->c == ',') continue;
             w->t0->s = t; v = a_MiniCompiler_compile(w, 98); tt = a_MiniCompiler_newTmp(w);
             a_VecChr_printf(w->vc, "Let(%s, %s);\n", tt, v);
             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_VecChr_din(_a_ vc0); v = "tmp0"; goto op2;
     }
     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:defEnum(0)\n", w->t0->len, t);
         }
         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 + 5] = '\0';
     } else {
         v = a_BufFree_malloc(_a_ w->bf, n + 1);
         memcpy(v, t, n); v[n] = '\0';
     }
 op2:
     t = a_Token1_get(w->t0); c = w->t0->c; n = w->t0->len;
     if (n == 0) return v;
     if (c == ('+' | '+' << 8) && pri >=  1)  {
         tv = a_MiniCompiler_newTmp(w);
         a_VecChr_printf(w->vc, "Let(%s, %s); Add(%s, %s, CInt:1);\n", tv, v, v, v);
         v = tv; goto op2;
     }
     if (c ==  '*'             && pri >=  4) { a_MiniCompiler_compile_Macro0( 3, "Mul(%s, %s, %s);\n"); }
     if (c ==  '/'             && pri >=  4) { a_MiniCompiler_compile_Macro0( 3, "Div(%s, %s, %s);\n"); }
     if (c ==  '%'             && pri >=  4) { a_MiniCompiler_compile_Macro0( 3, "Mod(%s, %s, %s);\n"); }
     if (c ==  '+'             && pri >=  5) { a_MiniCompiler_compile_Macro0( 4, "Add(%s, %s, %s);\n"); }
     if (c ==  '-'             && pri >=  5) { a_MiniCompiler_compile_Macro0( 4, "Sub(%s, %s, %s);\n"); }
     if (c == ('<' | '<' << 8) && pri >=  6) { a_MiniCompiler_compile_Macro0( 5, "Shl(%s, %s, %s);\n"); }
     if (c == ('>' | '>' << 8) && pri >=  6) { a_MiniCompiler_compile_Macro0( 5, "Shr(%s, %s, %s);\n"); }
     if (c == ('<' | '=' << 8) && pri >=  7) { a_MiniCompiler_compile_Macro0( 6, "Cle(%s, %s, %s);\n"); }
     if (c ==  '<'             && pri >=  7) { a_MiniCompiler_compile_Macro0( 6, "Clt(%s, %s, %s);\n"); }
     if (c == ('>' | '=' << 8) && pri >=  7) { a_MiniCompiler_compile_Macro0( 6, "Cge(%s, %s, %s);\n"); }
     if (c ==  '>'             && pri >=  7) { a_MiniCompiler_compile_Macro0( 6, "Cgt(%s, %s, %s);\n"); }
     if (c == ('=' | '=' << 8) && pri >=  8) { a_MiniCompiler_compile_Macro0( 7, "Ceq(%s, %s, %s);\n"); }
     if (c == ('!' | '=' << 8) && pri >=  8) { a_MiniCompiler_compile_Macro0( 7, "Cne(%s, %s, %s);\n"); }
     if (c ==  '&'             && pri >=  9) { a_MiniCompiler_compile_Macro0( 8, "And(%s, %s, %s);\n"); }
     if (c ==  '^'             && pri >= 10) { a_MiniCompiler_compile_Macro0( 9, "Xor(%s, %s, %s);\n"); }
     if (c ==  '|'             && pri >= 11) { a_MiniCompiler_compile_Macro0(10, "Or_(%s, %s, %s);\n"); }
     if (c == '='  && pri >= 15) { a_VecChr_printf(w->vc, "Let(%s, %s);\n", v, a_MiniCompiler_compile(w, 15)); goto op2; }
     if (c ==  ';' && pri >= 98) { if (pri == 98) { w->t0->s = t; return v; } a_VecChr_printf(w->vc, "Semi();\n"); w->tmpNo = 0; w->autoClose *= -1; goto op1; }
     w->t0->s = t; return v; // 一度読み込んだ未解釈の演算子をt0に押し戻してからreturn.
 }
 
 void a_conv_clang_clout(const char *s, intptr_t sn, a_VecChr *dst, int flg)
 {
     if ((flg & 1) != 0) a_VecChr_N(dst) = 0;
     a_Token0 t0[1]; a_Token0_ini1(t0);
     t0->s = s; t0->s1 = s + sn;
     a_MiniCompiler mc[1]; a_MiniCompiler_ini(mc); mc->t0 = t0; mc->vc = dst;
     a_MiniCompiler_compile(mc, 99); a_VecChr_replace(dst, 0, 0, mc->lbl->p, a_VecChr_N(mc->lbl)); 
     a_MiniCompiler_din(mc); a_VecChr_reserve0(dst);
 }
 
 void a_convVc_clang_clout(a_VecChr *src, a_VecChr *dst, int flg) { a_conv_clang_clout(src->p, a_VecChr_N(src), dst, flg); }



** (99) 更新履歴
-2026.05.04(月) 初版

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS