aboutsummaryrefslogtreecommitdiffstats
path: root/source/state.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/state.cpp')
-rw-r--r--source/state.cpp68
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)