diff options
Diffstat (limited to 'main.cpp')
-rw-r--r-- | main.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..d9cb5c5 --- /dev/null +++ b/main.cpp @@ -0,0 +1,70 @@ +/// 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; +} + |