]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
more refactoring, object organization
authorClyne Sullivan <clyne@bitgloo.com>
Fri, 13 Oct 2023 14:13:31 +0000 (10:13 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Fri, 13 Oct 2023 14:13:31 +0000 (10:13 -0400)
libalee/corewords.cpp
libalee/parser.cpp
libalee/state.cpp
libalee/state.hpp

index 34125bd66e9baf081b8b9d7580715854cceb0814..e9b9f47690a01a4d05ac684b5b1dfbaa5bd7fa48 100644 (file)
@@ -44,6 +44,8 @@ void CoreWords::run(Cell ins, State& state)
 
     Addr index = ins;
 
+    auto& ip = state.ip();
+
     auto popd = [](State& s) {
         DoubleCell dcell = s.pop();
         dcell <<= sizeof(Cell) * 8;
@@ -59,8 +61,8 @@ void CoreWords::run(Cell ins, State& state)
 execute:
     if (index >= Dictionary::Begin) {
         // must be calling a defined subroutine
-        state.pushr(state.ip);
-        state.ip = index;
+        state.pushr(ip);
+        ip = index;
         return;
     } else switch (index) {
     case 0: // _lit
@@ -154,22 +156,21 @@ execute:
     case 22: // colon
         state.push(state.dict.alignhere());
         while (!state.dict.hasInput())
-            state.input(state);
+            state.input();
         state.dict.addDefinition(state.dict.input());
         state.compiling(true);
         break;
     case 23: // tick
         while (!state.dict.hasInput())
-            state.input(state);
+            state.input();
         find(state, state.dict.input());
         break;
     case 24: // execute
         index = state.pop();
         goto execute;
     case 25: // exit
-        state.ip = state.popr();
-        if (state.ip == 0)
-            std::longjmp(state.jmpbuf, static_cast<int>(Error::exit));
+        ip = state.popr();
+        state.verify(ip != 0, Error::exit);
         break;
     case 26: // semic
         state.dict.add(findi("exit"));
@@ -188,7 +189,7 @@ execute:
         }
         [[fallthrough]];
     case 28: // _jmp
-        state.ip = state.beyondip();
+        ip = state.beyondip();
         return;
     case 29: // depth
         state.push(static_cast<Cell>(state.size()));
@@ -197,12 +198,12 @@ execute:
         state.push(static_cast<Cell>(state.rsize()));
         break;
     case 31: // _in
-        state.input(state);
+        state.input();
         break;
     case 32: // _ex
         {
         const auto st = state.save();
-        state.ip = 0;
+        ip = 0;
         Parser::parseSource(state);
         state.load(st);
         }
@@ -244,7 +245,7 @@ execute:
         break;
     }
 
-    state.ip += sizeof(Cell);
+    ip += sizeof(Cell);
 }
 
 template<typename Iter>
index 2b1d8e11d0af7bcd873361cd8dfbcb4c9621034a..da7ae0b5cf92c246bb36147766f72a389a87e80e 100644 (file)
 #include "ctype.hpp"
 #include "parser.hpp"
 
+#include <algorithm>
+#include <cstring>
+
 Error Parser::parse(State& state, const char *str)
 {
     auto addr = Dictionary::Input;
 
-    Cell len = 0;
-    for (auto ptr = str; *ptr; ++ptr)
-        ++len;
-
+    const auto len = static_cast<Cell>(std::strlen(str));
     state.dict.write(addr, 0);
     state.dict.write(Dictionary::SourceLen, len);
 
@@ -43,15 +43,12 @@ Error Parser::parse(State& state, const char *str)
 
 Error Parser::parseSource(State& state)
 {
-    auto word = state.dict.input();
-    while (word.size() > 0) {
-        if (auto ret = parseWord(state, word); ret != Error::none)
-            return ret;
+    auto err = Error::none;
 
-        word = state.dict.input();
-    }
+    while (err == Error::none && state.dict.hasInput())
+        err = parseWord(state, state.dict.input());
 
-    return Error::none;
+    return err;
 }
 
 Error Parser::parseWord(State& state, Word word)
index b19d291b87eca7d7f943f248bca560591cc67b81..6e129999af210c9330f872c559660fe6baf6cd50 100644 (file)
@@ -32,34 +32,30 @@ void State::compiling(bool yes)
     dict.write(Dictionary::Compiling, yes);
 }
 
-std::pair<Addr, std::jmp_buf> State::save()
+State::Context State::save()
 {
-    std::pair<Addr, std::jmp_buf> st;
-    st.first = ip;
-    std::memcpy(st.second, jmpbuf, sizeof(std::jmp_buf));
-    return st;
+    return context;
 }
 
