/// sforth, an implementation of forth /// Copyright (C) 2024 Clyne Sullivan /// /// This program is free software: you can redistribute it and/or modify it /// under the terms of the GNU 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 General Public License for /// more details. /// /// You should have received a copy of the GNU General Public License along /// with this program. If not, see . #include "sforth/forth.hpp" #include #include #include #include #include #include constinit static sforth::forth<4096> forth {sforth::initialize<&forth>()}; constinit static sforth::native_word<".", [](auto) { char buf[8 * sizeof(sforth::cell) + 1] = {}; std::to_chars(buf, buf + sizeof(buf), forth.pop(), forth.base); std::cout << buf << ' '; }> dot; constinit static sforth::native_word<"U.", [](auto) { char buf[8 * sizeof(sforth::cell) + 1] = {}; std::to_chars(buf, buf + sizeof(buf), std::bit_cast(forth.pop()), forth.base); std::cout << buf << ' '; }, &dot> udot; constinit static sforth::native_word<"EMIT", [](auto) { std::cout << static_cast(forth.pop()); }, &udot> emit; constinit static sforth::native_word<"TYPE", [](auto) { const unsigned u = forth.pop(); const auto caddr = reinterpret_cast(forth.pop()); std::cout << std::string_view{caddr, u}; }, &emit> type; static bool parse_stream(auto&, std::istream&, bool say_okay = false); int main(int argc, const char *argv[]) { std::span args (argv + 1, argc - 1); dot.next = std::exchange(forth.next, &type); for (auto arg : args) { if (std::ifstream file {arg}; parse_stream(forth, file)) return 0; } parse_stream(forth, std::cin, true); } bool parse_stream(auto &fth, std::istream& str, bool say_okay) { std::string line; while (str.good()) { std::getline(str, line); if (!line.empty()) { if (sforth::isequal(line, "bye")) return true; try { fth.parse_line(line); } catch (sforth::error e) { std::cerr << sforth::error_string(e) << " in " << line << std::endl; continue; } } if (say_okay) std::cout << (fth.compiling ? "compiled" : "ok") << std::endl; } return false; }