acl4の開発ログ #08

2026.03.14(土) #0

2026.03.14(土) #1

2026.03.15(日) #0

2026.03.15(日) #1

2026.03.16(月) #0

2026.03.17(火) #0

2026.03.17(火) #1

// tt0003a.c (memo: p0002b.c を参考にして作った)

#define a_Version 1
#include <acl4.c>

a_class(a_BufFree) { a_VecChr stk[1]; };
a_static void a_BufFree_ini(a_BufFree *w) { a_VecChr_ini(w->stk); }
a_static void a_BufFree_din(a_BufFree *w) { a_VecChr_din(w->stk); }

a_static void a_BufFree_add(a_BufFree *w, void *p, intptr_t sz)
{
    void **t = a_VecChr_stkAdd(w->stk, 2 * sizeof (void *));
    t[0] = p; t[1] = (void *) sz;
}

a_static void *a_BufFree_malloc(a_BufFree *w, intptr_t sz)
{
    void *p = a_malloc(_arg_  sz); a_BufFree_add(w, p, sz); return p;
}

a_static void a_BufFree_flush(a_BufFree *w)
{
    while (w->stk->n > 0) {
        w->stk->n -= 2 * sizeof (void *);
        void **t = (void **) (w->stk->p + w->stk->n);
        a_free(_arg_  t[0], (intptr_t) t[1]);
    }
}

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

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

a_static void MiniCompiler_din(MiniCompiler *w)
{
    a_BufFree_flush(w->bf); a_BufFree_din(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(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)
{
    const char *t = Token1_get(w->t0); intptr_t n = w->t0->len; uint32_t c = w->t0->c;
    char *v, *tv, *vv;
    if (n == 0) return NULL;
    if (c == '(') { v = MiniCompiler_compile(w, 99); Token1_get(w->t0); goto op2; }
    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 == '='  && pri >= 15) { a_VecChr_printf(w->vc, "Let(%s, %s);\n", v, MiniCompiler_compile(w, 15)); goto op2; }
    if (c ==  ';' && pri >= 98) { a_VecChr_printf(w->vc, "Semi();\n"); v = MiniCompiler_compile(w, 97); goto op2; }
    w->t0->s = t; return v; // 一度読み込んだ未解釈の演算子をt0に押し戻してからreturn.
}

int main(int argc, const char **argv)
{
    VecChr src[1], dst[1]; VecChr_iniArg(src, argc, argv, 1, 3);
    Token0 t0[1]; Token0_ini1(t0);
    t0->s = src->p; t0->s1 = src->p + src->n;
    MiniCompiler mc[1]; MiniCompiler_ini(mc); mc->t0 = t0;
    VecChr_ini(dst); mc->vc = dst;
    char *v = MiniCompiler_compile(mc, 99);
    if (v == NULL) v = "(null)";
    printf("%sans: %s\n", dst->p, v);
    MiniCompiler_din(mc);
    VecChr_din4(src, dst, 0, 0);
    a_malloc_debugList(_arg);
    return 0;
}
実行結果:
>tt0003a "x=y=1+2*3; (a+b)*c"
Mul(tmp0, 2, 3);
Add(tmp1, 1, tmp0);
Let(y, tmp1);
Let(x, y);
Semi();
Add(tmp2, a, b);
Mul(tmp3, tmp2, c);
ans: tmp3

こめんと欄


コメントお名前NameLink

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