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.
# 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

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

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

@ -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/>.
*/
#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));
}

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

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

Loading…
Cancel
Save