acl4の開発ログ

2026.03.17(火) #2

// tt0003b.c

// (tt0003a.cと同じ部分は省略).

a_static void *VecChr_stkTop(a_VecChr *w, intptr_t sz) { return w->p + w->n - sz; }

a_class(MiniCompiler_Sub) {
    int mod;
    int lb; VecChr vc[2];
        // mod=0: for文.
        //   lb+0:continue0, lb+1:continue, lb+2:break.
        //   vc0:繰り返し条件, vc1:cotinue時のインクリメント処理など.
};

a_class(MiniCompiler) {
    a_Token0 *t0;
    a_BufFree bf[1];
    a_VecChr *vc;
    a_VecChr stk[1];
    int tmpNo, tmpLb, autoClose;
};

a_static void MiniCompiler_ini(MiniCompiler *w)
{
    a_BufFree_ini(w->bf); a_VecChr_ini(w->stk); w->tmpNo = 0; w->tmpLb = 0; w->autoClose = 0;
}

a_static void MiniCompiler_din(MiniCompiler *w)
{
    a_BufFree_flush(w->bf); a_BufFree_din(w->bf); a_VecChr_din(w->stk);
}

a_static char *MiniCompiler_newTmp(MiniCompiler *w)
{
    char s[256];
    intptr_t n = sprintf(s, "tmp%d", w->tmpNo++);
    char *v = a_BufFree_malloc(w->bf, n + 1);
    memcpy(v, s, n + 1);
    return v;
}

#define MiniCompiler_compile_Macro0(pri, fmt)   vv = MiniCompiler_compile(w, pri); tv = MiniCompiler_newTmp(w); a_VecChr_printf(w->vc, fmt, tv, v, vv); v = tv; goto op2

