/// sforth, an implementation of forth /// Copyright (C) 2024 Clyne Sullivan <clyne@bitgloo.com> /// /// 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 <http://www.gnu.org/licenses/>. #include "forth.hpp" #include <array> #include <fstream> #include <iostream> #include <span> #include <string> static std::array<forth::cell, 1024> dict; static auto fth = new (dict.data()) forth; static bool parse_stream(forth *, std::istream&, bool say_okay = false); int main(int argc, const char *argv[]) { std::span args (argv + 1, argc - 1); forth::initialize<&fth>(dict.end()); fth->add(".", [](auto) { std::cout << fth->pop() << ' '; }); fth->add("emit", [](auto) { std::cout << static_cast<char>(fth->pop()); }); for (auto arg : args) { if (std::ifstream file {arg}; parse_stream(fth, file)) return 0; } parse_stream(fth, std::cin, true); } bool parse_stream(forth *fth, std::istream& str, bool say_okay) { std::string line; while (str.good()) { std::getline(str, line); if (!line.empty()) { if (line == "bye") return true; try { fth->parse_line(line); } catch (forth::error e) { std::cerr << fth->error_string(e); continue; } } if (say_okay) std::cout << (fth->compiling ? "compiled" : "ok") << std::endl; } return false; }