Started builtins refactoring and testing
This commit is contained in:
parent
548b29d897
commit
bc5736bf35
@ -31,6 +31,28 @@ concept Iterable = (With_Index_Method<T> || With_Index_Operator<T>) && requires
|
||||
{ t.size() } -> std::convertible_to<usize>;
|
||||
};
|
||||
|
||||
static Result<std::vector<Value>> deep_flat(Interpreter &interpreter, Iterable auto const& array)
|
||||
{
|
||||
std::vector<Value> result;
|
||||
|
||||
for (auto i = 0u; i < array.size(); ++i) {
|
||||
Value element;
|
||||
if constexpr (With_Index_Method<decltype(array)>) {
|
||||
element = Try(array.index(interpreter, i));
|
||||
} else {
|
||||
element = std::move(array[i]);
|
||||
}
|
||||
|
||||
if (auto collection = get_if<Collection>(element)) {
|
||||
std::ranges::move(Try(deep_flat(interpreter, *collection)), std::back_inserter(result));
|
||||
} else {
|
||||
result.push_back(std::move(element));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Create chord out of given notes
|
||||
template<Iterable T>
|
||||
static inline std::optional<Error> create_chord(std::vector<Note> &chord, Interpreter &interpreter, T&& args)
|
||||
@ -543,7 +565,7 @@ static Result<Value> builtin_fold(Interpreter &interpreter, std::vector<Value> a
|
||||
|
||||
/// Execute blocks depending on condition
|
||||
static Result<Value> builtin_if(Interpreter &i, std::vector<Value> args) {
|
||||
constexpr auto guard = Guard<2> {
|
||||
static constexpr auto guard = Guard<2> {
|
||||
.name = "if",
|
||||
.possibilities = {
|
||||
"(any, function) -> any",
|
||||
@ -656,7 +678,7 @@ static Result<Value> builtin_shuffle(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
static std::mt19937 rnd{std::random_device{}()};
|
||||
auto array = Try(flatten(i, std::move(args)));
|
||||
std::shuffle(array.begin(), array.end(), rnd);
|
||||
std::ranges::shuffle(array, rnd);
|
||||
return array;
|
||||
}
|
||||
|
||||
@ -664,7 +686,7 @@ static Result<Value> builtin_shuffle(Interpreter &i, std::vector<Value> args)
|
||||
static Result<Value> builtin_permute(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
auto array = Try(flatten(i, std::move(args)));
|
||||
std::next_permutation(array.begin(), array.end());
|
||||
std::ranges::next_permutation(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
@ -672,7 +694,7 @@ static Result<Value> builtin_permute(Interpreter &i, std::vector<Value> args)
|
||||
static Result<Value> builtin_sort(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
auto array = Try(flatten(i, std::move(args)));
|
||||
std::sort(array.begin(), array.end());
|
||||
std::ranges::sort(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
@ -680,28 +702,26 @@ static Result<Value> builtin_sort(Interpreter &i, std::vector<Value> args)
|
||||
static Result<Value> builtin_reverse(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
auto array = Try(flatten(i, std::move(args)));
|
||||
std::reverse(array.begin(), array.end());
|
||||
std::ranges::reverse(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
/// Get minimum of arguments
|
||||
static Result<Value> builtin_min(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
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;
|
||||
auto array = Try(deep_flat(i, std::move(args)));
|
||||
if (auto min = std::ranges::min_element(array); min != array.end())
|
||||
return *min;
|
||||
return Value{};
|
||||
}
|
||||
|
||||
/// Get maximum of arguments
|
||||
static Result<Value> builtin_max(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
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;
|
||||
auto array = Try(deep_flat(i, std::move(args)));
|
||||
if (auto max = std::ranges::max_element(array); max != array.end())
|
||||
return *max;
|
||||
return Value{};
|
||||
}
|
||||
|
||||
/// Parition arguments into 2 arrays based on predicate
|
||||
@ -935,7 +955,8 @@ static Result<Value> builtin_call(Interpreter &i, std::vector<Value> args)
|
||||
return guard.yield_error();
|
||||
}
|
||||
|
||||
auto &callable = *Try(guard.match<Function>(args.front()));
|
||||
auto fst = std::move(args.front());
|
||||
auto &callable = *Try(guard.match<Function>(fst));
|
||||
args.erase(args.begin());
|
||||
return callable(i, std::move(args));
|
||||
}
|
||||
|
@ -205,6 +205,8 @@ Result<Value> Interpreter::eval(Ast &&ast)
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << ast.type << std::endl;
|
||||
std::cout << ast.token.type << std::endl;
|
||||
unreachable();
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ struct Intrinsic : Function
|
||||
constexpr ~Intrinsic() = default;
|
||||
|
||||
/// Calls underlying function pointer
|
||||
Result<Value> operator()(Interpreter&, std::vector<Value>) const;
|
||||
Result<Value> operator()(Interpreter&, std::vector<Value>) const override;
|
||||
|
||||
/// Compares if function pointers are equal
|
||||
bool operator==(Intrinsic const&) const = default;
|
||||
|
8
regression-tests/builtin/call.mq
Normal file
8
regression-tests/builtin/call.mq
Normal file
@ -0,0 +1,8 @@
|
||||
-- Call executes blocks without parameters
|
||||
say (call [42]);
|
||||
|
||||
-- Call executes block passing parameters
|
||||
say (call [n | n + 1] 10);
|
||||
|
||||
-- Call executes builtin functions
|
||||
call say 43;
|
13
regression-tests/builtin/if.mq
Normal file
13
regression-tests/builtin/if.mq
Normal file
@ -0,0 +1,13 @@
|
||||
-- If executes then first block when condition is true
|
||||
if true [say 1];
|
||||
if true [say 2] [say 3];
|
||||
|
||||
-- If executes second block when condition is false
|
||||
if false [say 4] [say 5];
|
||||
|
||||
-- If returns nil when without else block
|
||||
say (if false [say 6]);
|
||||
|
||||
-- If returns block execution value
|
||||
say (if true [7]);
|
||||
say (if false [say 100; 8] [say 200; 9]);
|
6
regression-tests/builtin/max.mq
Normal file
6
regression-tests/builtin/max.mq
Normal file
@ -0,0 +1,6 @@
|
||||
say (max 1 2 5 4 3);
|
||||
say (max (200 + up 10));
|
||||
say (max (100 + down 10));
|
||||
|
||||
-- Max should do deep search
|
||||
say (max 1 2 [3; 4; [5; 10; 8]; 1] 2);
|
6
regression-tests/builtin/min.mq
Normal file
6
regression-tests/builtin/min.mq
Normal file
@ -0,0 +1,6 @@
|
||||
say (min 1 2 5 4 3);
|
||||
say (min (200 + up 10));
|
||||
say (min (100 + down 10));
|
||||
|
||||
-- Min should do deep search
|
||||
say (min 1 2 [3; 4; [5; 0; 8]; 1] 2);
|
4
regression-tests/builtin/reverse.mq
Normal file
4
regression-tests/builtin/reverse.mq
Normal file
@ -0,0 +1,4 @@
|
||||
say (reverse []);
|
||||
say (reverse (up 10));
|
||||
say (reverse (reverse (up 10)));
|
||||
say (reverse [[1; 2; 3]; 4; 5] 6 7 [[8; 9]]);
|
Loading…
Reference in New Issue
Block a user