// /// @file corewords.hpp /// @brief Manages the fundamental word-set and its execution. // // Alee Forth: A portable and concise Forth implementation in modern C++. // Copyright (C) 2023 Clyne Sullivan // // 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 . #ifndef ALEEFORTH_COREWORDS_HPP #define ALEEFORTH_COREWORDS_HPP #include "config.hpp" #include "dictionary.hpp" #include "types.hpp" #include class State; /** * To be implemented by the user, this function is called when the `sys` word * is executed. * @param state Current execution state object. */ void user_sys(State& state); /** * @class CoreWords * @brief Provides the fundamental word-set and manages its execution. */ class CoreWords { public: /** * Searches for the token/index of the given word if it is part of the * fundamental word-set. * @param state Current execution state object. * @param word Word (stored in state's dictionary memory) to look up. * @return The token/index of the word or -1 if not found. */ static Cell findi(State& state, Word word); /** * Looks up the token/index of the given fundamental word. * Primarily used for compile-time lookup. * @param word The word to look up. * @return The token/index of the word or -1 if not found. */ consteval static Cell token(const char *word) { return findi(word, strlen(word)); } /** * Executes the given execution token using the given state. * @param token Any valid execution token (word, fundamental, constant...). * @param state The state object to execute with. */ static void run(Cell token, State& state); /** * String lookup table for the fundamental word-set. * This also determines the opcode (index) of these words. */ constexpr static char wordsarr[] = "_lit\0drop\0dup\0swap\0pick\0sys\0" "+\0-\0m*\0_/\0_%\0" "_@\0_!\0>r\0r>\0=\0" "<\0&\0|\0^\0" "<<\0>>\0:\0_'\0execute\0" "exit\0;\0_jmp0\0_jmp\0" "depth\0_rdepth\0_in\0_ev\0find\0" "_uma\0u<\0um/mod\0_nx\0"; /** * Count of total fundamental words. */ constexpr static Cell WordCount = [] { return std::count(wordsarr, wordsarr + sizeof(wordsarr), '\0'); }(); private: /** * Generic implementation of findi(). Private; use public implementations. * @param it Beginning iterator of the word to search for. * @param size Size of the searched-for word i.e. end == it + size. * @return The token/index of the word or -1 if not found. */ template LIBALEE_SECTION 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 = strlen(ptr); if (wordsize == size && Dictionary::equal(ptr, ptr + wordsize, it)) return wordsi; ptr += wordsize + 1; } return -1; } public: static void word_lit(State&); static void word_drop(State&); static void word_dup(State&); static void word_swap(State&); static void word_pick(State&); static void word_sys(State&); static void word_add(State&); static void word_sub(State&); static void word_mul(State&); static void word_div(State&); static void word_mod(State&); static void word_peek(State&); static void word_poke(State&); static void word_rpush(State&); static void word_rpop(State&); static void word_eq(State&); static void word_lt(State&); static void word_and(State&); static void word_or(State&); static void word_xor(State&); static void word_shl(State&); static void word_shr(State&); static void word_colon(State&); static void word_tick(State&); static void word_execute(State&); static void word_exit(State&); static void word_semic(State&); static void word_jmp0(State&); static void word_jmp(State&); static void word_depth(State&); static void word_rdepth(State&); static void word_in(State&); static void word_ev(State&); static void word_find(State&); static void word_uma(State&); static void word_ult(State&); static void word_ummod(State&); constexpr static void (*wordstbl[])(State&) = { word_lit, word_drop, word_dup, word_swap, word_pick, word_sys, word_add, word_sub, word_mul, word_div, word_mod, word_peek, word_poke, word_rpush, word_rpop, word_eq, word_lt, word_and, word_or, word_xor, word_shl, word_shr, word_colon, word_tick, word_execute, word_exit, word_semic, word_jmp0, word_jmp, word_depth, word_rdepth, word_in, word_ev, word_find, word_uma, word_ult, word_ummod }; }; #endif // ALEEFORTH_COREWORDS_HPP