]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
Word::iterator
authorClyne Sullivan <clyne@bitgloo.com>
Fri, 10 Mar 2023 14:14:09 +0000 (09:14 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Fri, 10 Mar 2023 14:14:09 +0000 (09:14 -0500)
libalee/corewords.cpp
libalee/corewords.hpp
libalee/dictionary.cpp
libalee/parser.cpp
libalee/types.cpp [new file with mode: 0644]
libalee/types.hpp

index d981098c6abece4196a979654e502b6c1ba88e3f..1d705f44ab2493001678d56589d011dc9629f954 100644 (file)
@@ -214,17 +214,18 @@ execute:
     state.ip += sizeof(Cell);
 }
 
-int CoreWords::findi(const char *word)
+template<class Comp>
+int findi(Comp comp)
 {
     std::size_t i = 0;
     int wordsi = 0;
 
-    while (i < sizeof(wordsarr)) {
+    while (i < sizeof(CoreWords::wordsarr)) {
         auto end = i;
-        while (wordsarr[end])
+        while (CoreWords::wordsarr[end])
             ++end;
 
-        if (!std::strcmp(word, wordsarr + i))
+        if (comp(CoreWords::wordsarr + i, end - i))
             return wordsi;
 
         ++wordsi;
@@ -234,23 +235,15 @@ int CoreWords::findi(const char *word)
     return -1;
 }
 
-int CoreWords::findi(State& state, Word word)
+int CoreWords::findi(const char *word)
 {
-    std::size_t i = 0;
-    int wordsi = 0;
-
-    while (i < sizeof(wordsarr)) {
-        auto end = i;
-        while (wordsarr[end])
-            ++end;
-
-        if (state.dict.equal(word, wordsarr + i, end - i))
-            return wordsi;
-
-        ++wordsi;
-        i = end + 1;
-    }
+    return ::findi([word](auto b, auto e) {
+        return !std::strncmp(word, b, e); });
+}
 
-    return -1;
+int CoreWords::findi(State& state, Word word)
+{
+    return ::findi([state, word](auto b, auto e) {
+        return state.dict.equal(word, b, e); });
 }
 
index 21a0951e42fd8925facbe3d30805276560fc0c7d..70cbb304fe867d8cd94bf10bd1d1bec4f57581a2 100644 (file)
@@ -37,7 +37,6 @@ public:
     static int findi(State&, Word);
     static void run(unsigned int, State&);
 
-private:
     constexpr static char wordsarr[] =
         "_lit\0drop\0dup\0swap\0pick\0sys\0"
         "+\0-\0m*\0_/\0_%\0"
index 29844b68b43468df4b2999095765e31ca029d858..8b617a9d92790da73224c49c96f24070925cc09f 100644 (file)
@@ -60,7 +60,7 @@ Addr Dictionary::alignhere() noexcept
 void Dictionary::addDefinition(Word word) noexcept
 {
     add(word.size());
-    for (auto w = word.start; w != word.end; ++w)
+    for (auto w = word.start; w != word.wend; ++w)
         writebyte(allot(1), readbyte(w));
 
     alignhere();
@@ -105,7 +105,7 @@ Word Dictionary::input() noexcept
     };
 
     while (idx < end) {
-        auto ch = readbyte(word.end);
+        auto ch = readbyte(word.wend);
 
         if (isspace(ch)) {
             if (word.size() > 0)
@@ -116,7 +116,7 @@ Word Dictionary::input() noexcept
             break;
         }
 
-        ++word.end;
+        ++word.wend;
         ++idx;
     }
 
@@ -124,26 +124,18 @@ Word Dictionary::input() noexcept
     return word;
 }
 
+#include <algorithm>
+
 bool Dictionary::equal(Word word, const char *str, unsigned len) const noexcept
 {
     if (word.size() != len)
         return false;
 
-    for (auto w = word.start; w != word.end; ++w) {
-        auto wc = readbyte(w);
-        if (wc != *str) {
-            if (isalpha(wc) && isalpha(*str) && (wc | 32) == (*str | 32)) {
-                ++str;
-                continue;
-            }
-
-            return false;
-        }
-
-        ++str;
-    }
-
-    return true;
+    return std::equal(word.begin(this), word.end(this), str,
+        [](auto wc, auto oc) {
+            return wc == oc ||
+                   (isalpha(wc) && isalpha(oc) && (wc | 32) == (oc | 32));
+        });
 }
 
 bool Dictionary::equal(Word word, Word other) const noexcept
@@ -151,21 +143,10 @@ bool Dictionary::equal(Word word, Word other) const noexcept
     if (word.size() != other.size())
         return false;
 
-    auto w = word.start, o = other.start;
-    while (w != word.end) {
-        auto wc = readbyte(w), oc = readbyte(o);
-        if (wc != oc) {
-            if (isalpha(wc) && isalpha(oc) && (wc | 32) == (oc | 32)) {
-                ++w, ++o;
-                continue;
-            }
-
-            return false;
-        }
-
-        ++w, ++o;
-    }
-
-    return true;
+    return std::equal(word.begin(this), word.end(this), other.begin(this),
+        [](auto wc, auto oc) {
+            return wc == oc ||
+                   (isalpha(wc) && isalpha(oc) && (wc | 32) == (oc | 32));
+        });
 }
 
