You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
3.0 KiB
C++

1 year ago
// sprit-forth: A portable subroutine-threaded Forth.
// Copyright (C) 2024 Clyne Sullivan <clyne@bitgloo.com>
1 year ago
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Library General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This library 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 Library General Public License for
// more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef TYPES_HPP
#define TYPES_HPP
#include <array>
#include <cstddef>
#include <cstdint>
#include <memory>
1 year ago
using Cell = intptr_t; /** Type of a dictionary's cell. */
using Addr = uintptr_t; /** Type of a dictionary address. */
using Func = void (*)(); /** Words are built of these types of functions. */
using FuncList = Func const *; /** Words are defined as a list of Func. */
// Cells, Addrs, and Funcs must all be the same size in bytes since the
// dictionary stores all of these types of values.
1 year ago
static_assert(sizeof(Cell) == sizeof(Addr));
static_assert(sizeof(Cell) == sizeof(Func));
/**
* Wraps the given functions so that a function pointer list can be created
* and used for a word's definition.
*/
template<auto... funcs>
constexpr auto WordWrap = []() noexcept {
constexpr static auto wrapper = +[] { (funcs(), ...); };
return &wrapper;
}();
/**
* @struct Word
* @brief Structure of a word's definition.
* A word has a name, a body (list of functions), a link to the next word
* definition, and an immediate indicator. This structure is matched when
* words are defined in the dictionary by ":" and ";".
*/
1 year ago
struct Word {
FuncList list; /** The word's body/definition. */
const char *name; /** Null-terminated string of word's name. */
Word *link = nullptr; /** Link to next word in definition chain. */
Cell imm = 0; /** If non-zero, word is "immediate". */
1 year ago
constexpr Word(const char *n, FuncList l):
list(l), name(n) {}
constexpr Word& markImmediate() noexcept {
imm = -1;
return *this;
}
constexpr bool immediate() const noexcept {
return imm;
}
};
// Words are built in the dictionary by the user using ":". These assertions
// ensure that the structures created by ":" match the actual structure of a
// Word exactly.
1 year ago
static_assert(offsetof(Word, list) == 0);
static_assert(offsetof(Word, name) == 1 * sizeof(Cell));
static_assert(offsetof(Word, link) == 2 * sizeof(Cell));
static_assert(offsetof(Word, imm) == 3 * sizeof(Cell));
static_assert(sizeof(Word) == 4 * sizeof(Cell));
enum class Error : int {
none = 1,
push,
pop,
rpush,
rpop,
noword
};
1 year ago
#endif // TYPES_HPP