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:
parent
2c19db7354
commit
1c6db5e7b7
@ -54,17 +54,6 @@ constexpr auto comparison_operator()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Interpreter::Interpreter()
|
Interpreter::Interpreter()
|
||||||
: Interpreter(std::cout)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Interpreter::~Interpreter()
|
|
||||||
{
|
|
||||||
Env::global.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
Interpreter::Interpreter(std::ostream& out)
|
|
||||||
: out(out)
|
|
||||||
{
|
{
|
||||||
{ // Context initialization
|
{ // Context initialization
|
||||||
context_stack.emplace_back();
|
context_stack.emplace_back();
|
||||||
@ -74,7 +63,6 @@ Interpreter::Interpreter(std::ostream& out)
|
|||||||
env = Env::global = Env::make();
|
env = Env::global = Env::make();
|
||||||
}
|
}
|
||||||
{ // Global default functions initialization
|
{ // Global default functions initialization
|
||||||
// TODO move `say` to `src/main.cc` since it's platform depdendent
|
|
||||||
auto &global = *Env::global;
|
auto &global = *Env::global;
|
||||||
global.force_define("typeof", +[](Interpreter&, std::vector<Value> args) -> Result<Value> {
|
global.force_define("typeof", +[](Interpreter&, std::vector<Value> args) -> Result<Value> {
|
||||||
assert(args.size() == 1, "typeof expects only one argument");
|
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> {
|
global.force_define("len", +[](Interpreter &, std::vector<Value> args) -> Result<Value> {
|
||||||
assert(args.size() == 1, "len only accepts one argument");
|
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)
|
Result<Value> Interpreter::eval(Ast &&ast)
|
||||||
{
|
{
|
||||||
switch (ast.type) {
|
switch (ast.type) {
|
||||||
|
12
src/main.cc
12
src/main.cc
@ -41,11 +41,21 @@ struct Runner
|
|||||||
Interpreter interpreter;
|
Interpreter interpreter;
|
||||||
|
|
||||||
Runner(std::string port)
|
Runner(std::string port)
|
||||||
: alsa("musique"), interpreter(std::cout)
|
: alsa("musique")
|
||||||
{
|
{
|
||||||
alsa.init_sequencer();
|
alsa.init_sequencer();
|
||||||
alsa.connect(port);
|
alsa.connect(port);
|
||||||
interpreter.midi_connection = &alsa;
|
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)
|
Result<void> run(std::string_view source, std::string_view filename)
|
||||||
|
@ -585,9 +585,6 @@ struct Interpreter
|
|||||||
/// It's optional for simple interpreter testing.
|
/// It's optional for simple interpreter testing.
|
||||||
midi::Connection *midi_connection = nullptr;
|
midi::Connection *midi_connection = nullptr;
|
||||||
|
|
||||||
/// Output of IO builtins like `say`
|
|
||||||
std::ostream &out;
|
|
||||||
|
|
||||||
/// Operators defined for language
|
/// Operators defined for language
|
||||||
std::unordered_map<std::string, Intrinsic> operators;
|
std::unordered_map<std::string, Intrinsic> operators;
|
||||||
|
|
||||||
@ -600,7 +597,6 @@ struct Interpreter
|
|||||||
|
|
||||||
Interpreter();
|
Interpreter();
|
||||||
~Interpreter();
|
~Interpreter();
|
||||||
explicit Interpreter(std::ostream& out);
|
|
||||||
Interpreter(Interpreter const&) = delete;
|
Interpreter(Interpreter const&) = delete;
|
||||||
Interpreter(Interpreter &&) = default;
|
Interpreter(Interpreter &&) = default;
|
||||||
|
|
||||||
|
@ -24,17 +24,6 @@ void evaluates_to(Value value, std::string_view source_code, reflection::source_
|
|||||||
}, sl)();
|
}, 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 = [] {
|
suite intepreter_test = [] {
|
||||||
"Interpreter"_test = [] {
|
"Interpreter"_test = [] {
|
||||||
should("evaluate literals") = [] {
|
should("evaluate literals") = [] {
|
||||||
@ -54,10 +43,6 @@ suite intepreter_test = [] {
|
|||||||
should("call builtin functions") = [] {
|
should("call builtin functions") = [] {
|
||||||
evaluates_to(Value::symbol("nil"), "typeof nil");
|
evaluates_to(Value::symbol("nil"), "typeof nil");
|
||||||
evaluates_to(Value::symbol("number"), "typeof 100");
|
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") = [] {
|
should("allows only for calling which is callable") = [] {
|
||||||
|
Loading…
Reference in New Issue
Block a user