Word::iterator

llvm
Clyne 2 years ago
parent f6e3fa4663
commit 7eeb515c5d
Signed by: clyne
GPG Key ID: 3267C8EBF3F9AFC7

@ -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); });
}

@ -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"

@ -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));
});
}

@ -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;

@ -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;
}

@ -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

Loading…
Cancel
Save