From 2eaffa5cfb8ad8e5d18ac1ed61b4ae6b976852ee Mon Sep 17 00:00:00 2001 From: Klaus Aehlig Date: Mon, 25 Mar 2024 11:57:42 +0100 Subject: Expression language: add float operations "*" and "+" Numerical values are used at some places in justbuild: as value for timeout scaling, as well as by the "range" expression that is used, e.g., to define repreated test runs. Therefore, improve support for numerical values by adding basic operations. --- .../build_engine/expression/evaluator.cpp | 38 ++++++++++++++++++++++ 1 file changed, 38 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 d2cee809..4499552b 100644 --- a/src/buildtool/build_engine/expression/evaluator.cpp +++ b/src/buildtool/build_engine/expression/evaluator.cpp @@ -82,6 +82,42 @@ auto Flatten(ExpressionPtr const& expr) -> ExpressionPtr { return ExpressionPtr{result}; } +auto Addition(ExpressionPtr const& expr) -> ExpressionPtr { + if (not expr->IsList()) { + throw Evaluator::EvaluationError{fmt::format( + "Addition expects a list, but found: {}", expr->ToString())}; + } + Expression::number_t result = 0.0; + auto const& list = expr->List(); + std::for_each(list.begin(), list.end(), [&](auto const& f) { + if (not f->IsNumber()) { + throw Evaluator::EvaluationError{fmt::format( + "Non-number entry found for argument to addition: {}", + f->ToString())}; + } + result += f->Number(); + }); + return ExpressionPtr(result); +} + +auto Multiplication(ExpressionPtr const& expr) -> ExpressionPtr { + if (not expr->IsList()) { + throw Evaluator::EvaluationError{fmt::format( + "Multiplication expects a list, but found: {}", expr->ToString())}; + } + Expression::number_t result = 1.0; + auto const& list = expr->List(); + std::for_each(list.begin(), list.end(), [&](auto const& f) { + if (not f->IsNumber()) { + throw Evaluator::EvaluationError{fmt::format( + "Non-number entry found for argument to multiplication: {}", + f->ToString())}; + } + result *= f->Number(); + }); + return ExpressionPtr(result); +} + auto All(ExpressionPtr const& list) -> ExpressionPtr { for (auto const& c : list->List()) { if (not ValueIsTrue(c)) { @@ -954,6 +990,8 @@ auto const kBuiltInFunctions = {"and", AndExpr}, {"or", OrExpr}, {"++", UnaryExpr(Flatten)}, + {"+", UnaryExpr(Addition)}, + {"*", UnaryExpr(Multiplication)}, {"nub_right", UnaryExpr(NubRight)}, {"range", UnaryExpr(Range)}, {"change_ending", ChangeEndingExpr}, -- cgit v1.2.3