aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2023-03-10 09:14:09 -0500
committerClyne Sullivan <clyne@bitgloo.com>2023-03-10 09:14:09 -0500
commit7eeb515c5dc57658ac98554f44780a1f9a6fd2a4 (patch)
tree117aa54de6aeae2218a16e74f9df5590d1d41237
parentf6e3fa466357a865310eb382aed55c5db8dab029 (diff)
Word::iterator
-rw-r--r--libalee/corewords.cpp33
-rw-r--r--libalee/corewords.hpp1
-rw-r--r--libalee/dictionary.cpp49
-rw-r--r--libalee/parser.cpp4
-rw-r--r--libalee/types.cpp51
-rw-r--r--libalee/types.hpp30
6 files changed, 107 insertions, 61 deletions
diff --git a/libalee/corewords.cpp b/libalee/corewords.cpp
index d981098..1d705f4 100644
--- a/libalee/corewords.cpp
+++ b/libalee/corewords.cpp
@@ -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); });
}
diff --git a/libalee/corewords.hpp b/libalee/corewords.hpp
index 21a0951..70cbb30 100644
--- a/libalee/corewords.hpp
+++ b/libalee/corewords.hpp
@@ -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"
diff --git a/libalee/dictionary.cpp b/libalee/dictionary.cpp
index 29844b6..8b617a9 100644
--- a/libalee/dictionary.cpp
+++ b/libalee/dictionary.cpp
@@ -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));
+ });
}
diff --git a/libalee/parser.cpp b/libalee/parser.cpp
index a9c9aaa..bcef963 100644
--- a/libalee/parser.cpp
+++ b/libalee/parser.cpp
@@ -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
index 0000000..fe6210e
--- /dev/null
+++ b/libalee/types.cpp
@@ -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;
+}
diff --git a/libalee/types.hpp b/libalee/types.hpp
index 530ff4f..5b577f2 100644
--- a/libalee/types.hpp
+++ b/libalee/types.hpp
@@ -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