diff options
Diffstat (limited to 'source/state.cpp')
-rw-r--r-- | source/state.cpp | 68 |
1 files changed, 52 insertions, 16 deletions
diff --git a/source/state.cpp b/source/state.cpp index a2f424c..5daa772 100644 --- a/source/state.cpp +++ b/source/state.cpp @@ -18,27 +18,63 @@ #include "core.hpp" #include "state.hpp" -//#include <csetjmp> +#include <csetjmp> #include <cstring> -//static std::jmp_buf jmpbuf; -Cell *SP = DICT.data() + DICT.size() - DS; -Cell *RP = DICT.data() + DICT.size() - DS - RS; FuncList IP = nullptr; - std::array<Cell, DictSize> DICT; Cell& HERE = DICT[DIdxHere]; Cell& LATEST = DICT[DIdxLatest]; Cell& STATE = DICT[DIdxState]; -void executor(FuncList *list) +static std::jmp_buf jmpbuf; +static Cell *SP = DICT.data() + DICT.size() - DS; +static Cell *RP = DICT.data() + DICT.size() - DS - RS; + +void push(Cell value) { + if (SP >= DICT.data() + DICT.size()) + std::longjmp(jmpbuf, static_cast<int>(Error::push)); + + *++SP = value; +} + +Cell pop() { + if (SP - 1 < DICT.data() + DICT.size() - DS) + std::longjmp(jmpbuf, static_cast<int>(Error::pop)); + + return *SP--; +} + +Cell *sp() { + return SP; +} + +void rpush(Cell value) { + if (RP >= DICT.data() + DICT.size() - DS) + std::longjmp(jmpbuf, static_cast<int>(Error::rpush)); + + *++RP = value; +} + +Cell rpop() { + if (RP - 1 < DICT.data() + DICT.size() - DS - RS) + std::longjmp(jmpbuf, static_cast<int>(Error::rpop)); + + return *RP--; +} + +Cell *rp() { + return RP; +} + +Error executor(FuncList *list) { - // TODO Use setjmp to recover from errors? - /*if (setjmp(jmpbuf) == 0)*/ { + auto result = static_cast<Error>(setjmp(jmpbuf)); + FuncList body; - FuncList body; - void (*entry)(FuncList); + if (static_cast<int>(result) == 0) { + result = Error::none; // We are given the pointer to a list of function pointers. // Dereference once to retrieve the function pointer list. @@ -65,19 +101,19 @@ entry: // their "calls". // If the word is pre-defined then the argument will simply be // ignored. - entry = (void (*)(FuncList))*body; - entry(body); + auto func = (void (*)(FuncList))*body; + func(body); } - - //std::longjmp(jmpbuf, 1); } + + return result; } -void execute1(Word *word) +Error execute1(Word *word) { // IP must initially be zero if executing a word at the top level. IP = 0; - executor(&word->list); + return executor(&word->list); } Word *find(const char *s, int len) |