]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
some class refactoring
authorClyne Sullivan <clyne@bitgloo.com>
Fri, 13 Oct 2023 00:23:50 +0000 (20:23 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Fri, 13 Oct 2023 00:23:50 +0000 (20:23 -0400)
libalee/corewords.cpp
libalee/dictionary.cpp
libalee/dictionary.hpp
libalee/parser.cpp
libalee/state.hpp
libalee/types.cpp
libalee/types.hpp

index 1344ca067c031812445a1fe55c28366bbfcdd36f..34125bd66e9baf081b8b9d7580715854cceb0814 100644 (file)
 #include <cstring>
 #include <utility>
 
-Word getword(State& state)
-{
-    auto word = state.dict.input();
-    while (word.size() == 0) {
-        state.input(state);
-        word = state.dict.input();
-    }
-    return word;
-}
-void newdef(State& state, Word word)
-{
-    auto& dict = state.dict;
-
-    auto addr = dict.alignhere();
-    dict.addDefinition(word);
-    state.push(addr);
-};
 void find(State& state, Word word)
 {
     if (auto j = state.dict.find(word); j > 0) {
@@ -169,11 +152,16 @@ execute:
         reinterpret_cast<Addr&>(state.top()) >>= static_cast<Addr>(cell);
         break;
     case 22: // colon
-        newdef(state, getword(state));
+        state.push(state.dict.alignhere());
+        while (!state.dict.hasInput())
+            state.input(state);
+        state.dict.addDefinition(state.dict.input());
         state.compiling(true);
         break;
     case 23: // tick
-        find(state, getword(state));
+        while (!state.dict.hasInput())
+            state.input(state);
+        find(state, state.dict.input());
         break;
     case 24: // execute
         index = state.pop();
index 7ae004339d9dd64930386633dbd26126a9e21c7b..64c0ac2b22d43f992a324bc1c5bda3a4a56d60f8 100644 (file)
@@ -71,8 +71,11 @@ void Dictionary::addDefinition(Word word) noexcept
     Cell wsize = word.size();
     add(wsize);
 
-    for (auto w = word.start; w != word.wend; ++w)
-        writebyte(allot(1), readbyte(w));
+    auto it = word.begin(this);
+    const auto end = word.end(this);
+
+    while (it != end)
+        writebyte(allot(1), *it++);
 
     alignhere();
 }
@@ -83,10 +86,8 @@ Addr Dictionary::find(Word word) noexcept
     for (;;) {
         const Addr l = read(lt);
         const Addr len = l & 0x1F;
-        Word lw;
-        lw.start = lt + sizeof(Cell);
-        lw.wend = lw.start + len;
 
+        const auto lw = Word::fromLength(lt + sizeof(Cell), len);
         if (equal(word, lw))
             return lt;
         else if (lt == Begin)
@@ -106,34 +107,54 @@ Addr Dictionary::getexec(Addr addr) noexcept
     return aligned(addr);
 }
 
+bool Dictionary::hasInput() const noexcept
+{
+    const Addr src = read(Dictionary::Source);
+    const Addr end = read(Dictionary::SourceLen);
+    uint8_t idx = read(Dictionary::Input) & 0xFFu;
+
+    while (idx < end) {
+        auto ch = readbyte(src + idx);
+
+        if (ch == '\0') {
+            break;
+        } else if (!isspace(ch)) {
+            return true;
+        }
+
+        ++idx;
+    }
+
+    return false;
+}
+
 Word Dictionary::input() noexcept
 {
     const Addr src = read(Dictionary::Source);
     const Addr end = read(Dictionary::SourceLen);
     uint8_t idx = read(Dictionary::Input) & 0xFFu;
 
-    Word word;
-    word.start = src + idx;
-    word.wend = word.start;
+    Addr wstart = src + idx;
+    Addr wend = wstart;
 
     while (idx < end) {
-        auto ch = readbyte(word.wend);
+        auto ch = readbyte(wend);
 
         if (isspace(ch)) {
-            if (word.size() > 0)
+            if (wend - wstart > 0)
                 break;
 
-            ++word.start;
+            ++wstart;
         } else if (ch == '\0') {
             break;
         }
 
-        ++word.wend;
+        ++wend;
         ++idx;
     }
 
     writebyte(Dictionary::Input, ++idx);
-    return word;
+    return Word(wstart, wend);
 }
 
 bool Dictionary::equal(Word word, const char *str, unsigned len) const noexcept
index 2f17a7771640e96b999aa0021710c2c35ce25149..14366a5898324a0dd1f897655f6d92db1d0ceda5 100644 (file)
@@ -109,6 +109,7 @@ public:
      * Returns an empty word if the buffer is empty or entirely read.
      */
     Word input() noexcept;
+    bool hasInput() const noexcept;
 
     /**
      * Checks if this dictionary's word is equivalent to the given string/size.
index cdec1a5a681d5c21705979488d868b91d76e8886..2b1d8e11d0af7bcd873361cd8dfbcb4c9621034a 100644 (file)
@@ -85,15 +85,16 @@ Error Parser::parseNumber(State& state, Word word)
 {
     const auto base = state.dict.read(Dictionary::Base);
     DoubleCell result = 0;
-    auto i = word.start;
-    bool inv;
-    char c;
+    auto it = word.begin(&state.dict);
 
-    c = state.dict.readbyte(i);
-    if (inv = c == '-'; inv)
-        c = state.dict.readbyte(++i);
+    bool inv = *it == '-';
+    if (inv)
+        ++it;
+
+    const auto end = word.end(&state.dict);
+    for (char c; it != end; ++it) {
+        c = *it;
 
-    do {
         if (isdigit(c)) {
             result *= base;
             result += c - '0';
@@ -103,10 +104,7 @@ Error Parser::parseNumber(State& state, Word word)
         } else {
             return Error::noword;
         }
-
-        if (++i < word.wend)
-            c = state.dict.readbyte(i);
-    } while (i < word.wend);
+    }
 
     if (inv)
         result *= -1;
index 4c74f9ae1b45cd29d6996261f3cac7c51b5d5dee..3a796938bcd7c836e6e85431ede5d459b45eb1a3 100644 (file)
@@ -31,11 +31,12 @@ constexpr unsigned ReturnStackSize = 16;
 
 class State
 {
+    friend class CoreWords;
+
 public:
     Addr ip = 0;
     Dictionary& dict;
     void (*input)(State&); // User-provided function to collect "stdin" input.
-    std::jmp_buf jmpbuf = {}; // Used when catching execution errors.
 
     constexpr State(Dictionary& d, void (*i)(State&)):
         dict(d), input(i) {}
@@ -43,17 +44,6 @@ public:
     bool compiling() const;
     void compiling(bool);
 
-    /**
-     * Saves execution state so that a new execution can begin.
-     * Used for EVALUATE.
-     */
-    std::pair<Addr, std::jmp_buf> save();
-
-    /**
-     * Reloads the given execution state.
-     */
-    void load(const std::pair<Addr, std::jmp_buf>&);
-
     /**
      * Begins execution at the given execution token.
      * If the token is a CoreWord, this function exits after its execution.
@@ -72,38 +62,32 @@ public:
     std::size_t rsize() const noexcept;
 
     inline void push(Cell value) {
-        if (dsp == dstack + DataStackSize)
-            std::longjmp(jmpbuf, static_cast<int>(Error::push));
+        verify(dsp < dstack + DataStackSize, Error::push);
         *dsp++ = value;
     }
 
     inline Cell pop() {
-        if (dsp == dstack)
-            std::longjmp(jmpbuf, static_cast<int>(Error::pop));
+        verify(dsp > dstack, Error::pop);
         return *--dsp;
     }
 
     inline void pushr(Cell value) {
-        if (rsp == rstack + ReturnStackSize)
-            std::longjmp(jmpbuf, static_cast<int>(Error::pushr));
+        verify(rsp < rstack + ReturnStackSize, Error::pushr);
         *rsp++ = value;
     }
 
     inline Cell popr() {
-        if (rsp == rstack)
-            std::longjmp(jmpbuf, static_cast<int>(Error::popr));
+        verify(rsp > rstack, Error::popr);
         return *--rsp;
     }
 
     inline Cell& top() {
-        if (dsp == dstack)
-            std::longjmp(jmpbuf, static_cast<int>(Error::top));
+        verify(dsp > dstack, Error::top);
         return *(dsp - 1);
     }
 
     inline Cell& pick(std::size_t i) {
-        if (dsp - i == dstack)
-            std::longjmp(jmpbuf, static_cast<int>(Error::pick));
+        verify(dsp - i > dstack, Error::pick);
         return *(dsp - i - 1);
     }
 
@@ -118,6 +102,23 @@ private:
     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));
+    }
+
+    /**
+     * Saves execution state so that a new execution can begin.
+     * Used for EVALUATE.
+     */
+    std::pair<Addr, std::jmp_buf> save();
+
+    /**
+     * Reloads the given execution state.
+     */
+    void load(const std::pair<Addr, std::jmp_buf>&);
 };
 
 #endif // ALEEFORTH_STATE_HPP
index baaa5ce3b7bbc296cd5d7cac308a04e944c4de92..83cf1f7bc67acec962847a6021328c9110ec5265 100644 (file)
@@ -40,6 +40,13 @@ Word::iterator& Word::iterator::operator++()
     return *this;
 }
 