-void State::load(const std::pair<Addr, std::jmp_buf>& st)
+void State::load(const State::Context& ctx)
 {
-    ip = st.first;
-    std::memcpy(jmpbuf, st.second, sizeof(std::jmp_buf));
+    context = ctx;
 }
 
 Error State::execute(Addr addr)
 {
-    auto stat = static_cast<Error>(setjmp(jmpbuf));
+    auto stat = static_cast<Error>(setjmp(context.jmpbuf));
 
     if (stat == Error::none) {
         CoreWords::run(addr, *this);
 
-        if (ip >= Dictionary::Begin) {
+        if (context.ip >= Dictionary::Begin) {
             // longjmp will exit this loop.
             for (;;)
-                CoreWords::run(dict.read(ip), *this);
+                CoreWords::run(dict.read(context.ip), *this);
         } else {
             // addr was a CoreWord, all done now.
-            ip = 0;
+            context.ip = 0;
         }
     } else if (stat == Error::exit) {
         stat = Error::none;
@@ -76,7 +72,7 @@ void State::reset()
         popr();
 
     dict.write(Dictionary::Compiling, 0);
-    ip = 0;
+    context.ip = 0;
 }
 
 std::size_t State::size() const noexcept
index 3a796938bcd7c836e6e85431ede5d459b45eb1a3..12a3aebc2e9a2748f16dd3bbcce2a61a10da4b27 100644 (file)
 
 #include <csetjmp>
 #include <cstddef>
-#include <tuple>
 
 constexpr unsigned DataStackSize = 16;
 constexpr unsigned ReturnStackSize = 16;
 
 class State
 {
-    friend class CoreWords;
+    using InputFunc = void (*)(State&);
+
+    struct Context {
+        Addr ip = 0;
+        std::jmp_buf jmpbuf = {};
+    };
 
 public:
-    Addr ip = 0;
     Dictionary& dict;
-    void (*input)(State&); // User-provided function to collect "stdin" input.
 
-    constexpr State(Dictionary& d, void (*i)(State&)):
-        dict(d), input(i) {}
-
-    bool compiling() const;
-    void compiling(bool);
+    constexpr State(Dictionary& d, InputFunc i):
+        dict(d), inputfunc(i), context() {}
 
     /**
      * Begins execution at the given execution token.
@@ -58,9 +57,31 @@ public:
      */
     void reset();
 
+    Addr& ip() noexcept {
+        return context.ip;
+    }
+
+    void input() noexcept {
+        inputfunc(*this);
+    }
+
+    bool compiling() const;
+    void compiling(bool);
+
     std::size_t size() const noexcept;
     std::size_t rsize() const noexcept;
 
+    /**
+     * Saves execution state so that a new execution can begin.
+     * Used for EVALUATE.
+     */
+    Context save();
+
+    /**
+     * Reloads the given execution state.
+     */
+    void load(const Context&);
+
     inline void push(Cell value) {
         verify(dsp < dstack + DataStackSize, Error::push);
         *dsp++ = value;
@@ -93,32 +114,23 @@ public:
 
     // Advances the instruction pointer and returns that cell's contents.
     inline Cell beyondip() {
-        ip += sizeof(Cell);
-        return dict.read(ip);
+        context.ip += sizeof(Cell);
+        return dict.read(context.ip);
     }
 
-private:
-    Cell dstack[DataStackSize] = {};
-    Cell rstack[ReturnStackSize] = {};
-    Cell *dsp = dstack;
-    Cell *rsp = rstack;
-    std::jmp_buf jmpbuf = {}; // Used when catching execution errors.
-
     inline void verify(bool condition, Error error) {
         if (!condition)
-            std::longjmp(jmpbuf, static_cast<int>(error));
+            std::longjmp(context.jmpbuf, static_cast<int>(error));
     }
 
-    /**
-     * Saves execution state so that a new execution can begin.
-     * Used for EVALUATE.
-     */
-    std::pair<Addr, std::jmp_buf> save();
+private:
+    InputFunc inputfunc; // User-provided function to collect "stdin" input.
+    Context context;
 
-    /**
-     * Reloads the given execution state.
-     */
-    void load(const std::pair<Addr, std::jmp_buf>&);
+    Cell dstack[DataStackSize] = {};
+    Cell rstack[ReturnStackSize] = {};
+    Cell *dsp = dstack;
+    Cell *rsp = rstack;
 };
 
 #endif // ALEEFORTH_STATE_HPP