Merge pull request #1 from pzembrod/c-volksforth

C volksforth
This commit is contained in:
Carsten Strotmann 2020-06-24 18:38:41 +00:00 committed by GitHub
commit 5b1f1ef22c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 0 deletions

17
portable/Idea.md Normal file
View File

@ -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.

5
portable/README.md Normal file
View File

@ -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.

63
portable/core.c Normal file
View File

@ -0,0 +1,63 @@
// 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 wont 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 + 1; // + 1 assuming direct threaded code where at core[w]
// is sitting the 1 byte virtual opcode for "next".
}
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;
}