some instruction progress
This commit is contained in:
@@ -245,35 +245,61 @@ uchar popLit() {
|
||||
return ram.literal_stack[--ram.lsp];
|
||||
}
|
||||
|
||||
/* check literal stack and push 4 top values as hex short literal if not empty and discard the rest of the stack */
|
||||
void attemptPushNumericLiteral() {
|
||||
/* clear the literal stack */
|
||||
void clearLit() {
|
||||
ram.lsp = 0; /* clear the literal stack */
|
||||
}
|
||||
|
||||
/* shape 2-byte vlaue on the main stack from the 4 values of the literal stack */
|
||||
void pushLitVal(strict) {
|
||||
uchar p1, p2, p3, p4;
|
||||
if(ram.lsp < 4) { /* if we don't strictly expect 4 bytes, do nothing */
|
||||
if(strict) trapout(STACK_UNDERFLOW);
|
||||
else {
|
||||
ram.lsp = 0; /* clear the literal stack */
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
p4 = popLit();
|
||||
p3 = popLit();
|
||||
p2 = popLit();
|
||||
p1 = popLit();
|
||||
pushMain((p1<<12) | (p2<<8) | (p3<<4) | p4);
|
||||
ram.lsp = 0; /* clear the literal stack */
|
||||
}
|
||||
}
|
||||
|
||||
/* Main interpreter loop */
|
||||
|
||||
void equi_main_loop() {
|
||||
uchar instr;
|
||||
uchar instr, i;
|
||||
/* reset all stacks before running and reinit CLT */
|
||||
ram.msp = ram.rsp = ram.lsp = ram.cltp = 0;
|
||||
/* reset pc */
|
||||
ram.pc = 65535;
|
||||
while(1) { /* iterate over the instructions in the command buffer */
|
||||
instr = ram.cmdbuf[++ram.pc];
|
||||
/* first, check for II mode */
|
||||
if(ram.II) {
|
||||
if(instr == ')')
|
||||
if(instr == INS_IIEND)
|
||||
ram.II = 0; /* unset instruction ignore mode flag */
|
||||
continue;
|
||||
}
|
||||
/* then, check for compilation mode */
|
||||
if(ram.CM) {
|
||||
if(instr == ';') { /* trigger word compilation logic as per the spec */
|
||||
ram.cmdbuf[ram.pc] = 'R'; /* in-place patch this instruction to R */
|
||||
|
||||
if(instr == INS_CMEND) { /* trigger word compilation logic as per the spec */
|
||||
ram.cmdbuf[ram.pc] = INS_RET; /* in-place patch this instruction to R */
|
||||
/* compiled words are saved vice versa to save code size */
|
||||
for(i=0;i<CLT_ENTRY_LEN;++i)
|
||||
ram.clt[ram.cltp].name[i] = popLit();
|
||||
ram.lsp = 0; /* clear the literal stack */
|
||||
ram.clt[ram.cltp].loc = ram.cbp; /* stored the compiled code location from the most recent CBP value */
|
||||
++ram.cltp; /* increase the word */
|
||||
if(ram.cltp == CLT_ENTRIES_MAX) {
|
||||
trapout(CLT_OVERFLOW);
|
||||
break;
|
||||
}
|
||||
|
||||
ram.CM = 0; /* unset compilation mode flag */
|
||||
}
|
||||
continue;
|
||||
@@ -285,11 +311,92 @@ void equi_main_loop() {
|
||||
continue;
|
||||
}
|
||||
/* then trigger literal auto-push if applicable */
|
||||
if(instr != '"' && instr != '\'' && instr != '#' && instr != ':')
|
||||
attemptPushNumericLiteral();
|
||||
switch(instr) {
|
||||
|
||||
default:
|
||||
if(ram.lsp > 0 && instr != INS_LITSTR && instr != INS_LITCALL && instr != INS_LITINT && instr != INS_CMSTART)
|
||||
pushLitVal(0);
|
||||
switch(instr) { /* then perform all main interpretation logic */
|
||||
case INS_IISTART: /* instruction ignore start */
|
||||
ram.II = 1; /* raise II flag */
|
||||
break;
|
||||
case INS_CMSTART: /* compilation start */
|
||||
ram.cbp = ram.pc + 1; /* save CBP */
|
||||
ram.CM = 1; /* raise CM flag */
|
||||
break;
|
||||
case INS_QUIT: /* gracefully quit the interpretation mode */
|
||||
goto brx;
|
||||
case INS_LITINT: /* literal stack -> main stack as short */
|
||||
pushLitVal(1);
|
||||
break;
|
||||
case INS_LITSTR:
|
||||
break;
|
||||
case INS_LITCALL:
|
||||
break;
|
||||
case INS_RET:
|
||||
ram.pc = popRet();
|
||||
break;
|
||||
case INS_M2R:
|
||||
break;
|
||||
case INS_R2M:
|
||||
break;
|
||||
case INS_LOAD:
|
||||
break;
|
||||
case INS_STORE:
|
||||
break;
|
||||
case INS_STOREBYTE:
|
||||
break;
|
||||
case INS_DROP:
|
||||
break;
|
||||
case INS_DUP:
|
||||
break;
|
||||
case INS_SWAP:
|
||||
break;
|
||||
case INS_ROT:
|
||||
break;
|
||||
case INS_OVER:
|
||||
break;
|
||||
case INS_JUMP:
|
||||
break;
|
||||
case INS_IF:
|
||||
break;
|
||||
case INS_EXPOINT: /* Locate execution point */
|
||||
pushMain(ram.pc + 1);
|
||||
break;
|
||||
case INS_GT:
|
||||
break;
|
||||
case INS_LT:
|
||||
break;
|
||||
case INS_EQ:
|
||||
break;
|
||||
case INS_ADD:
|
||||
break;
|
||||
case INS_SUB:
|
||||
break;
|
||||
case INS_MUL:
|
||||
break;
|
||||
case INS_DIV:
|
||||
break;
|
||||
case INS_NEG:
|
||||
break;
|
||||
case INS_NOT:
|
||||
break;
|
||||
case INS_AND:
|
||||
break;
|
||||
case INS_OR:
|
||||
break;
|
||||
case INS_XOR:
|
||||
break;
|
||||
case INS_COUT:
|
||||
break;
|
||||
case INS_NBKIN:
|
||||
case INS_BKIN:
|
||||
break;
|
||||
case INS_PORTIO:
|
||||
break;
|
||||
case INS_PERSIST_READ:
|
||||
break;
|
||||
case INS_PERSIST_WRITE:
|
||||
break;
|
||||
default: /* all characters not processed before are invalid instructions */
|
||||
trapout(INVALID_INSTRUCTION);
|
||||
goto brx;
|
||||
}
|
||||
continue;
|
||||
@@ -333,12 +440,12 @@ int main(int argc, char* argv[]) {
|
||||
cputc(instr); /* echo it */
|
||||
#endif
|
||||
--ram.ibp;
|
||||
} else if(instr == '(') { /* process II just to avoid quitting in command mode */
|
||||
} else if(instr == INS_IISTART) { /* process II just to avoid quitting in command mode */
|
||||
#ifdef __CC65__
|
||||
cputc(instr); /* echo it */
|
||||
#endif
|
||||
ram.II = 1;
|
||||
} else if(instr == ')') { /* process II just to avoid quitting in command mode */
|
||||
} else if(instr == INS_IIEND) { /* process II just to avoid quitting in command mode */
|
||||
#ifdef __CC65__
|
||||
cputc(instr); /* echo it */
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user