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
This commit is contained in:
Robert Bendun 2022-05-24 03:48:10 +02:00
parent 2c19db7354
commit 1c6db5e7b7
4 changed files with 16 additions and 41 deletions

View File

@ -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<Value> args) -> Result<Value> {
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<Value> args) -> Result<Value> {
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<Value> args) -> Result<Value> {
assert(args.size() == 1, "len only accepts one argument");
@ -142,6 +121,11 @@ Interpreter::Interpreter(std::ostream& out)
}
}
Interpreter::~Interpreter()
{
Env::global.reset();
}
Result<Value> Interpreter::eval(Ast &&ast)
{
switch (ast.type) {

View File

@ -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<Value> args) -> Result<Value> {
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<void> run(std::string_view source, std::string_view filename)

View File

@ -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<std::string, Intrinsic> operators;
@ -600,7 +597,6 @@ struct Interpreter
Interpreter();
~Interpreter();
explicit Interpreter(std::ostream& out);
Interpreter(Interpreter const&) = delete;
Interpreter(Interpreter &&) = default;

View File

@ -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<void> {
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") = [] {