From 1c6db5e7b73484c223e1db71962477a0031f1361 Mon Sep 17 00:00:00 2001 From: Robert Bendun Date: Tue, 24 May 2022 03:48:10 +0200 Subject: [PATCH] Removed `say` from default builtins, moved to `src/main.cc` The reason is that `say` requires text output to work, which is platform specific. Interpreter should only register platform independent functions like operations on arrays or math library --- src/interpreter.cc | 26 +++++--------------------- src/main.cc | 12 +++++++++++- src/musique.hh | 4 ---- src/tests/interpreter.cc | 15 --------------- 4 files changed, 16 insertions(+), 41 deletions(-) diff --git a/src/interpreter.cc b/src/interpreter.cc index 363fa52..12c2d25 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -54,17 +54,6 @@ constexpr auto comparison_operator() } Interpreter::Interpreter() - : Interpreter(std::cout) -{ -} - -Interpreter::~Interpreter() -{ - Env::global.reset(); -} - -Interpreter::Interpreter(std::ostream& out) - : out(out) { { // Context initialization context_stack.emplace_back(); @@ -74,7 +63,6 @@ Interpreter::Interpreter(std::ostream& out) env = Env::global = Env::make(); } { // Global default functions initialization - // TODO move `say` to `src/main.cc` since it's platform depdendent auto &global = *Env::global; global.force_define("typeof", +[](Interpreter&, std::vector args) -> Result { assert(args.size() == 1, "typeof expects only one argument"); @@ -92,15 +80,6 @@ Interpreter::Interpreter(std::ostream& out) } }); - global.force_define("say", +[](Interpreter &i, std::vector args) -> Result { - for (auto it = args.begin(); it != args.end(); ++it) { - i.out << *it; - if (std::next(it) != args.end()) - i.out << ' '; - } - i.out << '\n'; - return {}; - }); global.force_define("len", +[](Interpreter &, std::vector args) -> Result { assert(args.size() == 1, "len only accepts one argument"); @@ -142,6 +121,11 @@ Interpreter::Interpreter(std::ostream& out) } } +Interpreter::~Interpreter() +{ + Env::global.reset(); +} + Result Interpreter::eval(Ast &&ast) { switch (ast.type) { diff --git a/src/main.cc b/src/main.cc index 0086dcc..de76fa3 100644 --- a/src/main.cc +++ b/src/main.cc @@ -41,11 +41,21 @@ struct Runner Interpreter interpreter; Runner(std::string port) - : alsa("musique"), interpreter(std::cout) + : alsa("musique") { alsa.init_sequencer(); alsa.connect(port); interpreter.midi_connection = &alsa; + + Env::global->force_define("say", +[](Interpreter&, std::vector args) -> Result { + for (auto it = args.begin(); it != args.end(); ++it) { + std::cout << *it; + if (std::next(it) != args.end()) + std::cout << ' '; + } + std::cout << '\n'; + return {}; + }); } Result run(std::string_view source, std::string_view filename) diff --git a/src/musique.hh b/src/musique.hh index 5ccdd9d..9c5ba8f 100644 --- a/src/musique.hh +++ b/src/musique.hh @@ -585,9 +585,6 @@ struct Interpreter /// It's optional for simple interpreter testing. midi::Connection *midi_connection = nullptr; - /// Output of IO builtins like `say` - std::ostream &out; - /// Operators defined for language std::unordered_map operators; @@ -600,7 +597,6 @@ struct Interpreter Interpreter(); ~Interpreter(); - explicit Interpreter(std::ostream& out); Interpreter(Interpreter const&) = delete; Interpreter(Interpreter &&) = default; diff --git a/src/tests/interpreter.cc b/src/tests/interpreter.cc index 4232b0b..9e3900a 100644 --- a/src/tests/interpreter.cc +++ b/src/tests/interpreter.cc @@ -24,17 +24,6 @@ void evaluates_to(Value value, std::string_view source_code, reflection::source_ }, sl)(); } -void produces_output(std::string_view source_code, std::string_view expected_output, reflection::source_location sl = reflection::source_location::current()) -{ - capture_errors([=]() -> Result { - std::stringstream ss; - Interpreter interpreter(ss); - Try(interpreter.eval(Try(Parser::parse(source_code, "test")))); - expect(eq(ss.str(), expected_output)) << "different evaluation output"; - return {}; - }, sl)(); -} - suite intepreter_test = [] { "Interpreter"_test = [] { should("evaluate literals") = [] { @@ -54,10 +43,6 @@ suite intepreter_test = [] { should("call builtin functions") = [] { evaluates_to(Value::symbol("nil"), "typeof nil"); evaluates_to(Value::symbol("number"), "typeof 100"); - - produces_output("say 5", "5\n"); - produces_output("say 1; say 2; say 3", "1\n2\n3\n"); - produces_output("say 1 2 3", "1 2 3\n"); }; should("allows only for calling which is callable") = [] {