consteval and other refactoring

optimize
Clyne 1 year ago
parent 70e399b498
commit 5991370657
Signed by: clyne
GPG Key ID: 3267C8EBF3F9AFC7

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

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

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

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

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

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

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

Loading…
Cancel
Save