scan builtin; Value and Array conviniance constructors made explicit

This commit is contained in:
Robert Bendun 2022-10-07 17:33:38 +02:00
parent 20bf379332
commit b6b1209014
6 changed files with 44 additions and 14 deletions

View File

@ -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

View File

@ -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);

View File

@ -89,17 +89,16 @@ 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 {
.type = errors::Unsupported_Types_For::Operator,
.name = std::is_same_v<std::plus<>, Binary_Operation> ? "+" : "-",
.possibilities = {
"(number, number) -> number",
"(music, number) -> music",
"(number, music) -> music",
"(array, number|music) -> array",
"(number|music, array) -> array",
}
return errors::Unsupported_Types_For {
.type = errors::Unsupported_Types_For::Operator,
.name = std::is_same_v<std::plus<>, Binary_Operation> ? "+" : "-",
.possibilities = {
"(number, number) -> number",
"(music, number) -> music",
"(number, music) -> music",
"(array, number|music) -> array",
"(number|music, array) -> array",
}
};
});

View File

@ -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))
{
}

View File

@ -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;

View File

@ -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: