aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2023-10-14 17:38:57 -0400
committerClyne Sullivan <clyne@bitgloo.com>2023-10-14 17:38:57 -0400
commit5991370657b48f5b44fbcc7877a7c26acf07d99e (patch)
treef0967c003302afb0db70a84e959a1513564f6322
parent70e399b49897d9ed6724a8396a015bddcfdfea79 (diff)
consteval and other refactoring
-rw-r--r--libalee/corewords.cpp49
-rw-r--r--libalee/corewords.hpp24
-rw-r--r--libalee/ctype.cpp36
-rw-r--r--libalee/ctype.hpp19
-rw-r--r--libalee/dictionary.cpp27
-rw-r--r--libalee/dictionary.hpp15
-rw-r--r--libalee/parser.cpp10
7 files changed, 73 insertions, 107 deletions
diff --git a/libalee/corewords.cpp b/libalee/corewords.cpp
index e9b9f47..62b0322 100644
--- a/libalee/corewords.cpp
+++ b/libalee/corewords.cpp
@@ -19,22 +19,22 @@
#include "corewords.hpp"
#include "parser.hpp"
-#include <cstring>
#include <utility>
void find(State& state, Word word)
{
+ Cell tok = 0;
+ Cell imm = 0;
+
if (auto j = state.dict.find(word); j > 0) {
- state.push(state.dict.getexec(j));
- auto imm = state.dict.read(j) & Dictionary::Immediate;
- state.push(imm ? 1 : -1);
- } else if (auto i = CoreWords::findi(state, word); i >= 0) {
- state.push(i);
- state.push(i == CoreWords::Semicolon ? 1 : -1);
- } else {
- state.push(0);
- state.push(0);
+ tok = state.dict.getexec(j);
+ imm = (state.dict.read(j) & Dictionary::Immediate) ? 1 : -1;
+ } else if (tok = CoreWords::findi(state, word); tok >= 0) {
+ imm = (tok == CoreWords::Semicolon) ? 1 : -1;
}
+
+ state.push(tok);
+ state.push(imm);
}
void CoreWords::run(Cell ins, State& state)
@@ -248,35 +248,8 @@ execute:
ip += sizeof(Cell);
}
-template<typename Iter>
-Cell findi(Iter it, std::size_t size)
-{
- auto ptr = CoreWords::wordsarr;
- Cell wordsi = 0;
-
- while (ptr < CoreWords::wordsarr + sizeof(CoreWords::wordsarr)) {
- auto end = ptr;
- while (*end)
- ++end;
-
- std::size_t wordsize = end - ptr;
- if (wordsize == size && Dictionary::equal(ptr, end, it))
- return wordsi;
-
- ++wordsi;
- ptr = end + 1;
- }
-
- return -1;
-}
-
-Cell CoreWords::findi(const char *word)
-{
- return ::findi(word, strlen(word));
-}
-
Cell CoreWords::findi(State& state, Word word)
{
- return ::findi(word.begin(&state.dict), word.size());
+ return findi(word.begin(&state.dict), word.size());
}
diff --git a/libalee/corewords.hpp b/libalee/corewords.hpp
index d4d7ef2..25f6a6e 100644
--- a/libalee/corewords.hpp
+++ b/libalee/corewords.hpp
@@ -22,6 +22,8 @@
#include "types.hpp"
#include "state.hpp"
+#include <cstring>
+
/**
* To be implemented by the user, this function is called when the `sys` word
* is executed.
@@ -38,8 +40,10 @@ public:
* Finds execution token that corresponds to the given word.
* Returns -1 if not found.
*/
- static Cell findi(const char *);
static Cell findi(State&, Word);
+ consteval static Cell findi(const char *word) {
+ return findi(word, std::strlen(word));
+ }
/**
* Executes the given CoreWord execution token using the given state.
@@ -55,6 +59,24 @@ public:
"exit\0;\0_jmp0\0_jmp\0"
"depth\0_rdepth\0_in\0_ev\0find\0"
"_uma\0u<\0um/mod\0";
+
+private:
+ template<typename Iter>
+ constexpr static Cell findi(Iter it, std::size_t size)
+ {
+ const char *ptr = CoreWords::wordsarr;
+
+ for (Cell wordsi = 0; wordsi < WordCount; ++wordsi) {
+ std::size_t wordsize = std::strlen(ptr);
+
+ if (wordsize == size && Dictionary::equal(ptr, ptr + wordsize, it))
+ return wordsi;
+
+ ptr += wordsize + 1;
+ }
+
+ return -1;
+ }
};
#endif // ALEEFORTH_COREWORDS_HPP
diff --git a/libalee/ctype.cpp b/libalee/ctype.cpp
deleted file mode 100644
index 547cd11..0000000
--- a/libalee/ctype.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * 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 "ctype.hpp"
-
-bool isspace(uint8_t c) {
- return c == ' ' || c == '\t' || c == '\r' || c == '\n';
-}
-
-bool isdigit(uint8_t c) {
- return c >= '0' && c <= '9';
-}
-
-bool isalpha(uint8_t c) {
- return isupper(c) || (c >= 'a' && c <= 'z');
-}
-
-bool isupper(uint8_t c) {
- return c >= 'A' && c <= 'Z';
-}
-
diff --git a/libalee/ctype.hpp b/libalee/ctype.hpp
index 5842dfb..878c747 100644
--- a/libalee/ctype.hpp
+++ b/libalee/ctype.hpp
@@ -25,10 +25,21 @@
#include <cstdint>
-bool isspace(uint8_t);
-bool isdigit(uint8_t);
-bool isalpha(uint8_t);
-bool isupper(uint8_t);
+constexpr inline bool isspace(uint8_t c) {
+ return c == ' ' || c == '\t' || c == '\r' || c == '\n';
+}
+
+constexpr inline bool isdigit(uint8_t c) {
+ return c >= '0' && c <= '9';
+}
+
+constexpr inline bool isupper(uint8_t c) {
+ return c >= 'A' && c <= 'Z';
+}
+
+constexpr inline bool isalpha(uint8_t c) {
+ return isupper(c) || (c >= 'a' && c <= 'z');
+}
#endif // ALEEFORTH_CTYPE_HPP
diff --git a/libalee/dictionary.cpp b/libalee/dictionary.cpp
index 64c0ac2..0d225e0 100644
--- a/libalee/dictionary.cpp
+++ b/libalee/dictionary.cpp
@@ -16,7 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include "ctype.hpp"
#include "dictionary.hpp"
#include <cstring>
@@ -49,15 +48,9 @@ void Dictionary::add(Cell value) noexcept
write(allot(sizeof(Cell)), value);
}
-Addr Dictionary::aligned(Addr addr) const noexcept
+Addr Dictionary::aligned(Addr addr)
{
- Addr unaligned = addr & (sizeof(Cell) - sizeof(uint8_t));
- if (unaligned) {
- addr += sizeof(Cell);
- addr -= unaligned;
- }
-
- return addr;
+ return (addr + (sizeof(Cell) - 1)) & ~(sizeof(Cell) - 1);
}
Addr Dictionary::alignhere() noexcept
@@ -71,11 +64,12 @@ void Dictionary::addDefinition(Word word) noexcept
Cell wsize = word.size();
add(wsize);
+ auto addr = allot(wsize);
auto it = word.begin(this);
const auto end = word.end(this);
while (it != end)
- writebyte(allot(1), *it++);
+ writebyte(addr++, *it++);
alignhere();
}
@@ -83,6 +77,7 @@ void Dictionary::addDefinition(Word word) noexcept
Addr Dictionary::find(Word word) noexcept
{
Addr lt = latest();
+
for (;;) {
const Addr l = read(lt);
const Addr len = l & 0x1F;
@@ -159,19 +154,11 @@ Word Dictionary::input() noexcept
bool Dictionary::equal(Word word, const char *str, unsigned len) const noexcept
{
- return word.size() == len &&
- equal(word.begin(this), word.end(this), str);
+ return word.size() == len && equal(word.begin(this), word.end(this), str);
}
bool Dictionary::equal(Word word, Word other) const noexcept
{
- return word.size() == other.size() &&
- equal(word.begin(this), word.end(this), other.begin(this));
-}
-
-bool Dictionary::eqchars(char c1, char c2)
-{
- return c1 == c2 ||
- (isalpha(c1) && isalpha(c2) && (c1 | 32) == (c2 | 32));
+ return word.size() == other.size() && equal(word.begin(this), word.end(this), other.begin(this));
}
diff --git a/libalee/dictionary.hpp b/libalee/dictionary.hpp
index 14366a5..b43ea2e 100644
--- a/libalee/dictionary.hpp
+++ b/libalee/dictionary.hpp
@@ -19,6 +19,7 @@
#ifndef ALEEFORTH_DICTIONARY_HPP
#define ALEEFORTH_DICTIONARY_HPP
+#include "ctype.hpp"
#include "types.hpp"
#include <algorithm>
@@ -78,7 +79,7 @@ public:
void latest(Addr l) noexcept { write(Latest, l); }
// Aligns the given address.
- Addr aligned(Addr) const noexcept;
+ static Addr aligned(Addr);
// Aligns `here`.
Addr alignhere() noexcept;
// Advances `here` by the given number of bytes.
@@ -123,7 +124,7 @@ public:
// Used for case-insensitive comparison between two iterators.
template<typename Iter1, typename Iter2>
- static bool equal(Iter1 b1, Iter1 e1, Iter2 b2) {
+ constexpr static bool equal(Iter1 b1, Iter1 e1, Iter2 b2) {
return std::equal(b1, e1, b2, eqchars);
}
@@ -131,7 +132,15 @@ public:
private:
// Case-insensitive comparison.
- static bool eqchars(char c1, char c2);
+ constexpr static bool eqchars(char c1, char c2) {
+ if (isalpha(static_cast<uint8_t>(c1)))
+ c1 |= 32;
+ if (isalpha(static_cast<uint8_t>(c2)))
+ c2 |= 32;
+
+ return c1 == c2;
+ }
+
};
#endif // ALEEFORTH_DICTIONARY_HPP
diff --git a/libalee/parser.cpp b/libalee/parser.cpp
index da7ae0b..16281d3 100644
--- a/libalee/parser.cpp
+++ b/libalee/parser.cpp
@@ -111,12 +111,12 @@ Error Parser::parseNumber(State& state, Word word)
auto ins = CoreWords::findi("_lit");
const Cell maxlit = Dictionary::Begin - CoreWords::WordCount;
- if (value >= 0 && value < maxlit) {
- state.dict.add(value + CoreWords::WordCount);
- } else {
+ if (value >= 0 && value < maxlit)
+ value += CoreWords::WordCount;
+ else
state.dict.add(ins);
- state.dict.add(value);
- }
+
+ state.dict.add(value);
} else {
state.push(value);
}