diff options
author | Paul Cristian Sarbu <paul.cristian.sarbu@huawei.com> | 2025-03-24 12:20:25 +0100 |
---|---|---|
committer | Paul Cristian Sarbu <paul.cristian.sarbu@huawei.com> | 2025-03-24 16:21:59 +0100 |
commit | 8064a0d3fb1badd17ad292284f7fff8a900157af (patch) | |
tree | e284f929e16a0c561b9036a53fe3ef489ddfed8a | |
parent | a428fdde8dc18ac7ba8738b198f95ae7eaba346d (diff) | |
download | justbuild-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.cpp | 30 |
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}, |