From ff45c72b7a5f50e5b915fd973e41c855f0b2b6da Mon Sep 17 00:00:00 2001 From: Stepan Usatiuk Date: Wed, 3 Jan 2024 18:58:43 +0100 Subject: [PATCH] epl --- src/main.cpp | 52 +++++++++++++++++++++++++++++++---- src/support/include/Options.h | 3 +- src/vm/include/VM.h | 2 ++ src/vm/src/Parser.cpp | 4 +-- src/vm/src/VM.cpp | 2 +- 5 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 31b266d..68fef6f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,14 +1,27 @@ +#include #include +#include +#include #include #include "MemoryContext.h" #include "Parser.h" #include "VM.h" +std::optional infile; + void parse_options(int argc, char *argv[]) { for (int i = 1; i < argc; i++) { std::string arg = argv[i]; + + if (arg == "-f") { + if (++i >= argc) throw std::invalid_argument("-f given but no file"); + infile = argv[i]; + continue; + } + + if (arg.length() < 2 || arg.substr(0, 2) != "--") { throw std::invalid_argument("Can't parse argument " + arg); } std::string rest = arg.substr(2); @@ -55,14 +68,43 @@ int main(int argc, char *argv[]) { parser.loadStr("(READ EVAL PRINT STOP)"); repl = parser.parseExpr(); } + Handle epl; + { + Parser parser; + parser.loadStr("(EVAL PRINT STOP)"); + epl = parser.parseExpr(); + } + VM vm; - while (true) { - std::cout << std::endl; - vm.loadControl(repl); - vm.run(); - std::cout << std::endl; + if (infile) { + Handle parsed; + std::stringstream buffer; + buffer << "("; + { + std::ifstream t(*infile); + buffer << t.rdbuf(); + } + buffer << ")"; + Parser parser; + parser.loadStr(buffer.str()); + parsed = parser.parseExpr(); + + Handle cur_expr = parsed; + while (!cur_expr.null()) { + vm.loadStack(Handle::cons(cur_expr.car(), nullptr)); + vm.loadControl(epl); + vm.run(); + cur_expr = cur_expr.cdr(); + } } + if (Options::get_bool("repl")) + while (true) { + std::cout << std::endl; + vm.loadControl(repl); + vm.run(); + std::cout << std::endl; + } } catch (const std::exception &e) { std::cerr << "\nError: " << e.what() << std::endl; return -1; diff --git a/src/support/include/Options.h b/src/support/include/Options.h index a415a57..c688f43 100644 --- a/src/support/include/Options.h +++ b/src/support/include/Options.h @@ -23,7 +23,8 @@ public: private: const static inline std::unordered_map> _defaults{{"cell_limit", 50000U}, {"command_strs", false}, - {"default_log_level", 1U}}; + {"default_log_level", 1U}, + {"repl", true}}; std::unordered_map> _current = _defaults; std::shared_mutex _mutex; diff --git a/src/vm/include/VM.h b/src/vm/include/VM.h index 20b4348..afb88e8 100644 --- a/src/vm/include/VM.h +++ b/src/vm/include/VM.h @@ -24,6 +24,8 @@ public: _stop = false; } + void loadStack(const Handle &h) { _s = h; } + void step(); private: diff --git a/src/vm/src/Parser.cpp b/src/vm/src/Parser.cpp index 9193909..8143a5b 100644 --- a/src/vm/src/Parser.cpp +++ b/src/vm/src/Parser.cpp @@ -57,7 +57,7 @@ std::string Parser::Tokenizer::getNext() { std::string_view Parser::Tokenizer::peek() const { return _tokens.front(); } void Parser::Tokenizer::load(std::string_view input) { - std::string_view::size_type curpos = input.find_first_not_of(' '); + std::string_view::size_type curpos = input.find_first_not_of(std::string{' ', '\n', '\r'}); static const std::string alnum = "-+>