From f7a9103bbef39b7f6c5909d7f74fa2aea4b81fe1 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Fri, 13 Oct 2023 10:13:31 -0400 Subject: [PATCH] more refactoring, object organization --- libalee/corewords.cpp | 23 ++++++++------- libalee/parser.cpp | 19 +++++------- libalee/state.cpp | 22 ++++++-------- libalee/state.hpp | 68 +++++++++++++++++++++++++------------------ 4 files changed, 69 insertions(+), 63 deletions(-) diff --git a/libalee/corewords.cpp b/libalee/corewords.cpp index 34125bd..e9b9f47 100644 --- a/libalee/corewords.cpp +++ b/libalee/corewords.cpp @@ -44,6 +44,8 @@ void CoreWords::run(Cell ins, State& state) Addr index = ins; + auto& ip = state.ip(); + auto popd = [](State& s) { DoubleCell dcell = s.pop(); dcell <<= sizeof(Cell) * 8; @@ -59,8 +61,8 @@ void CoreWords::run(Cell ins, State& state) execute: if (index >= Dictionary::Begin) { // must be calling a defined subroutine - state.pushr(state.ip); - state.ip = index; + state.pushr(ip); + ip = index; return; } else switch (index) { case 0: // _lit @@ -154,22 +156,21 @@ execute: case 22: // colon state.push(state.dict.alignhere()); while (!state.dict.hasInput()) - state.input(state); + state.input(); state.dict.addDefinition(state.dict.input()); state.compiling(true); break; case 23: // tick while (!state.dict.hasInput()) - state.input(state); + state.input(); find(state, state.dict.input()); break; case 24: // execute index = state.pop(); goto execute; case 25: // exit - state.ip = state.popr(); - if (state.ip == 0) - std::longjmp(state.jmpbuf, static_cast(Error::exit)); + ip = state.popr(); + state.verify(ip != 0, Error::exit); break; case 26: // semic state.dict.add(findi("exit")); @@ -188,7 +189,7 @@ execute: } [[fallthrough]]; case 28: // _jmp - state.ip = state.beyondip(); + ip = state.beyondip(); return; case 29: // depth state.push(static_cast(state.size())); @@ -197,12 +198,12 @@ execute: state.push(static_cast(state.rsize())); break; case 31: // _in - state.input(state); + state.input(); break; case 32: // _ex { const auto st = state.save(); - state.ip = 0; + ip = 0; Parser::parseSource(state); state.load(st); } @@ -244,7 +245,7 @@ execute: break; } - state.ip += sizeof(Cell); + ip += sizeof(Cell); } template diff --git a/libalee/parser.cpp b/libalee/parser.cpp index 2b1d8e1..da7ae0b 100644 --- a/libalee/parser.cpp +++ b/libalee/parser.cpp @@ -20,14 +20,14 @@ #include "ctype.hpp" #include "parser.hpp" +#include +#include + Error Parser::parse(State& state, const char *str) { auto addr = Dictionary::Input; - Cell len = 0; - for (auto ptr = str; *ptr; ++ptr) - ++len; - + const auto len = static_cast(std::strlen(str)); state.dict.write(addr, 0); state.dict.write(Dictionary::SourceLen, len); @@ -43,15 +43,12 @@ Error Parser::parse(State& state, const char *str) Error Parser::parseSource(State& state) { - auto word = state.dict.input(); - while (word.size() > 0) { - if (auto ret = parseWord(state, word); ret != Error::none) - return ret; + auto err = Error::none; - word = state.dict.input(); - } + while (err == Error::none && state.dict.hasInput()) + err = parseWord(state, state.dict.input()); - return Error::none; + return err; } Error Parser::parseWord(State& state, Word word) diff --git a/libalee/state.cpp b/libalee/state.cpp index b19d291..6e12999 100644 --- a/libalee/state.cpp +++ b/libalee/state.cpp @@ -32,34 +32,30 @@ void State::compiling(bool yes) dict.write(Dictionary::Compiling, yes); } -std::pair State::save() +State::Context State::save() { - std::pair st; - st.first = ip; - std::memcpy(st.second, jmpbuf, sizeof(std::jmp_buf)); - return st; + return context; } -void State::load(const std::pair& st) +void State::load(const State::Context& ctx) { - ip = st.first; - std::memcpy(jmpbuf, st.second, sizeof(std::jmp_buf)); + context = ctx; } Error State::execute(Addr addr) { - auto stat = static_cast(setjmp(jmpbuf)); + auto stat = static_cast(setjmp(context.jmpbuf)); if (stat == Error::none) { CoreWords::run(addr, *this); - if (ip >= Dictionary::Begin) { + if (context.ip >= Dictionary::Begin) { // longjmp will exit this loop. for (;;) - CoreWords::run(dict.read(ip), *this); + CoreWords::run(dict.read(context.ip), *this); } else { // addr was a CoreWord, all done now. - ip = 0; + context.ip = 0; } } else if (stat == Error::exit) { stat = Error::none; @@ -76,7 +72,7 @@ void State::reset() popr(); dict.write(Dictionary::Compiling, 0); - ip = 0; + context.ip = 0; } std::size_t State::size() const noexcept diff --git a/libalee/state.hpp b/libalee/state.hpp index 3a79693..12a3aeb 100644 --- a/libalee/state.hpp +++ b/libalee/state.hpp @@ -24,25 +24,24 @@ #include #include -#include constexpr unsigned DataStackSize = 16; constexpr unsigned ReturnStackSize = 16; class State { - friend class CoreWords; + using InputFunc = void (*)(State&); + + struct Context { + Addr ip = 0; + std::jmp_buf jmpbuf = {}; + }; public: - Addr ip = 0; Dictionary& dict; - void (*input)(State&); // User-provided function to collect "stdin" input. - constexpr State(Dictionary& d, void (*i)(State&)): - dict(d), input(i) {} - - bool compiling() const; - void compiling(bool); + constexpr State(Dictionary& d, InputFunc i): + dict(d), inputfunc(i), context() {} /** * Begins execution at the given execution token. @@ -58,9 +57,31 @@ public: */ void reset(); + Addr& ip() noexcept { + return context.ip; + } + + void input() noexcept { + inputfunc(*this); + } + + bool compiling() const; + void compiling(bool); + std::size_t size() const noexcept; std::size_t rsize() const noexcept; + /** + * Saves execution state so that a new execution can begin. + * Used for EVALUATE. + */ + Context save(); + + /** + * Reloads the given execution state. + */ + void load(const Context&); + inline void push(Cell value) { verify(dsp < dstack + DataStackSize, Error::push); *dsp++ = value; @@ -93,32 +114,23 @@ public: // Advances the instruction pointer and returns that cell's contents. inline Cell beyondip() { - ip += sizeof(Cell); - return dict.read(ip); + context.ip += sizeof(Cell); + return dict.read(context.ip); } -private: - Cell dstack[DataStackSize] = {}; - 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(error)); + std::longjmp(context.jmpbuf, static_cast(error)); } - /** - * Saves execution state so that a new execution can begin. - * Used for EVALUATE. - */ - std::pair save(); +private: + InputFunc inputfunc; // User-provided function to collect "stdin" input. + Context context; - /** - * Reloads the given execution state. - */ - void load(const std::pair&); + Cell dstack[DataStackSize] = {}; + Cell rstack[ReturnStackSize] = {}; + Cell *dsp = dstack; + Cell *rsp = rstack; }; #endif // ALEEFORTH_STATE_HPP