scan builtin; Value and Array conviniance constructors made explicit
This commit is contained in:
parent
20bf379332
commit
b6b1209014
@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
* Added `scan` builtin, which computes prefix sum of passed values when provided with addition operator
|
||||
|
||||
### Fixed
|
||||
|
||||
* Prevented accidental recursive construction of Arrays and Values by making convinience constructor `Value::Value(std::vector<Value>&&)` explicit
|
||||
|
||||
## [0.1.0] - 2022-09-25
|
||||
|
||||
### Added
|
||||
|
@ -564,6 +564,28 @@ static Result<Value> builtin_fold(Interpreter &interpreter, std::vector<Value> a
|
||||
return init;
|
||||
}
|
||||
|
||||
/// Scan computes inclusive prefix sum
|
||||
static Result<Value> builtin_scan(Interpreter &interpreter, std::vector<Value> args)
|
||||
{
|
||||
if (args.size()) {
|
||||
if (auto p = get_if<Function>(args.front())) {
|
||||
auto xs = Try(flatten(interpreter, std::span(args).subspan(1)));
|
||||
for (auto i = 1u; i < xs.size(); ++i) {
|
||||
xs[i] = Try((*p)(interpreter, { xs[i-1], xs[i] }));
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
}
|
||||
|
||||
return errors::Unsupported_Types_For {
|
||||
.type = errors::Unsupported_Types_For::Function,
|
||||
.name = "scan",
|
||||
.possibilities = {
|
||||
"(callback, ...array) -> any"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Execute blocks depending on condition
|
||||
static Result<Value> builtin_if(Interpreter &i, std::vector<Value> args) {
|
||||
static constexpr auto guard = Guard<2> {
|
||||
@ -997,6 +1019,7 @@ void Interpreter::register_builtin_functions()
|
||||
global.force_define("reverse", builtin_reverse);
|
||||
global.force_define("rotate", builtin_rotate);
|
||||
global.force_define("round", apply_numeric_transform<&Number::round>);
|
||||
global.force_define("scan", builtin_scan);
|
||||
global.force_define("shuffle", builtin_shuffle);
|
||||
global.force_define("sim", builtin_sim);
|
||||
global.force_define("sort", builtin_sort);
|
||||
|
@ -89,8 +89,8 @@ static Result<Value> plus_minus_operator(Interpreter &interpreter, std::vector<V
|
||||
|
||||
static_assert(std::is_same_v<std::plus<>, Binary_Operation> || std::is_same_v<std::minus<>, Binary_Operation>,
|
||||
"Error message printing only supports operators given above");
|
||||
return Error {
|
||||
.details = errors::Unsupported_Types_For {
|
||||
|
||||
return errors::Unsupported_Types_For {
|
||||
.type = errors::Unsupported_Types_For::Operator,
|
||||
.name = std::is_same_v<std::plus<>, Binary_Operation> ? "+" : "-",
|
||||
.possibilities = {
|
||||
@ -100,7 +100,6 @@ static Result<Value> plus_minus_operator(Interpreter &interpreter, std::vector<V
|
||||
"(array, number|music) -> array",
|
||||
"(number|music, array) -> array",
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ Array::Array(Array &&) = default;
|
||||
Array::~Array() = default;
|
||||
|
||||
Array::Array(std::vector<Value>&& elements)
|
||||
: elements{std::move(elements)}
|
||||
: elements(std::move(elements))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ struct Array : Collection
|
||||
std::vector<Value> elements;
|
||||
|
||||
Array();
|
||||
Array(std::vector<Value>&&);
|
||||
explicit Array(std::vector<Value>&&);
|
||||
Array(Array const&);
|
||||
Array(Array &&);
|
||||
~Array() override;
|
||||
|
@ -38,7 +38,7 @@ struct Value
|
||||
Value(char const* s); ///< Create value of type symbol holding provided symbol
|
||||
Value(std::string s); ///< Create value of type symbol holding provided symbol
|
||||
Value(std::string_view s); ///< Create value of type symbol holding provided symbol
|
||||
Value(std::vector<Value> &&array); ///< Create value of type array holding provided array
|
||||
explicit Value(std::vector<Value> &&array); ///< Create value of type array holding provided array
|
||||
|
||||
// TODO Most strings should not be allocated by Value, but reference to string allocated previously
|
||||
// Wrapper for std::string is needed that will allocate only when needed, middle ground between:
|
||||
|
Loading…
Reference in New Issue
Block a user