commit 5d1c6000a76f2eb7f32b5da1d07647fe105d3f06
parent cea8998261c6915e453edc02bad8b0fb13da105d
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Wed, 3 Aug 2022 17:58:20 -0400
cvm: we have a mainloop!
Diffstat:
2 files changed, 96 insertions(+), 26 deletions(-)
diff --git a/posix/tmpboot.fs b/posix/tmpboot.fs
@@ -1 +1 @@
-Hello 'X'
+'X' (emit) bye
diff --git a/posix/vm.c b/posix/vm.c
@@ -62,8 +62,7 @@ static void rpush(dword d) { vm.RSP -= 4; sd(vm.RSP, d); }
static dword here() { return gd(HERE); }
static void allot(dword n) { sd(HERE, here()+n); }
static dword current() { return gd(CURRENT); }
-static dword find(char* name) {
- byte slen = strlen(name);
+static dword _find(byte *name, byte slen) {
dword a = current();
byte len;
while (a) {
@@ -75,6 +74,9 @@ static dword find(char* name) {
}
return 0;
}
+static dword find(char *name) {
+ return _find((byte*)name, strlen(name));
+}
static void cwrite(byte b) {
sb(here(), b);
allot(1);
@@ -94,6 +96,17 @@ static void callwr(dword a) {
dwrite(a);
}
static void callword(dword addr); // forward declaration
+static void _entry(byte *name, byte slen) {
+ memcpy(&vm.mem[here()], name, slen);
+ allot(slen);
+ dwrite(current());
+ cwrite(slen);
+ sd(CURRENT, here());
+}
+static void entry(char *name) {
+ _entry((byte*)name, strlen(name));
+}
+
// Operations
@@ -137,6 +150,7 @@ static void QUIT() { // op: 06
static void ABORT() { // op: 07
vm.PSP = PSTOP;
+ sd(COMPILING, 0);
QUIT();
}
@@ -588,7 +602,75 @@ err:
ppush(0);
}
-#define OPCNT 0x51
+// ( a1 a2 u -- f )
+static void REQ() { // op: 51
+ dword u = ppop();
+ dword a2 = ppop();
+ dword a1 = ppop();
+ ppush(memcmp(&vm.mem[a1], &vm.mem[a2], u) == 0);
+}
+
+static void FIND() { // op: 52
+ dword s = ppop();
+ byte len = gb(s++);
+ ppush(_find(&vm.mem[s], len));
+}
+
+static void APOS() { // op: 53
+ WORD();
+ FIND();
+ if (!ppeek()) WNF();
+}
+
+static void ENTRY() { // op: 54
+ dword s = ppop();
+ byte len = gb(s++);
+ _entry(&vm.mem[s], len);
+}
+
+static void XTCOMP() { // op: 55
+ sd(COMPILING, 1);
+ while (gd(COMPILING)) {
+ WORD();
+ PARSE();
+ if (ppop()) {
+ LITN();
+ } else {
+ ppush(CURWORD);
+ FIND();
+ if (!ppeek()) { WNF(); return; }
+ if (gb(ppeek()-1) & 0x80) { // immediate
+ callword(ppop());
+ } else {
+ EXECUTEWR();
+ }
+ }
+ }
+ EXITWR();
+}
+
+static void DOCOL() { // op: 56
+ WORD();
+ ENTRY();
+ XTCOMP();
+}
+
+static void STOPCOL() { // op: 57
+ sd(COMPILING, 0);
+}
+
+static void RUNWORD() { // op: 58
+ PARSE();
+ if (!ppop()) {
+ ppush(CURWORD);
+ FIND();
+ if (!ppeek()) { WNF(); return; }
+ callword(ppop());
+ STACKCHK();
+ }
+}
+
+#define OPCNT 0x59
static void (*ops[OPCNT])() = {
BR, CALL, RET, LIT, BYE, BYEFAIL, QUIT, ABORT,
EXECUTE, CELL, VAL, ALIAS, DOES, SLIT, CBR, NEXT,
@@ -600,7 +682,8 @@ static void (*ops[OPCNT])() = {
ADD, SUB, MUL, DIVMOD, AND, OR, XOR, BOOL,
NOT, LT, SHLC, SHRC, LSHIFT, RSHIFT, LITN, EXECUTEWR,
EXITWR, MOVE, MOVEWR, RTYPE, WNF, STACKCHK, MAYBEWORD, WORD,
- PARSE};
+ PARSE, REQ, FIND, APOS, ENTRY, XTCOMP, DOCOL, STOPCOL,
+ RUNWORD};
static char *opnames[OPCNT] = {
"(br)", NULL, NULL, NULL, "bye", "bytefail", "quit", "(abort)",
@@ -613,7 +696,8 @@ static char *opnames[OPCNT] = {
"+", "-", "*", "/mod", "and", "or", "xor", "bool",
"not", "<", "<<c", ">>c", "lshift", "rshift", "litn", "execute,",
"exit,", "move", "move,", "rtype", "(wnf)", "stack?", "maybeword", "word",
- "parse"};
+ "parse", "[]=", "find", "'", "entry", "xtcomp", ":", ";",
+ "runword"};
static void oprun1() { // run next op
byte opcode = vm.mem[vm.PC++];
@@ -633,19 +717,12 @@ static void callword(dword addr) {
oldPC = vm.PC;
vm.PC = addr;
while (vm.PC && (vm.PC < MEMSZ)) oprun1();
- vm.PC = oldPC;
+ if (vm.PC < MEMSZ) {
+ vm.PC = oldPC;
+ }
}
// Dictionary building
-static void entry(char *name) {
- dword len = strlen(name);
- memcpy(&vm.mem[here()], name, len);
- allot(len);
- dwrite(current());
- cwrite(len);
- sd(CURRENT, here());
-}
-
static void opentry(byte op) {
entry(opnames[op]);
cwrite(op);
@@ -678,16 +755,9 @@ static void buildsysdict() {
lblmain = here();
sd(0x01, lblmain);
callwr(find("word"));
- callwr(find("dup"));
- callwr(find("1+"));
- callwr(find("swap"));
- callwr(find("c@"));
- callwr(find("rtype"));
- callwr(find("word"));
- callwr(find("parse"));
- callwr(find("drop"));
- callwr(find("(emit)"));
- callwr(find("bye"));
+ callwr(find("runword"));
+ cwrite(0x00); // BR
+ dwrite(lblmain);
}
// Interpret loop