size reduction and refactoring

llvm
Clyne 2 years ago
parent 7eeb515c5d
commit b31036813c

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

@ -17,9 +17,9 @@
*/ */
#include "alee.hpp" #include "alee.hpp"
#include "libalee/ctype.hpp"
#include "splitmemdict.hpp" #include "splitmemdict.hpp"
#include <cctype>
#include <msp430.h> #include <msp430.h>
#include "core.fth.h" #include "core.fth.h"
@ -149,10 +149,10 @@ void user_sys(State& state)
break; break;
case 2: case 2:
{ auto addr = state.pop(); { auto addr = state.pop();
*((uint8_t *)addr) = state.pop(); } *reinterpret_cast<uint8_t *>(addr) = state.pop(); }
break; break;
case 3: case 3:
state.push(*((uint8_t *)state.pop())); state.push(*reinterpret_cast<uint8_t *>(state.pop()));
break; break;
default: default:
break; break;

@ -214,22 +214,22 @@ execute:
state.ip += sizeof(Cell); state.ip += sizeof(Cell);
} }
template<class Comp> template<typename Iter>
int findi(Comp comp) int findi(Iter it, int size)
{ {
std::size_t i = 0; auto ptr = CoreWords::wordsarr;
int wordsi = 0; int wordsi = 0;
while (i < sizeof(CoreWords::wordsarr)) { while (ptr < CoreWords::wordsarr + sizeof(CoreWords::wordsarr)) {
auto end = i; auto end = ptr;
while (CoreWords::wordsarr[end]) while (*end)
++end; ++end;
if (comp(CoreWords::wordsarr + i, end - i)) if (end - ptr == size && Dictionary::equal(ptr, end, it))
return wordsi; return wordsi;
++wordsi; ++wordsi;
i = end + 1; ptr = end + 1;
} }
return -1; return -1;
@ -237,13 +237,11 @@ int findi(Comp comp)
int CoreWords::findi(const char *word) int CoreWords::findi(const char *word)
{ {
return ::findi([word](auto b, auto e) { return ::findi(word, strlen(word));
return !std::strncmp(word, b, e); });
} }
int CoreWords::findi(State& state, Word word) int CoreWords::findi(State& state, Word word)
{ {
return ::findi([state, word](auto b, auto e) { return ::findi(word.begin(&state.dict), word.size());
return state.dict.equal(word, b, e); });
} }

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

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

@ -16,9 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "ctype.hpp"
#include "dictionary.hpp" #include "dictionary.hpp"
#include <cctype>
#include <cstring> #include <cstring>
void Dictionary::initialize() void Dictionary::initialize()
@ -68,9 +68,8 @@ void Dictionary::addDefinition(Word word) noexcept
Addr Dictionary::find(Word word) noexcept Addr Dictionary::find(Word word) noexcept
{ {
Addr lt = latest(), oldlt; Addr lt = latest();
do { for (;;) {
oldlt = lt;
const auto l = static_cast<Addr>(read(lt)); const auto l = static_cast<Addr>(read(lt));
const Addr len = l & 0x1F; const Addr len = l & 0x1F;
const Word lw { const Word lw {
@ -80,9 +79,11 @@ Addr Dictionary::find(Word word) noexcept
if (equal(word, lw)) if (equal(word, lw))
return lt; return lt;
else if (lt == Begin)
break;
else else
lt -= l >> 6; lt -= l >> 6;
} while (lt != oldlt); }
return 0; return 0;
} }
@ -124,29 +125,21 @@ Word Dictionary::input() noexcept
return word; return word;
} }
#include <algorithm>
bool Dictionary::equal(Word word, const char *str, unsigned len) const noexcept bool Dictionary::equal(Word word, const char *str, unsigned len) const noexcept
{ {
if (word.size() != len) return word.size() == len &&
return false; equal(word.begin(this), word.end(this), str);
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 bool Dictionary::equal(Word word, Word other) const noexcept
{ {
if (word.size() != other.size()) return word.size() == other.size() &&
return false; equal(word.begin(this), word.end(this), other.begin(this));
}
return std::equal(word.begin(this), word.end(this), other.begin(this),
[](auto wc, auto oc) { bool Dictionary::eqchars(char c1, char c2)
return wc == oc || {
(isalpha(wc) && isalpha(oc) && (wc | 32) == (oc | 32)); return c1 == c2 ||
}); (isalpha(c1) && isalpha(c2) && (c1 | 32) == (c2 | 32));
} }

@ -21,6 +21,7 @@
#include "types.hpp" #include "types.hpp"
#include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
@ -74,7 +75,15 @@ public:
bool equal(Word, const char *, unsigned) const noexcept; bool equal(Word, const char *, unsigned) const noexcept;
bool equal(Word, Word) 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; virtual ~Dictionary() = default;
private:
static bool eqchars(char c1, char c2);
}; };
#endif // ALEEFORTH_DICTIONARY_HPP #endif // ALEEFORTH_DICTIONARY_HPP

@ -17,9 +17,9 @@
*/ */
#include "corewords.hpp" #include "corewords.hpp"
#include "ctype.hpp"
#include "parser.hpp" #include "parser.hpp"
#include <cctype>
#include <cstring> #include <cstring>
int Parser::parse(State& state, const char *str) int Parser::parse(State& state, const char *str)

Loading…
Cancel
Save