builtin mix; fixed vectorized equality

This commit is contained in:
Robert Bendun 2022-09-05 23:52:26 +02:00
parent d77f844c81
commit 91f401a13a
2 changed files with 39 additions and 1 deletions

View File

@ -746,6 +746,36 @@ static Result<Value> builtin_incoming(Interpreter &i, std::vector<Value> args)
return Value{};
}
/// Interleaves arguments
static Result<Value> builtin_mix(Interpreter &i, std::vector<Value> args)
{
std::vector<Value> result;
std::unordered_map<std::size_t, std::size_t> indicies;
size_t awaiting_containers = std::count_if(args.begin(), args.end(), [](Value const& v) { return is_indexable(v.type); });
// Algorithm description:
// Repeat until all arguments were exhausted:
// For each argument:
// If it can be iterated then add current element to the list and move to the next one.
// If next element cannot be retrived mark container as exhausted and start from beginning
// Otherwise append element to the list
do {
for (size_t idx = 0; idx < args.size(); ++idx) {
if (auto &arg = args[idx]; is_indexable(arg.type)) {
result.push_back(Try(arg.index(i, indicies[idx]++ % arg.size())));
if (indicies[idx] == arg.size())
awaiting_containers--;
} else {
result.push_back(arg);
}
}
} while (awaiting_containers);
return Value::from(std::move(result));
}
void Interpreter::register_builtin_functions()
{
auto &global = *Env::global;
@ -764,6 +794,7 @@ void Interpreter::register_builtin_functions()
global.force_define("len", builtin_len);
global.force_define("max", builtin_max);
global.force_define("min", builtin_min);
global.force_define("mix", builtin_mix);
global.force_define("note_off", builtin_note_off);
global.force_define("note_on", builtin_note_on);
global.force_define("nprimes", builtin_primes);

View File

@ -136,7 +136,14 @@ static Result<Value> equality_operator(Interpreter &interpreter, std::vector<Val
std::vector<Value> result;
result.reserve(args[0].size());
for (auto i = 0u; i < args[0].size(); ++i) {
result.push_back(Value::from(Try(args[0].index(interpreter, i)) == args[1]));
result.push_back(
Value::from(
Binary_Predicate{}(
Try(args[0].index(interpreter, i)),
args[1]
)
)
);
}
return Value::from(Array { std::move(result) });
}