+Word::iterator Word::iterator::operator++(int)
+{
+    const auto copy = *this;
+    addr++;
+    return copy;
+}
+
 Word::iterator::value_type Word::iterator::operator*()
 {
     return dict->readbyte(addr);
index 95daee65f856613813a6bbda0e069895d88e4d24..4d86c5deaef33f07c163f936357f8494d28a44ca 100644 (file)
@@ -23,7 +23,7 @@
 #include <iterator>
 
 /**
- * Configure the below three types to match your platform.
+ * Configure the below types for your platform.
  */
 using Addr = uint16_t;
 using Cell = int16_t;
@@ -48,13 +48,16 @@ enum class Error : int {
 };
 
 /**
- * Stores the start and (past-the-)end addresses of a dictionary's word.
+ * Stores the start and past-the-end addresses of a dictionary's word.
  */
-struct Word
+class Word
 {
     Addr start;
     Addr wend;
 
+public:
+    struct iterator;
+
     constexpr explicit Word(Addr s = 0, Addr e = 0):
         start(s), wend(e) {}
 
@@ -64,8 +67,6 @@ struct Word
 
     Addr size() const noexcept;
 
-    // Iterators provided for std::equal.
-    struct iterator;
     iterator begin(const Dictionary *);
     iterator end(const Dictionary *);
 
@@ -83,6 +84,7 @@ struct Word
             addr(a), dict(d) {}
 
         iterator& operator++();
+        iterator operator++(int);
         value_type operator*();
         bool operator!=(const iterator&);
     };