I'm doing a Forth interpreter in C. I can't decide how to better implement the Forth dictionary.
struct Word {
struct Word* next;
char* name;
int* opcode;
// int arg_count;
}
struct Dictionary {
struct Word words;
int size;
}
opcode
is a sequence of codes - functions of word. So each opcode[i] corresponds to some function. I suppose it should be some table with elements [opcode<->function pointer]. But how to implement it?
We don't know the size of function. We can't use void* (or we can?) since we must somehow having only opcode execute the function.
What should I do?
Some variation on this definition is quite common in traditional Forth implementations:
typedef int cell;
typedef void code_t (struct Word *);
struct Word
{
char name[NAME_LENGTH];
struct Word *next;
code_t *code;
cell body[]; /* Upon instantiation, this could be zero or more items. */
};
The dictionary will then be a list linked through the next
pointer. The words are allocated sequentially, interleaving the struct Word
header, and the body
data.
To execute a word, call word->code(word);
. The function pointed to by code
can then decide what to do with body
. The body could be data, or it could be what you call "opcodes".
A colon defintion will have code
pointing at something like this:
void docolon (struct Word *word)
{
/* IP is a variable holding the instruction pointer. */
rpush (IP); /* Push the current instruction pointer to the return stack. */
IP = (struct Word *)word->body; /* Start executing the word body (opcodes). */
}
Whereas a primitive word, e.g. +
would look like
void plus (struct Word *word)
{
cell n1 = pop();
cell n2 = pop();
push (n1 + n2);
}