aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2023-03-10 11:36:30 -0500
committerClyne Sullivan <clyne@bitgloo.com>2023-03-10 11:36:30 -0500
commitb31036813c7706527e2067392660c9068447fa2c (patch)
treedf1e9cf14b10a4faa7ff553e84152d0a58d9ab52
parent7eeb515c5dc57658ac98554f44780a1f9a6fd2a4 (diff)
size reduction and refactoring
-rw-r--r--README.md4
-rw-r--r--alee-msp430.cpp6
-rw-r--r--libalee/corewords.cpp22
-rw-r--r--libalee/ctype.cpp52
-rw-r--r--libalee/ctype.hpp37
-rw-r--r--libalee/dictionary.cpp39
-rw-r--r--libalee/dictionary.hpp9
-rw-r--r--libalee/parser.cpp2
8 files changed, 131 insertions, 40 deletions
diff --git a/README.md b/README.md
index b59c463..bf8bf9d 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ The goal of portability extends down to microcontroller targets with kilobytes o
System-specific functionality is obtained through a `sys` Forth word. This word calls a user-supplied C++ function that implements the necessary (or any additional) functionality.
-# Forth compatibility
+## Forth compatibility
Alee implements a large majority of the "core" and "core extension" [word sets](https://forth-standard.org/standard/core). Implementation is tracked in `compat.txt`, with missing words listed below. Fundamental words are built into Alee (written in C++); the rest of the implementation is in `core.fth` and `core-ext.fth`.
@@ -41,3 +41,5 @@ The `msp430` target builds Alee for the [MSP430G2553](https://www.ti.com/product
Configurable constants and types are defined either in the Makefile or in `types.hpp`.
+ text data bss dec hex filename
+ 8528 8 252 8788 2254 alee-msp430
diff --git a/alee-msp430.cpp b/alee-msp430.cpp
index 4116118..3121dc1 100644
--- a/alee-msp430.cpp
+++ b/alee-msp430.cpp
@@ -17,9 +17,9 @@
*/
#include "alee.hpp"
+#include "libalee/ctype.hpp"
#include "splitmemdict.hpp"
-#include <cctype>
#include <msp430.h>
#include "core.fth.h"
@@ -149,10 +149,10 @@ void user_sys(State& state)
break;
case 2:
{ auto addr = state.pop();
- *((uint8_t *)addr) = state.pop(); }
+ *reinterpret_cast<uint8_t *>(addr) = state.pop(); }
break;
case 3:
- state.push(*((uint8_t *)state.pop()));
+ state.push(*reinterpret_cast<uint8_t *>(state.pop()));
break;
default:
break;
diff --git a/libalee/corewords.cpp b/libalee/corewords.cpp
index 1d705f4..ced3973 100644
--- a/libalee/corewords.cpp
+++ b/libalee/corewords.cpp
@@ -214,22 +214,22 @@ execute:
state.ip += sizeof(Cell);
}
-template<class Comp>
-int findi(Comp comp)
+template<typename Iter>
+int findi(Iter it, int size)
{
- std::size_t i = 0;
+ auto ptr = CoreWords::wordsarr;
int wordsi = 0;
- while (i < sizeof(CoreWords::wordsarr)) {
- auto end = i;
- while (CoreWords::wordsarr[end])
+ while (ptr < CoreWords::wordsarr + sizeof(CoreWords::wordsarr)) {
+ auto end = ptr;
+ while (*end)
++end;
- if (comp(CoreWords::wordsarr + i, end - i))
+ if (end - ptr == size && Dictionary::equal(ptr, end, it))
return wordsi;
++wordsi;
- i = end + 1;
+ ptr = end + 1;
}
return -1;
@@ -237,13 +237,11 @@ int findi(Comp comp)
int CoreWords::findi(const char *word)
{
- return ::findi([word](auto b, auto e) {
- return !std::strncmp(word, b, e); });
+ return ::findi(word, strlen(word));
}
int CoreWords::findi(State& state, Word word)
{
- return ::findi([state, word](auto b, auto e) {
- return state.dict.equal(word, b, e); });
+ return ::findi(word.begin(&state.dict), word.size());
}
diff --git a/libalee/ctype.cpp b/libalee/ctype.cpp
new file mode 100644
index 0000000..a0c8dc1
--- /dev/null
+++ b/libalee/ctype.cpp
@@ -0,0 +1,52 @@
+/**
+ * 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 isspace(char c) {
+ return isspace(static_cast<uint8_t>(c));
+}
+
+bool isdigit(uint8_t c) {
+ return c >= '0' && c <= '9';
+}
+
+bool isdigit(char c) {
+ return isdigit(static_cast<uint8_t>(c));
+}
+
+bool isalpha(uint8_t c) {
+ return isupper(c) || (c >= 'a' && c <= 'z');
+}
+
+bool isalpha(char c) {
+ return isalpha(static_cast<uint8_t>(c));
+}
+
+bool isupper(uint8_t c) {
+ return c >= 'A' && c <= 'Z';
+}
+
+bool isupper(char c) {
+ return isupper(static_cast<uint8_t>(c));
+}
+
diff --git a/libalee/ctype.hpp b/libalee/ctype.hpp
new file mode 100644
index 0000000..d1a1d0b
--- /dev/null
+++ b/libalee/ctype.hpp
@@ -0,0 +1,37 @@
+/**
+ * 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/>.
+ */
+
+#ifndef ALEEFORTH_CTYPE_HPP
+#define ALEEFORTH_CTYPE_HPP
+
+#include <cstdint>
+
+bool isspace(uint8_t);
+bool isspace(char);
+
+bool isdigit(uint8_t);
+bool isdigit(char);
+
+bool isalpha(uint8_t);
+bool isalpha(char);
+
+bool isupper(uint8_t);
+bool isupper(char);
+
+#endif // ALEEFORTH_CTYPE_HPP
+
diff --git a/libalee/dictionary.cpp b/libalee/dictionary.cpp
index 8b617a9..81b5c64 100644
--- a/libalee/dictionary.cpp
+++ b/libalee/dictionary.cpp
@@ -16,9 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#include "ctype.hpp"
#include "dictionary.hpp"
-#include <cctype>
#include <cstring>
void Dictionary::initialize()
@@ -68,9 +68,8 @@ void Dictionary::addDefinition(Word word) noexcept
Addr Dictionary::find(Word word) noexcept
{
- Addr lt = latest(), oldlt;
- do {
- oldlt = lt;
+ Addr lt = latest();
+ for (;;) {
const auto l = static_cast<Addr>(read(lt));
const Addr len = l & 0x1F;
const Word lw {
@@ -80,9 +79,11 @@ Addr Dictionary::find(Word word) noexcept
if (equal(word, lw))
return lt;
+ else if (lt == Begin)
+ break;
else
lt -= l >> 6;
- } while (lt != oldlt);
+ }
return 0;
}
@@ -124,29 +125,21 @@ 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;
-
- 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));
- });
+ return word.size() == len &&
+ equal(word.begin(this), word.end(this), str);
}
bool Dictionary::equal(Word word, Word other) const noexcept
{
- if (word.size() != other.size())
- return false;
-
- 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));
- });
+ 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));
}
diff --git a/libalee/dictionary.hpp b/libalee/dictionary.hpp
index 0a2e4d3..53172d2 100644
--- a/libalee/dictionary.hpp
+++ b/libalee/dictionary.hpp
@@ -21,6 +21,7 @@
#include "types.hpp"
+#include <algorithm>
#include <cstddef>
#include <cstdint>
@@ -74,7 +75,15 @@ public:
bool equal(Word, const char *, unsigned) const noexcept;
bool equal(Word, Word) const noexcept;
+ template<typename Iter1, typename Iter2>
+ static bool equal(Iter1 b1, Iter1 e1, Iter2 b2) {
+ return std::equal(b1, e1, b2, eqchars);
+ }
+
virtual ~Dictionary() = default;
+
+private:
+ static bool eqchars(char c1, char c2);
};
#endif // ALEEFORTH_DICTIONARY_HPP
diff --git a/libalee/parser.cpp b/libalee/parser.cpp
index bcef963..3b14224 100644
--- a/libalee/parser.cpp
+++ b/libalee/parser.cpp
@@ -17,9 +17,9 @@
*/
#include "corewords.hpp"
+#include "ctype.hpp"
#include "parser.hpp"
-#include <cctype>
#include <cstring>
int Parser::parse(State& state, const char *str)