川合のプログラミング言語自作のためのテキスト第二版#0010

  • (by K, 2019.06.30)

(18) TJ-03x

  • 次はTJ-03aを書き直してみます。やってみたら61行になりました。
    #include "kll0.h"
    
    enum { EAX = 0, ECX = 1 };
    
    void sub_print(int i)
    {
        printf("%d\n", i);
    }
    
    void sub_time()
    {
        printf("time=%.3f[sec]\n", clock() / (double) CLOCKS_PER_SEC);
    }
    
    int main(int argc, const char **argv)
    {
        KLexer lx(NEW1(kautoreleasePool, KStringId)("; = + - print while ( < ) { } time"));
        char *txt = (char *) kerrorExitP0(kreadFileA(argv[1], "rt", 2), "usage>%s program-file", argv[0]);
        KLexer_Elmt *le = (KLexer_Elmt *) lx.add(txt)->p;
        int pc = 0, qc = 0, wqc = 0, wqc2 = 0, *var = (int *) kautoreleasePool->alloc((*lx.sid->n) * sizeof (int));
        for (int i = 0; i < *lx.sid->n; i++)
            var[i] = lx.getConstInt(i);	// intではないときは0を返す.
        unsigned char *code = (unsigned char *) kmallocRWX(1024 * 1024);
        qc += kputBin(&code[qc], "83_ec_7c"); // SUB ESP,124.  この命令でスタックを調整させる.
        for (int n = lx.getElmtLen(); pc < n; pc++) {
            if (le[pc + 1].i == 1) { // 2単語目が"=".
                if (le[pc + 3].i == 0) {	// 単純代入.
                    qc += kputBin(&code[qc], "8b_%i8_%i32  a3_%i32", EAX * 8 + 0x05, &var[le[pc + 2].i], &var[le[pc].i]);
                } else if (le[pc + 3].i == 2 && le[pc + 5].i == 0) { // 加算.
                    qc += kputBin(&code[qc], "8b_%i8_%i32  8b_%i8_%i32  01_c8  a3_%i32", EAX * 8 + 0x05, &var[le[pc + 2].i], ECX * 8 + 0x05, &var[le[pc + 4].i], &var[le[pc].i]);
                } else if (le[pc + 3].i == 3 && le[pc + 5].i == 0) { // 減算.
                    qc += kputBin(&code[qc], "8b_%i8_%i32  8b_%i8_%i32  29_c8  a3_%i32", EAX * 8 + 0x05, &var[le[pc + 2].i], ECX * 8 + 0x05, &var[le[pc + 4].i], &var[le[pc].i]);
                } else
                    goto err;
            } else if (le[pc].i == 5 && le[pc + 1].i == 6 && le[pc + 3].i == 7 && le[pc + 5].i == 8 && le[pc + 6].i == 9) {	// while.
                wqc = qc;
                qc += kputBin(&code[qc], "8b_%i8_%i32  8b_%i8_%i32  39_c8  0f_8d_%i32", EAX * 8 + 0x05, &var[le[pc + 2].i], ECX * 8 + 0x05, &var[le[pc + 4].i], &var[le[pc].i], 0);
                wqc2 = qc;
                pc += 7 - 1;
                continue;
            } else if (le[pc].i == 10) {
                qc += kputBin(&code[qc], "e9_%r32", &code[wqc]);
                kputBin(&code[wqc2 - 4], "%r32", &code[qc]);
                continue;
            } else if (le[pc].i == 11 && le[pc + 1].i == 0) { // time.
                qc += kputBin(&code[qc], "e8_%r32", sub_time);
            } else if (le[pc].i == 4 && le[pc + 2].i == 0) { // print.
                qc += kputBin(&code[qc], "8b_%i8_%i32  89_04_24  e8_%r32", EAX * 8 + 0x05, &var[le[pc + 1].i], sub_print);
            } else
                goto err;
            while (le[pc].i != 0)
                pc++;
        }
        qc += kputBin(&code[qc], "83_c4_7c  c3"); // ADD ESP,124.  最初に調整したスタックを元に戻す.  RET.
        void (*func)();	// funcは関数へのポインタ型の変数.
        func = (void (*)()) code;
        func();
        exit(0);
    err:
        kerrorExit("syntax error : %.30s", le[pc].p0);
    }

次回に続く

こめんと欄


コメントお名前NameLink

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-06-30 (日) 09:31:31 (83d)