From 8064a0d3fb1badd17ad292284f7fff8a900157af Mon Sep 17 00:00:00 2001 From: Paul Cristian Sarbu Date: Mon, 24 Mar 2025 12:20:25 +0100 Subject: 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. --- .../build_engine/expression/evaluator.cpp | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src/buildtool/build_engine/expression/evaluator.cpp') 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}, -- cgit v1.2.3