From f5b950094659c1f4494847d257a40dafd98fdb1f Mon Sep 17 00:00:00 2001 From: Philip Zembrod Date: Tue, 23 Jun 2020 21:53:51 +0200 Subject: [PATCH 1/2] Initial idea sketch for a C-based VolksForth core. --- portable/README.md | 5 ++++ portable/core.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 portable/README.md create mode 100644 portable/core.c diff --git a/portable/README.md b/portable/README.md new file mode 100644 index 0000000..1943603 --- /dev/null +++ b/portable/README.md @@ -0,0 +1,5 @@ +# Idea for a "C-VolksForth" + +So far anything in this directory is just an early idea for a C-based +core of a VolksForth variant that could be compiled and run on any +platform with a C compiler, e.g. Linux. diff --git a/portable/core.c b/portable/core.c new file mode 100644 index 0000000..50308b9 --- /dev/null +++ b/portable/core.c @@ -0,0 +1,62 @@ + +// This is only a sketch of an idea yet. + + +byte core[0x10000]; + +uint16 ip; +uint16 w; + +void run() { + while (true) { + next(); + } +} + +void next() { + w = *((uint16*) core + ip); + ip += 2; + byte opcode = core[w]; + // on second thought, the above looks more like direct threaded, + // which is maybe not what we want in a C core for VolksForth. + // Or is it? + process(opcode); +} + +void process(byte opcode) { + if (opcode & 0xc0) { + // handle special opcode + // This is assuming we won’t have more than 64 C primitives, + // and might have use for a few + // opcodes with inlined parameters. Not sure about this, though. + } else { + jumptable[opcode](); + } +} + +void jumptable[0x40]() = { + nest, unnest, dup, drop, plus, emit +}; + +void nest() { + rs[rp++] = ip; + ip = w + 2; +} + +void unnest() { + ip = rs[--rp]; +} + +void dup() { + uint16 = s[sp]; + s[++sp] = uint16; +} + +void emit() { + putc(s[sp--]); +} + +void plus() { + a = s[sp--]; + s[sp] += a; +} From 2b99999cf90b308f02fd7a73f76977e940d598f7 Mon Sep 17 00:00:00 2001 From: Philip Zembrod Date: Tue, 23 Jun 2020 22:26:00 +0200 Subject: [PATCH 2/2] Update nest() to DTC. Add Idea.md --- portable/Idea.md | 17 +++++++++++++++++ portable/core.c | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 portable/Idea.md diff --git a/portable/Idea.md b/portable/Idea.md new file mode 100644 index 0000000..a825e20 --- /dev/null +++ b/portable/Idea.md @@ -0,0 +1,17 @@ +# A virtual C-implemented VM as core for a portable VolksForth + +Basic idea is a Forth VM with direct or indirect threaded code, +operating on a 64kB byte array core, implemented in C. +For compatibility with the other VolksForth flavours we would likely +let data stack and return stack live inside the core, not in separate +C data structures. + +Forth primitives like nest, unnest, dup, emit, + etc. are implemnted +as C functions. Each primitive has a virtual bytecode opcode associated +with it. These virtual opcodes usually sit in the CFA of Forth words. + +Yet TBD is whether it is worth enhancing the execution of these opcodes +to a virtual bytecode CPU allowing CODE words in Forth code using +these virtual opcodes, or whether each opcode is considered to have +an implicit NEXT call at its end, i.e. only predefined CODE words of +length 1 are supported. diff --git a/portable/core.c b/portable/core.c index 50308b9..8e6ac01 100644 --- a/portable/core.c +++ b/portable/core.c @@ -40,7 +40,8 @@ void jumptable[0x40]() = { void nest() { rs[rp++] = ip; - ip = w + 2; + ip = w + 1; // + 1 assuming direct threaded code where at core[w] + // is sitting the 1 byte virtual opcode for "next". } void unnest() {