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.


Tags: , , ,