aboutsummaryrefslogtreecommitdiffstats
path: root/libalee/state.cpp
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2023-03-11 07:36:11 -0500
committerClyne Sullivan <clyne@bitgloo.com>2023-03-11 07:36:11 -0500
commitbc3e952b487365fdf5e60e9fcfa0841c23972e30 (patch)
treecc53facc2a62db4dc93a25c772f521786305ead8 /libalee/state.cpp
parentf8270776e79f4d2edb7c2a19c1ecd3bf3b2bf153 (diff)
common error enum; eval to _ev
Diffstat (limited to 'libalee/state.cpp')
-rw-r--r--libalee/state.cpp36
1 files changed, 31 insertions, 5 deletions
diff --git a/libalee/state.cpp b/libalee/state.cpp
index b3c98b1..bfd29d1 100644
--- a/libalee/state.cpp
+++ b/libalee/state.cpp
@@ -19,6 +19,7 @@
#include "corewords.hpp"
#include "state.hpp"
+#include <cstring>
#include <iterator>
bool State::compiling() const
@@ -31,11 +32,25 @@ void State::compiling(bool yes)
dict.write(Dictionary::Compiling, yes);
}
-State::Error State::execute(Addr addr)
+std::pair<Addr, std::jmp_buf> State::save()
{
- auto stat = static_cast<State::Error>(setjmp(jmpbuf));
+ std::pair<Addr, std::jmp_buf> st;
+ st.first = ip;
+ std::memcpy(st.second, jmpbuf, sizeof(std::jmp_buf));
+ return st;
+}
+
+void State::load(const std::pair<Addr, std::jmp_buf>& st)
+{
+ ip = st.first;
+ std::memcpy(jmpbuf, st.second, sizeof(std::jmp_buf));
+}
+
+Error State::execute(Addr addr)
+{
+ auto stat = static_cast<Error>(setjmp(jmpbuf));
- if (stat == State::Error::none) {
+ if (stat == Error::none) {
CoreWords::run(addr, *this);
if (ip >= Dictionary::Begin) {
@@ -46,13 +61,24 @@ State::Error State::execute(Addr addr)
// addr was a CoreWord, all done now.
ip = 0;
}
- } else if (stat == State::Error::exit) {
- stat = State::Error::none;
+ } else if (stat == Error::exit) {
+ stat = Error::none;
}
return stat;
}
+void State::reset()
+{
+ while (size())
+ pop();
+ while (rsize())
+ popr();
+
+ dict.write(Dictionary::Compiling, 0);
+ ip = 0;
+}
+
std::size_t State::size() const noexcept
{
return std::distance(dstack, static_cast<const Cell *>(dsp));