#include "kll0.h"
KSrc *src;
KLexer *lx;
KSizPtr *varSp;
unsigned char *code;
int qc;
void sub_print(int i) { printf("%d\n", i); }
void sub_exit() { exit(0); }
void sub_list()
{
for (int i = 0, i1 = src->ln.sp.sizPtr(); i < i1; i++) {
KSrcLine *pl = (KSrcLine *) src->ln.sp.getPtr(i);
printf("%4d %.*s\n", pl->ln, pl->src.s, pl->src.p);
}
}int compile(int l, const char *s, int ln)
{
static KPhraseCmp *phr = NEW1(kautoreleasePool, KPhraseCmp)(32, 100, lx->sid);
while (l > 0 && s[l - 1] == '\n')
l--;
lx->sp->s = 0;
int i0 = *lx->sid->n;
lx->add(l, (const char *) s);
KLexer_Elmt *le = (KLexer_Elmt *) lx->add(1, ";")->p, *lp;
int i1 = *lx->sid->n, *var = (int *) varSp->reserve(i1 * sizeof (int))->p, pc = 0;
for (int i = i0; i < i1; i++)
var[i] = lx->getConstInt(i); // intではないときは0を返す.
for (int pc1 = lx->getElmtLen(); pc < pc1; pc++) {
phr->setPr(le, 0, pc, pc1);
lp = &le[pc];
if (phr->cmpPr( 1, "@ ;")) continue;
if (phr->cmpPr( 2, "@ @* = @* ;")) { qc += kputBin(&code[qc], "8b_85_%i32 89_85_%i32", lp[2].i * 4, lp[0].i * 4);
} else if (phr->cmpPr( 3, "@ @* = @* + @* ;")) { qc += kputBin(&code[qc], "8b_85_%i32 03_85_%i32 89_85_%i32", lp[2].i * 4, lp[4].i * 4, lp[0].i * 4);
} else if (phr->cmpPr( 4, "@ @* = @* - @* ;")) { qc += kputBin(&code[qc], "8b_85_%i32 2b_85_%i32 89_85_%i32", lp[2].i * 4, lp[4].i * 4, lp[0].i * 4);
} else if (phr->cmpPr( 5, "@ PRINT @* ;")) { qc += kputBin(&code[qc], "8b_85_%i32 89_04_24 e8_%r32", lp[1].i * 4, sub_print);
} else if (phr->cmpPr( 6, "@ EXIT ;")) { qc += kputBin(&code[qc], "e8_%r32", sub_exit);
} else if (phr->cmpPr( 7, "@ LIST ;")) { qc += kputBin(&code[qc], "e8_%r32", sub_list);
} else
goto err;
while (le[pc].i != 0)
pc++;
}
return 0;
err:
if (l >= 30)
l = 30;
printf("syntax error [%d] : %.*s\n\n", ln, l, le[pc].p0);
return 1;
}
int main() {
code = (unsigned char *) kmallocRWX(1024 * 1024);
lx = NEW1(kautoreleasePool, KLexer)(NEW1(kautoreleasePool, KStringId)(1, "; = + - PRINT EXIT LIST"));
varSp = NEW1(kautoreleasePool, KSizPtr)(kmemPool);
char *cmdlin = (char *) kautoreleasePool->alloc(65536), *p;
src = NEW1(kautoreleasePool, KSrc);
for (;;) {
ok:
printf("Ok\n");
skip:
fgets(cmdlin, 65536, stdin);
for (p = cmdlin; *p == ' ' || *p == '\t'; p++);
if (*p == '\n') goto skip;
kupperCaseM(strlen(p), (unsigned char *) p, lx->chrTyp);
if ('0' <= *p && *p <= '9') {
src->editLine(strchr(p, '\n') - p, p);
goto skip;
}
qc = 0;
qc += kputBin(&code[qc], "60 83_ec_7c 0xbd_%i32"); // PUSHAD. SUB ESP,124. MOV EBP,0. この命令でスタックを調整させる.
if (strncmp(p, "RUN", 3) == 0 && p[3] <= ' ') {
int i, i1 = src->ln.sp.sizPtr();
for (i = 0; i < i1; i++) {
KSrcLine *pl = (KSrcLine *) src->ln.sp.getPtr(i);
if (compile(pl->src.s, pl->src.p, pl->ln) != 0) goto ok;
}
} else {
if (compile(strlen(p), p, -1) != 0) goto ok;
}
qc += kputBin(&code[qc], "83_c4_7c 61 c3"); // ADD ESP,124. 最初に調整したスタックを元に戻す. POPAD. RET.
kputBin(&code[5], "%i32", varSp->p);
((void (*)()) code)(); // codeを関数呼び出し.
printf("\n");
}
}
| コメント | お名前 | NameLink | |