diff options
Diffstat (limited to 'libalee/state.hpp')
-rw-r--r-- | libalee/state.hpp | 117 |
1 files changed, 87 insertions, 30 deletions
diff --git a/libalee/state.hpp b/libalee/state.hpp index 0ac9a7c..a5e49b5 100644 --- a/libalee/state.hpp +++ b/libalee/state.hpp @@ -1,20 +1,22 @@ -/** - * 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/>. - */ +// +/// @file state.hpp +/// @brief Provides object to manage execution and interpretation state. +// +// 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_STATE_HPP #define ALEEFORTH_STATE_HPP @@ -26,31 +28,53 @@ #include <csetjmp> #include <cstddef> +/** + * Size of the primary data stack, number of cells. + */ constexpr unsigned DataStackSize = 64; + +/** + * Size of the return stack, number of cells. + */ constexpr unsigned ReturnStackSize = 64; +/** + * @class State + * Object to track execution state. + */ class State { + /** Input functions should add input to the input buffer when available. */ using InputFunc = void (*)(State&); + /** Context object that defines a state of execution. */ struct Context { - Addr ip = 0; - std::jmp_buf jmpbuf = {}; + Addr ip = 0; /** Instruction pointer */ + std::jmp_buf jmpbuf = {}; /** setjmp() buffer for exiting execute() */ }; public: + /** Reference to dictionary used by this state. */ Dictionary& dict; + /** + * Constructs a state object that uses the given dictionary and input + * function. + * @param d The dictionary to be used by this state + * @param i The input collection function to be used by this state + */ constexpr State(Dictionary& d, InputFunc i): dict(d), inputfunc(i), context() {} /** - * Begins execution at the given execution token. + * Begins execution starting from the given execution token. * If the token is a CoreWord, this function exits after its execution. * Otherwise, execution continues until the word's execution completes. * Encountering an error will cause this function to exit immediately. + * @param addr The token to be executed + * @return An error token to indicate if execution was successful */ - Error execute(Addr); + Error execute(Addr addr); /** * Clears the data and return stacks, sets ip to zero, and clears the @@ -58,25 +82,30 @@ public: */ void reset(); + /** Returns a reference to the instruction pointer. */ LIBALEE_SECTION Addr& ip() noexcept { return context.ip; } + /** Calls the user input function with this state as the argument. */ LIBALEE_SECTION void input() noexcept { inputfunc(*this); } + /** Returns true if currently in a compiling state. */ bool compiling() const; + /** Sets the compiling state. True if compiling, false if interpreting. */ void compiling(bool); + /** Returns the number of values stored on the data stack. */ std::size_t size() const noexcept; + /** Returns the number of values stored on the return stack. */ std::size_t rsize() const noexcept; /** - * Saves execution state so that a new execution can begin. - * Used for EVALUATE. + * Returns the current execution state. Usually followed by a load() call. */ Context save(); @@ -85,49 +114,77 @@ public: */ void load(const Context&); + /** + * Pushes the given value to the data stack. + */ LIBALEE_SECTION inline void push(Cell value) { verify(dsp < dstack + DataStackSize, Error::push); *dsp++ = value; } + /** + * Pops a value from the data stack and returns that value. + */ LIBALEE_SECTION inline Cell pop() { verify(dsp > dstack, Error::pop); return *--dsp; } + /** + * Pushes the given value to the return stack. + */ LIBALEE_SECTION inline void pushr(Cell value) { verify(rsp < rstack + ReturnStackSize, Error::pushr); *rsp++ = value; } + /** + * Pops a value from the return stack and returns that value. + */ LIBALEE_SECTION inline Cell popr() { verify(rsp > rstack, Error::popr); return *--rsp; } + /** + * Returns the value stored at the current data stack position. + */ LIBALEE_SECTION inline Cell& top() { verify(dsp > dstack, Error::top); return *(dsp - 1); } + /** + * Picks a value currently stored on the data stack. + * @param i Index from current position to fetch from + * @return The value stored at the given index + */ LIBALEE_SECTION inline Cell& pick(std::size_t i) { verify(dsp - i > dstack, Error::pick); return *(dsp - i - 1); } - // Advances the instruction pointer and returns that cell's contents. + /** + * Advances the instruction pointer and returns that cell's contents. + */ LIBALEE_SECTION inline Cell beyondip() { context.ip += sizeof(Cell); return dict.read(context.ip); } + /** + * Asserts the given condition is true, longjmp-ing if false. + * Used as an exception handler and the method of exiting execution. + * @param condition Condition to be tested + * @param error Error code to report via longjmp() on false condition + */ LIBALEE_SECTION inline void verify(bool condition, Error error) { if (!condition) @@ -135,13 +192,13 @@ public: } private: - InputFunc inputfunc; // User-provided function to collect "stdin" input. - Context context; + InputFunc inputfunc; /** User-provided function to collect user input. */ + Context context; /** State's current execution context. */ - Cell dstack[DataStackSize] = {}; - Cell rstack[ReturnStackSize] = {}; - Cell *dsp = dstack; - Cell *rsp = rstack; + Cell dstack[DataStackSize] = {}; /** Data stack */ + Cell rstack[ReturnStackSize] = {}; /** Return stack */ + Cell *dsp = dstack; /** Current data stack position */ + Cell *rsp = rstack; /** Current return stack position */ }; #endif // ALEEFORTH_STATE_HPP |