summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2025-03-24 12:20:25 +0100
committerPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2025-03-24 16:21:59 +0100
commit8064a0d3fb1badd17ad292284f7fff8a900157af (patch)
treee284f929e16a0c561b9036a53fe3ef489ddfed8a
parenta428fdde8dc18ac7ba8738b198f95ae7eaba346d (diff)
downloadjustbuild-8064a0d3fb1badd17ad292284f7fff8a900157af.tar.gz
Add 'zip_with' expression
Produces the list containing the results of evaluating the body on the corresponding elementwise pairs from the two input lists. If the input lists are of different sizes, the extra elements are ignored.
-rw-r--r--src/buildtool/build_engine/expression/evaluator.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/buildtool/build_engine/expression/evaluator.cpp b/src/buildtool/build_engine/expression/evaluator.cpp
index e26c43e0..3f166b36 100644
--- a/src/buildtool/build_engine/expression/evaluator.cpp
+++ b/src/buildtool/build_engine/expression/evaluator.cpp
@@ -1035,6 +1035,35 @@ auto ForeachMapExpr(SubExprEvaluator&& eval,
return ExpressionPtr{result};
}
+auto ZipWithExpr(SubExprEvaluator&& eval,
+ ExpressionPtr const& expr,
+ Configuration const& env) -> ExpressionPtr {
+ auto range_1 = eval(expr->Get("range_1", Expression::kEmptyList), env);
+ auto const& range_1_list = range_1->List();
+ if (range_1_list.empty()) {
+ return Expression::kEmptyList;
+ }
+ auto range_2 = eval(expr->Get("range_2", Expression::kEmptyList), env);
+ auto const& range_2_list = range_2->List();
+ if (range_2_list.empty()) {
+ return Expression::kEmptyList;
+ }
+ auto const size = std::min(range_1_list.size(), range_2_list.size());
+ auto const& var_1 = expr->Get("var_1", "$1"s);
+ auto const& var_2 = expr->Get("var_2", "$2"s);
+ auto const& body = expr->Get("body", list_t{});
+ auto result = Expression::list_t{};
+ result.reserve(size);
+ for (auto it = std::make_pair(range_1_list.begin(), range_2_list.begin());
+ it.first != range_1_list.end() and it.second != range_2_list.end();
+ ++it.first, ++it.second) {
+ result.emplace_back(eval(body,
+ env.Update(var_1->String(), *it.first)
+ .Update(var_2->String(), *it.second)));
+ }
+ return ExpressionPtr{result};
+}
+
auto FoldLeftExpr(SubExprEvaluator&& eval,
ExpressionPtr const& expr,
Configuration const& env) -> ExpressionPtr {
@@ -1331,6 +1360,7 @@ auto const kBuiltInFunctions =
{"from_subdir", FromSubdirExpr},
{"foreach", ForeachExpr},
{"foreach_map", ForeachMapExpr},
+ {"zip_with", ZipWithExpr},
{"foldl", FoldLeftExpr},
{"let*", LetExpr},
{"env", EnvExpr},