a_static char *MiniCompiler_compile(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 == '}') {
        MiniCompiler_Sub *sb = VecChr_stkTop(w->stk, sizeof (MiniCompiler_Sub));
        if (sb->mod == 0) {
            a_VecChr_printf(w->vc, "Lbt(LT%04d);\n%s%sLbt(LT%04d);\n", sb->lb + 1, sb->vc[1].p, sb->vc[0].p, sb->lb + 2);
            a_VecChr_din4(&sb->vc[0], &sb->vc[1], 0, 0); w->stk->n -= sizeof (MiniCompiler_Sub); goto op1;
        }
        w->t0->s = t; return NULL;
    }
    if (n == 0) return NULL;
    if (c ==  ';') { if (pri == 98) { w->t0->s = t; return NULL; } a_VecChr_printf(w->vc, "Semi();\n"); w->autoClose *= -1; goto op1; }
    if (c == '(') { v = MiniCompiler_compile(w, 99); a_Token1_get(w->t0); goto op2; }
    tt = Token1_get(w->t0); if (w->t0->c == ':') { a_VecChr_printf(w->vc, "Lbt(%.*s);\n", n, t); goto op1; } // コードラベル宣言.
    if (n == 2 && memcmp(t, "if", 2) == 0 && w->t0->c == '(') {
        v = 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, 0, %.*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 == '(') {
        MiniCompiler_compile(w, 98); Token1_get(w->t0);
        MiniCompiler_Sub *sb = a_VecChr_stkAdd(w->stk, sizeof (MiniCompiler_Sub));
        sb->mod = 0;
        sb->lb = w->tmpLb; w->tmpLb += 3;
        a_VecChr_ini4(&sb->vc[0], &sb->vc[1], 0, 0);
        a_VecChr_printf(w->vc, "Lbt(LT%04d);\n", sb->lb + 0);
        a_VecChr *vc0 = w->vc; w->vc = &sb->vc[0];
        v = MiniCompiler_compile(w, 98); Token1_get(w->t0);
        if (v == NULL) { a_VecChr_printf(w->vc, "Jmp(LT%04d);\n", sb->lb + 0); }
        else { a_VecChr_printf(w->vc, "Jne(%s, 0, LT%04d);\n", v, sb->lb + 0); }
        w->vc = &sb->vc[1];
        v = MiniCompiler_compile(w, 98); Token1_get(w->t0); // ')'
        w->vc = vc0;
        tt = a_Token1_get(w->t0); if (w->t0->c != '{') { w->t0->s = tt; w->autoClose--; }
        goto op1;
    }
    w->t0->s = tt; // 一度読み込んだ未解釈の演算子をt0に押し戻す.
    v = a_BufFree_malloc(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 ==  '*' && pri >=  4)             { MiniCompiler_compile_Macro0( 3, "Mul(%s, %s, %s);\n"); }
    if (c ==  '/' && pri >=  4)             { MiniCompiler_compile_Macro0( 3, "Div(%s, %s, %s);\n"); }
    if (c ==  '%' && pri >=  4)             { MiniCompiler_compile_Macro0( 3, "Mod(%s, %s, %s);\n"); }
    if (c ==  '+' && pri >=  5)             { MiniCompiler_compile_Macro0( 4, "Add(%s, %s, %s);\n"); }
    if (c ==  '-' && pri >=  5)             { MiniCompiler_compile_Macro0( 4, "Sub(%s, %s, %s);\n"); }
    if (c == ('<' | '=' << 8) && pri >=  7) { MiniCompiler_compile_Macro0( 6, "Cle(%s, %s, %s);\n"); }
    if (c ==  '<'             && pri >=  7) { MiniCompiler_compile_Macro0( 6, "Clt(%s, %s, %s);\n"); }
    if (c == ('>' | '=' << 8) && pri >=  7) { MiniCompiler_compile_Macro0( 6, "Cge(%s, %s, %s);\n"); }
    if (c ==  '>'             && pri >=  7) { MiniCompiler_compile_Macro0( 6, "Cgt(%s, %s, %s);\n"); }
    if (c == ('=' | '=' << 8) && pri >=  8) { MiniCompiler_compile_Macro0( 7, "Ceq(%s, %s, %s);\n"); }
    if (c == ('!' | '=' << 8) && pri >=  8) { MiniCompiler_compile_Macro0( 7, "Cne(%s, %s, %s);\n"); }
    if (c == '='  && pri >= 15) { a_VecChr_printf(w->vc, "Let(%s, %s);\n", v, 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->autoClose *= -1; goto op1; }
    w->t0->s = t; return v; // 一度読み込んだ未解釈の演算子をt0に押し戻してからreturn.
}
// 実行結果.
>tt0003b "s=0; for (i=0;i<10;i=i+1) s=s+i;"
Let(s, 0);
Semi();
Let(i, 0);
Lbt(LT0000);
Add(tmp2, s, i);
Let(s, tmp2);
Semi();
Lbt(LT0001);
Add(tmp1, i, 1);
Let(i, tmp1);
Clt(tmp0, i, 10);
Jne(tmp0, 0, LT0000);
Lbt(LT0002);
ans: (null)

>tt0003b "s=0; for (i=0;i<10;i=i+1) for (j=0;j<10;j=j+1) s=s+i*j;"
Let(s, 0);
Semi();
Let(i, 0);
Lbt(LT0000);
Let(j, 0);
Lbt(LT0003);
Mul(tmp4, i, j);
Add(tmp5, s, tmp4);
Let(s, tmp5);
Semi();
Lbt(LT0004);
Add(tmp3, j, 1);
Let(j, tmp3);
Clt(tmp2, j, 10);
Jne(tmp2, 0, LT0003);
Lbt(LT0005);
Lbt(LT0001);
Add(tmp1, i, 1);
Let(i, tmp1);
Clt(tmp0, i, 10);
Jne(tmp0, 0, LT0000);
Lbt(LT0002);
ans: (null)

2026.03.18(水) #0

2026.03.18(水) #1

2026.03.18(水) #2

こめんと欄


コメントお名前NameLink

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS