summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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},