some class refactoring

optimize
Clyne 11 months ago
parent d36bb13f52
commit 15c0c2f789
Signed by: clyne
GPG Key ID: 3267C8EBF3F9AFC7

@ -22,23 +22,6 @@
#include <cstring>
#include <utility>
Word getword(State& state)
{
auto word = state.dict.input();
while (word.size() == 0) {
state.input(state);
word = state.dict.input();
}
return word;
}
void newdef(State& state, Word word)
{
auto& dict = state.dict;
auto addr = dict.alignhere();
dict.addDefinition(word);
state.push(addr);
};
void find(State& state, Word word)
{
if (auto j = state.dict.find(word); j > 0) {
@ -169,11 +152,16 @@ execute:
reinterpret_cast<Addr&>(state.top()) >>= static_cast<Addr>(cell);
break;
case 22: // colon
newdef(state, getword(state));
state.push(state.dict.alignhere());
while (!state.dict.hasInput())
state.input(state);
state.dict.addDefinition(state.dict.input());
state.compiling(true);
break;
case 23: // tick
find(state, getword(state));
while (!state.dict.hasInput())
state.input(state);
find(state, state.dict.input());
break;
case 24: // execute
index = state.pop();

@ -71,8 +71,11 @@ void Dictionary::addDefinition(Word word) noexcept
Cell wsize = word.size();
add(wsize);
for (auto w = word.start; w != word.wend; ++w)
writebyte(allot(1), readbyte(w));
auto it = word.begin(this);
const auto end = word.end(this);
while (it != end)
writebyte(allot(1), *it++);
alignhere();
}
@ -83,10 +86,8 @@ Addr Dictionary::find(Word word) noexcept
for (;;) {
const Addr l = read(lt);
const Addr len = l & 0x1F;
Word lw;
lw.start = lt + sizeof(Cell);
lw.wend = lw.start + len;
const auto lw = Word::fromLength(lt + sizeof(Cell), len);
if (equal(word, lw))
return lt;
else if (lt == Begin)
@ -106,34 +107,54 @@ Addr Dictionary::getexec(Addr addr) noexcept
return aligned(addr);
}
bool Dictionary::hasInput() const noexcept
{
const Addr src = read(Dictionary::Source);
const Addr end = read(Dictionary::SourceLen);
uint8_t idx = read(Dictionary::Input) & 0xFFu;
while (idx < end) {
auto ch = readbyte(src + idx);
if (ch == '\0') {
break;
} else if (!isspace(ch)) {
return true;
}
++idx;
}
return false;
}
Word Dictionary::input() noexcept
{
const Addr src = read(Dictionary::Source);
const Addr end = read(Dictionary::SourceLen);
uint8_t idx = read(Dictionary::Input) & 0xFFu;
Word word;
word.start = src + idx;
word.wend = word.start;
Addr wstart = src + idx;
Addr wend = wstart;
while (idx < end) {
auto ch = readbyte(word.wend);
auto ch = readbyte(wend);
if (isspace(ch)) {
if (word.size() > 0)
if (wend - wstart > 0)
break;
++word.start;
++wstart;
} else if (ch == '\0') {
break;
}
++word.wend;
++wend;
++idx;
}
writebyte(Dictionary::Input, ++idx);
return word;
return Word(wstart, wend);
}
bool Dictionary::equal(Word word, const char *str, unsigned len) const noexcept

@ -109,6 +109,7 @@ public:
* Returns an empty word if the buffer is empty or entirely read.
*/
Word input() noexcept;
bool hasInput() const noexcept;
/**
* Checks if this dictionary's word is equivalent to the given string/size.

@ -85,15 +85,16 @@ Error Parser::parseNumber(State& state, Word word)
{
const auto base = state.dict.read(Dictionary::Base);
DoubleCell result = 0;
auto i = word.start;
bool inv;
char c;
auto it = word.begin(&state.dict);
c = state.dict.readbyte(i);
if (inv = c == '-'; inv)
c = state.dict.readbyte(++i);
bool inv = *it == '-';
if (inv)
++it;
const auto end = word.end(&state.dict);
for (char c; it != end; ++it) {
c = *it;
do {
if (isdigit(c)) {
result *= base;
result += c - '0';
@ -103,10 +104,7 @@ Error Parser::parseNumber(State& state, Word word)
} else {
return Error::noword;
}
if (++i < word.wend)
c = state.dict.readbyte(i);
} while (i < word.wend);
}
if (inv)
result *= -1;

@ -31,11 +31,12 @@ constexpr unsigned ReturnStackSize = 16;
class State
{
friend class CoreWords;
public:
Addr ip = 0;
Dictionary& dict;
void (*input)(State&); // User-provided function to collect "stdin" input.
std::jmp_buf jmpbuf = {}; // Used when catching execution errors.
constexpr State(Dictionary& d, void (*i)(State&)):
dict(d), input(i) {}
@ -43,17 +44,6 @@ public:
bool compiling() const;
void compiling(bool);
/**
* Saves execution state so that a new execution can begin.
* Used for EVALUATE.
*/
std::pair<Addr, std::jmp_buf> save();
/**
* Reloads the given execution state.
*/
void load(const std::pair<Addr, std::jmp_buf>&);
/**
* Begins execution at the given execution token.
* If the token is a CoreWord, this function exits after its execution.
@ -72,38 +62,32 @@ public:
std::size_t rsize() const noexcept;
inline void push(Cell value) {
if (dsp == dstack + DataStackSize)
std::longjmp(jmpbuf, static_cast<int>(Error::push));
verify(dsp < dstack + DataStackSize, Error::push);
*dsp++ = value;
}
inline Cell pop() {
if (dsp == dstack)
std::longjmp(jmpbuf, static_cast<int>(Error::pop));
verify(dsp > dstack, Error::pop);
return *--dsp;
}
inline void pushr(Cell value) {
if (rsp == rstack + ReturnStackSize)
std::longjmp(jmpbuf, static_cast<int>(Error::pushr));
verify(rsp < rstack + ReturnStackSize, Error::pushr);
*rsp++ = value;
}
inline Cell popr() {
if (rsp == rstack)
std::longjmp(jmpbuf, static_cast<int>(Error::popr));
verify(rsp > rstack, Error::popr);
return *--rsp;
}
inline Cell& top() {
if (dsp == dstack)
std::longjmp(jmpbuf, static_cast<int>(Error::top));
verify(dsp > dstack, Error::top);
return *(dsp - 1);
}
inline Cell& pick(std::size_t i) {
if (dsp - i == dstack)
std::longjmp(jmpbuf, static_cast<int>(Error::pick));
verify(dsp - i > dstack, Error::pick);
return *(dsp - i - 1);
}
@ -118,6 +102,23 @@ private:
Cell rstack[ReturnStackSize] = {};
Cell *dsp = dstack;
Cell *rsp = rstack;
std::jmp_buf jmpbuf = {}; // Used when catching execution errors.
inline void verify(bool condition, Error error) {
if (!condition)
std::longjmp(jmpbuf, static_cast<int>(error));
}
/**
* Saves execution state so that a new execution can begin.
* Used for EVALUATE.
*/
std::pair<Addr, std::jmp_buf> save();
/**
* Reloads the given execution state.
*/
void load(const std::pair<Addr, std::jmp_buf>&);
};
#endif // ALEEFORTH_STATE_HPP

