/// 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 static std::array dict; static sforth::forth *fth = [] constexpr { fth = new (dict.data()) sforth::forth; sforth::initialize<&fth>(dict.end()); return fth; }(); static bool parse_stream(sforth::forth *, std::istream&, bool say_okay = false); int main(int argc, const char *argv[]) { std::span args (argv + 1, argc - 1); fth->add(".", [](auto) { char buf[32] = {}; std::to_chars(buf, buf + sizeof(buf), fth->pop(), fth->base); std::cout << buf << ' '; }); fth->add("emit", [](auto) { std::cout << static_cast(fth->pop()); }); fth->add("dictsize", [](auto) { fth->push(dict.size() * sizeof(sforth::cell)); }); for (auto arg : args) { if (std::ifstream file {arg}; parse_stream(fth, file)) return 0; } parse_stream(fth, std::cin, true); } bool parse_stream(sforth::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 (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; }