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 +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 + 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 + * + * 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 . + */ + +#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 +#include +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