From 55554606a1e1c714e974ac020c464dadd72460b3 Mon Sep 17 00:00:00 2001 From: Robert Bendun Date: Tue, 14 Jun 2022 11:21:37 +0200 Subject: [PATCH] partition function --- src/interpreter.cc | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/interpreter.cc b/src/interpreter.cc index f0cdf34..c3ddcd0 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -47,13 +47,19 @@ static constexpr bool is_indexable(Value::Type type) return type == Value::Type::Array || type == Value::Type::Block; } +/// Returns if type can be called +static constexpr bool is_callable(Value::Type type) +{ + return type == Value::Type::Block || type == Value::Type::Intrinsic; +} + /// Binary operation may be vectorized when there are two argument which one is indexable and other is not static bool may_be_vectorized(std::vector const& args) { return args.size() == 2 && (is_indexable(args[0].type) != is_indexable(args[1].type)); } -static Result into_flat_array(Interpreter &i, std::vector args) +static Result into_flat_array(Interpreter &i, std::span args) { Array array; for (auto &arg : args) { @@ -75,6 +81,11 @@ static Result into_flat_array(Interpreter &i, std::vector args) return array; } +static Result into_flat_array(Interpreter &i, std::vector args) +{ + return into_flat_array(i, std::span(args)); +} + /// Intrinsic implementation primitive to ease operation vectorization /// @invariant args.size() == 2 Result vectorize(auto &&operation, Interpreter &interpreter, std::vector args) @@ -401,6 +412,24 @@ Interpreter::Interpreter() return *max; }); + global.force_define("partition", +[](Interpreter &i, std::vector args) -> Result { + assert(!args.empty(), "partition requires function to partition with"); // TODO(assert) + auto predicate = std::move(args.front()); + assert(is_callable(predicate.type), "partition requires function to partition with"); // TODO(assert) + + auto array = Try(into_flat_array(i, std::span(args).subspan(1))); + + Array tuple[2] = {}; + for (auto &value : array.elements) { + tuple[Try(predicate(i, { std::move(value) })).truthy()].elements.push_back(std::move(value)); + } + + return Value::from(Array { .elements = { + Value::from(std::move(tuple[true])), + Value::from(std::move(tuple[false])) + }}); + }); + global.force_define("chord", +[](Interpreter &i, std::vector args) -> Result { Chord chord; Try(create_chord(chord.notes, i, std::move(args)));