summaryrefslogtreecommitdiff
path: root/src/buildtool/build_engine/expression/evaluator.cpp
diff options
context:
space:
mode:
authorKlaus Aehlig <klaus.aehlig@huawei.com>2024-03-25 11:57:42 +0100
committerKlaus Aehlig <klaus.aehlig@huawei.com>2024-03-26 10:56:30 +0100
commit2eaffa5cfb8ad8e5d18ac1ed61b4ae6b976852ee (patch)
tree032cddb636d94ff6ce8f245becaf7055d9045b5b /src/buildtool/build_engine/expression/evaluator.cpp
parentd58620bcf328a500b964fd9190f712c96d6a136e (diff)
downloadjustbuild-2eaffa5cfb8ad8e5d18ac1ed61b4ae6b976852ee.tar.gz
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.
Diffstat (limited to 'src/buildtool/build_engine/expression/evaluator.cpp')
-rw-r--r--src/buildtool/build_engine/expression/evaluator.cpp38
1 files changed, 38 insertions, 0 deletions
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},