index a9c9aaa19c9beb2b7d4af6e9ae1fd3020d7ef0d7..bcef9637390b4b4d131f36e062893386d2e73cae 100644 (file)
@@ -100,9 +100,9 @@ int Parser::parseNumber(State& state, Word word)
             return UnknownWord;
         }
 
-        if (++i < word.end)
+        if (++i < word.wend)
             c = state.dict.readbyte(i);
-    } while (i < word.end);
+    } while (i < word.wend);
 
     if (inv)
         result *= -1;
diff --git a/libalee/types.cpp b/libalee/types.cpp
new file mode 100644 (file)
index 0000000..fe6210e
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * Alee Forth: A portable and concise Forth implementation in modern C++.
+ * Copyright (C) 2023  Clyne Sullivan <clyne@bitgloo.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "dictionary.hpp"
+#include "types.hpp"
+
+unsigned Word::size() const noexcept
+{
+    return wend - start;
+}
+
+Word::iterator Word::begin(const Dictionary *dict)
+{
+    return iterator(start, dict);
+}
+
+Word::iterator Word::end(const Dictionary *dict)
+{
+    return iterator(wend, dict);
+}
+
+Word::iterator& Word::iterator::operator++()
+{
+    addr++;
+    return *this;
+}
+
+Word::iterator::value_type Word::iterator::operator*()
+{
+    return dict->readbyte(addr);
+}
+
+bool Word::iterator::operator!=(const iterator& other)
+{
+    return dict != other.dict || addr != other.addr;
+}
index 530ff4f60525530ecd708dd3c04b4ee5f4f164dd..5b577f200368e99b0ffea4909a57db07df27a04f 100644 (file)
@@ -20,7 +20,9 @@
 #define ALEEFORTH_TYPES_HPP
 
 #include <cstdint>
+#include <iterator>
 
+struct Dictionary;
 struct State;
 
 using Addr = uint16_t;
@@ -32,12 +34,32 @@ constexpr unsigned int MaxCellNumberChars = 6; // -32768
 
 struct Word
 {
+    struct iterator;
+
     Addr start = 0;
-    Addr end = 0;
+    Addr wend = 0;
+
+    iterator begin(const Dictionary *);
+    iterator end(const Dictionary *);
+    unsigned size() const noexcept;
+
+    struct iterator {
+        using iterator_category = std::input_iterator_tag;
+        using value_type = uint8_t;
+        using pointer = void;
+        using reference = void;
+        using difference_type = Cell;
+
+        Addr addr;
+        const Dictionary *dict;
+
+        constexpr iterator(Addr a, const Dictionary *d):
+            addr(a), dict(d) {}
 
-    unsigned size() const noexcept {
-        return end - start;
-    }
+        iterator& operator++();
+        value_type operator*();
+        bool operator!=(const iterator&);
+    };
 };
 
 #endif // ALEEFORTH_TYPES_HPP