ES-BASIC #5

(7) ES-BASICのコア部分

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

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