Question

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?

Was it helpful?

Solution

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);
}

OTHER TIPS

All of this below is based on an assumption: You want to declare function pointers.

typedef int (*OPCODE)(char *);

struct Word 
{
    struct Word* next;
    char* name;
    OPCODE *opcode;
    // int arg_count;
};

opcode is a function pointer to a function that returns an integer and takes a char * as the argument. A really good page of short tutorials on function pointers is The Function Pointer Tutorials by Lars Engelfried.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top