commit 898f1f22d340085c7f1b42398c3a7f581ae858ad
parent d2f4b058d26f1c624d7108a2a712f468ac6ae49c
Author: Luxferre <lux@ferre>
Date: Mon, 8 Aug 2022 11:07:24 +0300
some instruction progress
Diffstat:
M | equi.c | | | 137 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- |
1 file changed, 122 insertions(+), 15 deletions(-)
diff --git a/equi.c b/equi.c
@@ -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