Writing an AVR Forth shell
Continuing along with an implementation of a Forth shell for the Arduino, I've been thinking about how to better access the registers.
Right now, the stack stores only 16-bit integers. I think it will have to be modified to store variables as well. A variable would be defined as something akin to
struct s_stackval {
uint8_t kind; /* enum here for variable or immediate */
uint16_t ival;
char *word;
};
This feels hacky, though.
Reading a value off the stack might look something like
struct s_stackval sv;
uint16_t x;
/* ... */
case '+':
sv = stack_pop();
if (K_IMM == sv.kind) {
x = sv.ival;
} else if (K_VAR == sv.kind) {
x = read_var(sv.word);
} else {
serial_write((char *)BADWORD, 10);
return;
}
sv = stack_pop();
if (K_IMM == sv.kind) {
x += sv.ival;
} else if (K_VAR == sv.kind) {
x += read_var(sv.word);
} else {
serial_write((char *)BADWORD, 10);
return;
}
stack_push(x);
serial_write((char *)OK, 4);
/* ... */
and maybe a read_var implementation with a hash table storing the
current value of the variable. It might have to be something like
struct s_variable {
char *name;
uint8_t is_register;
uint16_t val;
};
If is_register is set, the word will be read from using a special
register reading function; otherwise, return the value.
I also need to consider memory usage here; working with 2K of RAM doesn't offer one much breathing room.