From 4dc2cafb17c2dbdb58ada3a200e843a894bfc113 Mon Sep 17 00:00:00 2001 From: Klaus Aehlig Date: Tue, 16 Apr 2024 16:07:21 +0200 Subject: expression language: add array access by index --- .../build_engine/expression/evaluator.cpp | 27 ++++++++++++++++++++++ 1 file changed, 27 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 93e9836a..b8102e95 100644 --- a/src/buildtool/build_engine/expression/evaluator.cpp +++ b/src/buildtool/build_engine/expression/evaluator.cpp @@ -664,6 +664,32 @@ auto LookupExpr(SubExprEvaluator&& eval, return lookup; } +auto ArrayAccessExpr(SubExprEvaluator&& eval, + ExpressionPtr const& expr, + Configuration const& env) -> ExpressionPtr { + auto k = eval(expr["index"], env); + auto d = eval(expr["list"], env); + if (not d->IsList()) { + throw Evaluator::EvaluationError{fmt::format( + "List expected to be list, but found {}.", d->ToString())}; + } + auto len = static_cast(d->List().size()); + int64_t index = 0; + if (k->IsNumber()) { + index = static_cast(std::lround(k->Number())); + } + if (k->IsString()) { + index = std::atol(k->String().c_str()); + } + if (0 <= index and index < len) { + return d->List()[static_cast(index)]; + } + if (index < 0 and len + index >= 0) { + return d->List()[static_cast(len + index)]; + } + return eval(expr->Get("default", Expression::none_t()), env); +} + auto EmptyMapExpr(SubExprEvaluator&& /*eval*/, ExpressionPtr const& /*expr*/, Configuration const& @@ -1053,6 +1079,7 @@ auto const kBuiltInFunctions = {"reverse", UnaryExpr(Reverse)}, {"values", UnaryExpr(Values)}, {"lookup", LookupExpr}, + {"[]", ArrayAccessExpr}, {"empty_map", EmptyMapExpr}, {"singleton_map", SingletonMapExpr}, {"disjoint_map_union", DisjointUnionExpr}, -- cgit v1.2.3