acl4のプログラムのページ0006
(1) C言語に変換したい
- a4_p0005で実行は簡単にできました。
- 今度は実行するのではなく、「C言語に変換する」っていうのをやってみます。つまりトランスパイラです(トランスコンパイラとも言います)。
- C言語に変換できれば、高速に実行することもできます(きっとコンパイラが最適化してくれるので)。
(2) p0006a.c [16行] : 即興で作ったトランスパイラ
#define a_Version 1
#include <acl4.c>
int main(int argc, const char **argv)
{
if (argc < 2) return 1;
Preprocessor pp[1]; Preprocessor_ini(pp); // プリプロセッサの初期化.
Preprocessor_SourceFiles_addFile(pp->sfs, argv[1], strlen(argv[1])); // 入力ファイルを指定.
Preprocessor_SourceFiles_addFile(pp->sfs, "a4vm-asm-p0006a.h", 17); // 最初にこれをインクロードさせる.
VecChr vc[1]; VecChr_ini(vc); pp->put0->dst = vc; // 出力先のオブジェクトを指定.
Preprocessor_main(pp); Preprocessor_din(pp); // プリプロセッサ処理. およびメモリ開放.
printf("%.*s}\n", (int) vc->n, vc->p);
VecChr_din(vc);
a_malloc_debugList(_arg);
return 0;
}
- 適当に作った定義ファイル: a4vm-asm-p0006a.h (内容は仮です。たぶん全部作り直します。)
#include <stdio.h>
int main()
{
int R00, R01, R02, R03;
#define Lod_RI(r,i) r = (i);
#define Lbl_T(t) t:
#define Add_RR(r,s) r += s;
#define Add_RI(r,i) r += (i);
#define Jle_RIT(r,i,t) if (r <= (i)) goto t;
#define Jlt_RIT(r,i,t) if (r < (i)) goto t;
#define Dbg_Ret_R(r) return r;
#define Dbg_Ret_I(i) return i;
#define Dbg_Putc_R(r) putchar(r);
#define Dbg_Putc_I(i) putchar(i);
#define Dbg_PutDec_R(r) printf("%d", r);
(3) 実行結果
- p0004a0.txt:
#define c R00 // 整数レジスタ
#define lp L0000 // ラベル
Lod_RI(c, 0x20)
Lbl_T(lp)
Dbg_Putc_R(c)
Add_RI(c, 1)
Jlt_RIT(c, 0x7f, lp)
Dbg_Putc_I('\n')
Dbg_Ret_I(0)
>p0006a p0004a0.txt
#line 1 "a4vm-asm-p0006a.h"
#include <stdio.h>
int main()
{
int R00, R01, R02, R03;
#line 3 "p0004a0.txt"
R00 = (0x20);
L0000:
putchar(R00);
R00 += (1);
if (R00 < (0x7f)) goto L0000;
putchar('\n');
return 0;
}
- こんな感じでちゃんと動いています。これをリダイレクトしてファイルにしてCコンパイラでコンパイルすれば、もちろん動きます。
- p0005a0.txt:
#define i R00 // 整数レジスタ
#define s R01
#define lp L0000 // ラベル
Lod_RI(s, 0)
Lod_RI(i, 0)
Lbl_T(lp)
Add_RR(s, i)
Add_RI(i, 1)
Jle_RIT(i, 1000, lp)
Dbg_PutDec_R(s)
Dbg_Putc_I('\n')
Dbg_Ret_I(0)
>p0006a p0005a0.txt
#line 1 "a4vm-asm-p0006a.h"
#include <stdio.h>
int main()
{
int R00, R01, R02, R03;
#line 4 "p0005a0.txt"
R01 = (0);
R00 = (0);
L0000:
R01 += R00;
R00 += (1);
if (R00 <= (1000)) goto L0000;
printf("%d", R01);
putchar('\n');
return 0;
}
(4) 考察
- アセンブラの構文体系を xxx(...) の形式で作っておけば、アセンブラ・実行エンジン・トランスパイラはすごく簡単に作れることが分かりました。
- 低級言語はこれが一番いいんじゃないかと思います。
(99) 更新履歴