@ -40,6 +40,13 @@ Word::iterator& Word::iterator::operator++()
return *this;
}
Word::iterator Word::iterator::operator++(int)
{
const auto copy = *this;
addr++;
return copy;
}
Word::iterator::value_type Word::iterator::operator*()
{
return dict->readbyte(addr);

@ -23,7 +23,7 @@
#include <iterator>
/**
* Configure the below three types to match your platform.
* Configure the below types for your platform.
*/
using Addr = uint16_t;
using Cell = int16_t;
@ -48,13 +48,16 @@ enum class Error : int {
};
/**
* Stores the start and (past-the-)end addresses of a dictionary's word.
* Stores the start and past-the-end addresses of a dictionary's word.
*/
struct Word
class Word
{
Addr start;
Addr wend;
public:
struct iterator;
constexpr explicit Word(Addr s = 0, Addr e = 0):
start(s), wend(e) {}
@ -64,8 +67,6 @@ struct Word
Addr size() const noexcept;
// Iterators provided for std::equal.
struct iterator;
iterator begin(const Dictionary *);
iterator end(const Dictionary *);
@ -83,6 +84,7 @@ struct Word
addr(a), dict(d) {}
iterator& operator++();
iterator operator++(int);
value_type operator*();
bool operator!=(const iterator&);
};

Loading…
Cancel
Save