Algorithms like min don't flatten all the way
To restore previous behaviour one can use `min (flat x)`
This commit is contained in:
parent
eb822a4a6e
commit
ab0ba8d4c8
@ -833,14 +833,15 @@ struct Value
|
||||
/// Using Explicit_Bool to prevent from implicit casts
|
||||
static Value from(Explicit_Bool b);
|
||||
|
||||
static Value from(Number n); ///< Create value of type number holding provided number
|
||||
static Value from(std::string s); ///< Create value of type symbol holding provided symbol
|
||||
static Value from(std::string_view s); ///< Create value of type symbol holding provided symbol
|
||||
static Value from(char const* s); ///< Create value of type symbol holding provided symbol
|
||||
static Value from(Block &&l); ///< Create value of type block holding provided block
|
||||
static Value from(Array &&array); ///< Create value of type array holding provided array
|
||||
static Value from(Note n); ///< Create value of type music holding provided note
|
||||
static Value from(Chord chord); ///< Create value of type music holding provided chord
|
||||
static Value from(Array &&array); ///< Create value of type array holding provided array
|
||||
static Value from(Block &&l); ///< Create value of type block holding provided block
|
||||
static Value from(Chord chord); ///< Create value of type music holding provided chord
|
||||
static Value from(Note n); ///< Create value of type music holding provided note
|
||||
static Value from(Number n); ///< Create value of type number holding provided number
|
||||
static Value from(char const* s); ///< Create value of type symbol holding provided symbol
|
||||
static Value from(std::string s); ///< Create value of type symbol holding provided symbol
|
||||
static Value from(std::string_view s); ///< Create value of type symbol holding provided symbol
|
||||
static Value from(std::vector<Value> &&array); ///< Create value of type array holding provided array
|
||||
|
||||
enum class Type
|
||||
{
|
||||
@ -1094,4 +1095,8 @@ static constexpr bool is_callable(Value::Type type)
|
||||
return type == Value::Type::Block || type == Value::Type::Intrinsic;
|
||||
}
|
||||
|
||||
/// Flattens one layer: `[[[1], 2], 3]` becomes `[[1], 2, 3]`
|
||||
Result<std::vector<Value>> flatten(Interpreter &i, std::span<Value>);
|
||||
Result<std::vector<Value>> flatten(Interpreter &i, std::vector<Value>);
|
||||
|
||||
#endif
|
||||
|
@ -111,6 +111,7 @@ static Result<Array> into_flat_array(Interpreter &i, std::vector<Value> args)
|
||||
return into_flat_array(i, std::span(args));
|
||||
}
|
||||
|
||||
|
||||
/// Helper to convert method to it's name
|
||||
template<auto> struct Number_Method_Name;
|
||||
template<> struct Number_Method_Name<&Number::floor> { static constexpr auto value = "floor"; };
|
||||
@ -466,8 +467,8 @@ static Result<Value> builtin_update(Interpreter &i, std::vector<Value> args)
|
||||
|
||||
if (Lazy_And_Number::typecheck_front(args)) {
|
||||
auto [v, index] = Lazy_And_Number::move_from(args);
|
||||
auto array = Try(into_flat_array(i, { Value::from(std::move(v)) }));
|
||||
array.elements[index.as_int()] = std::move(args.back());
|
||||
auto array = Try(flatten(i, { Value::from(std::move(v)) }));
|
||||
array[index.as_int()] = std::move(args.back());
|
||||
return Value::from(std::move(array));
|
||||
}
|
||||
|
||||
@ -500,41 +501,41 @@ static Result<Value> builtin_flat(Interpreter &i, std::vector<Value> args)
|
||||
static Result<Value> builtin_shuffle(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
static std::mt19937 rnd{std::random_device{}()};
|
||||
auto array = Try(into_flat_array(i, std::move(args)));
|
||||
std::shuffle(array.elements.begin(), array.elements.end(), rnd);
|
||||
auto array = Try(flatten(i, std::move(args)));
|
||||
std::shuffle(array.begin(), array.end(), rnd);
|
||||
return Value::from(std::move(array));
|
||||
}
|
||||
|
||||
/// Permute arguments
|
||||
static Result<Value> builtin_permute(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
auto array = Try(into_flat_array(i, std::move(args)));
|
||||
std::next_permutation(array.elements.begin(), array.elements.end());
|
||||
auto array = Try(flatten(i, std::move(args)));
|
||||
std::next_permutation(array.begin(), array.end());
|
||||
return Value::from(std::move(array));
|
||||
}
|
||||
|
||||
/// Sort arguments
|
||||
static Result<Value> builtin_sort(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
auto array = Try(into_flat_array(i, std::move(args)));
|
||||
std::sort(array.elements.begin(), array.elements.end());
|
||||
auto array = Try(flatten(i, std::move(args)));
|
||||
std::sort(array.begin(), array.end());
|
||||
return Value::from(std::move(array));
|
||||
}
|
||||
|
||||
/// Reverse arguments
|
||||
static Result<Value> builtin_reverse(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
auto array = Try(into_flat_array(i, std::move(args)));
|
||||
std::reverse(array.elements.begin(), array.elements.end());
|
||||
auto array = Try(flatten(i, std::move(args)));
|
||||
std::reverse(array.begin(), array.end());
|
||||
return Value::from(std::move(array));
|
||||
}
|
||||
|
||||
/// Get minimum of arguments
|
||||
static Result<Value> builtin_min(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
auto array = Try(into_flat_array(i, std::move(args)));
|
||||
auto min = std::min_element(array.elements.begin(), array.elements.end());
|
||||
if (min == array.elements.end())
|
||||
auto array = Try(flatten(i, std::move(args)));
|
||||
auto min = std::min_element(array.begin(), array.end());
|
||||
if (min == array.end())
|
||||
return Value{};
|
||||
return *min;
|
||||
}
|
||||
@ -542,9 +543,9 @@ static Result<Value> builtin_min(Interpreter &i, std::vector<Value> args)
|
||||
/// Get maximum of arguments
|
||||
static Result<Value> builtin_max(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
auto array = Try(into_flat_array(i, std::move(args)));
|
||||
auto max = std::max_element(array.elements.begin(), array.elements.end());
|
||||
if (max == array.elements.end())
|
||||
auto array = Try(flatten(i, std::move(args)));
|
||||
auto max = std::max_element(array.begin(), array.end());
|
||||
if (max == array.end())
|
||||
return Value{};
|
||||
return *max;
|
||||
}
|
||||
@ -563,10 +564,10 @@ static Result<Value> builtin_partition(Interpreter &i, std::vector<Value> args)
|
||||
|
||||
auto predicate = std::move(args.front());
|
||||
Try(guard(is_callable, predicate));
|
||||
auto array = Try(into_flat_array(i, std::span(args).subspan(1)));
|
||||
auto array = Try(flatten(i, std::span(args).subspan(1)));
|
||||
|
||||
Array tuple[2] = {};
|
||||
for (auto &value : array.elements) {
|
||||
for (auto &value : array) {
|
||||
tuple[Try(predicate(i, { std::move(value) })).truthy()].elements.push_back(std::move(value));
|
||||
}
|
||||
|
||||
@ -589,13 +590,13 @@ static Result<Value> builtin_rotate(Interpreter &i, std::vector<Value> args)
|
||||
}
|
||||
|
||||
auto offset = std::move(args.front()).n.as_int();
|
||||
auto array = Try(into_flat_array(i, std::span(args).subspan(1)));
|
||||
auto array = Try(flatten(i, std::span(args).subspan(1)));
|
||||
if (offset > 0) {
|
||||
offset = offset % array.elements.size();
|
||||
std::rotate(array.elements.begin(), array.elements.begin() + offset, array.elements.end());
|
||||
offset = offset % array.size();
|
||||
std::rotate(array.begin(), array.begin() + offset, array.end());
|
||||
} else if (offset < 0) {
|
||||
offset = -offset % array.elements.size();
|
||||
std::rotate(array.elements.rbegin(), array.elements.rbegin() + offset, array.elements.rend());
|
||||
offset = -offset % array.size();
|
||||
std::rotate(array.rbegin(), array.rbegin() + offset, array.rend());
|
||||
}
|
||||
return Value::from(std::move(array));
|
||||
}
|
||||
|
28
src/value.cc
28
src/value.cc
@ -130,6 +130,14 @@ Value Value::from(Array &&array)
|
||||
return v;
|
||||
}
|
||||
|
||||
Value Value::from(std::vector<Value> &&array)
|
||||
{
|
||||
Value v;
|
||||
v.type = Type::Array;
|
||||
v.array = Array { .elements = std::move(array) };
|
||||
return v;
|
||||
}
|
||||
|
||||
Value Value::from(Note n)
|
||||
{
|
||||
Value v;
|
||||
@ -494,3 +502,23 @@ std::ostream& operator<<(std::ostream& os, Chord const& chord)
|
||||
}
|
||||
return os << ']';
|
||||
}
|
||||
|
||||
Result<std::vector<Value>> flatten(Interpreter &interpreter, std::span<Value> args)
|
||||
{
|
||||
std::vector<Value> result;
|
||||
for (auto &x : args) {
|
||||
if (is_indexable(x.type)) {
|
||||
for (usize i = 0; i < x.size(); ++i) {
|
||||
result.push_back(Try(x.index(interpreter, i)));
|
||||
}
|
||||
} else {
|
||||
result.push_back(std::move(x));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Result<std::vector<Value>> flatten(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
return flatten(i, std::span(args));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user