Started builtins refactoring and testing

This commit is contained in:
Robert Bendun 2022-09-25 10:40:36 +02:00
parent 548b29d897
commit bc5736bf35
8 changed files with 77 additions and 17 deletions

View File

@ -31,6 +31,28 @@ concept Iterable = (With_Index_Method<T> || With_Index_Operator<T>) && requires
{ t.size() } -> std::convertible_to<usize>; { 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 /// Create chord out of given notes
template<Iterable T> template<Iterable T>
static inline std::optional<Error> create_chord(std::vector<Note> &chord, Interpreter &interpreter, T&& args) 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 /// Execute blocks depending on condition
static Result<Value> builtin_if(Interpreter &i, std::vector<Value> args) { static Result<Value> builtin_if(Interpreter &i, std::vector<Value> args) {
constexpr auto guard = Guard<2> { static constexpr auto guard = Guard<2> {
.name = "if", .name = "if",
.possibilities = { .possibilities = {
"(any, function) -> any", "(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{}()}; static std::mt19937 rnd{std::random_device{}()};
auto array = Try(flatten(i, std::move(args))); auto array = Try(flatten(i, std::move(args)));
std::shuffle(array.begin(), array.end(), rnd); std::ranges::shuffle(array, rnd);
return array; 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) static Result<Value> builtin_permute(Interpreter &i, std::vector<Value> args)
{ {
auto array = Try(flatten(i, std::move(args))); auto array = Try(flatten(i, std::move(args)));
std::next_permutation(array.begin(), array.end()); std::ranges::next_permutation(array);
return 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) static Result<Value> builtin_sort(Interpreter &i, std::vector<Value> args)
{ {
auto array = Try(flatten(i, std::move(args))); auto array = Try(flatten(i, std::move(args)));
std::sort(array.begin(), array.end()); std::ranges::sort(array);
return 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) static Result<Value> builtin_reverse(Interpreter &i, std::vector<Value> args)
{ {
auto array = Try(flatten(i, std::move(args))); auto array = Try(flatten(i, std::move(args)));
std::reverse(array.begin(), array.end()); std::ranges::reverse(array);
return array; return array;
} }
/// Get minimum of arguments /// Get minimum of arguments
static Result<Value> builtin_min(Interpreter &i, std::vector<Value> args) static Result<Value> builtin_min(Interpreter &i, std::vector<Value> args)
{ {
auto array = Try(flatten(i, std::move(args))); auto array = Try(deep_flat(i, std::move(args)));
auto min = std::min_element(array.begin(), array.end()); if (auto min = std::ranges::min_element(array); min != array.end())
if (min == array.end()) return *min;
return Value{}; return Value{};
return *min;
} }
/// Get maximum of arguments /// Get maximum of arguments
static Result<Value> builtin_max(Interpreter &i, std::vector<Value> args) static Result<Value> builtin_max(Interpreter &i, std::vector<Value> args)
{ {
auto array = Try(flatten(i, std::move(args))); auto array = Try(deep_flat(i, std::move(args)));
auto max = std::max_element(array.begin(), array.end()); if (auto max = std::ranges::max_element(array); max != array.end())
if (max == array.end()) return *max;
return Value{}; return Value{};
return *max;
} }
/// Parition arguments into 2 arrays based on predicate /// 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(); 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()); args.erase(args.begin());
return callable(i, std::move(args)); return callable(i, std::move(args));
} }

View File

@ -205,6 +205,8 @@ Result<Value> Interpreter::eval(Ast &&ast)
} }
} }
std::cout << ast.type << std::endl;
std::cout << ast.token.type << std::endl;
unreachable(); unreachable();
} }

View File

@ -22,7 +22,7 @@ struct Intrinsic : Function
constexpr ~Intrinsic() = default; constexpr ~Intrinsic() = default;
/// Calls underlying function pointer /// 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 /// Compares if function pointers are equal
bool operator==(Intrinsic const&) const = default; bool operator==(Intrinsic const&) const = default;

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

View 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]);

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

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

View 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]]);