Skip to content

Commit 526fcd6

Browse files
committed
Implement support for abs() in subscription expressions
Signed-off-by: Dmitrii Petukhov <[email protected]>
1 parent 4d2b2b8 commit 526fcd6

7 files changed

+179
-78
lines changed

src/groups/bmq/bmqeval/bmqeval_simpleevaluator.cpp

+29
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,35 @@ bdld::Datum SimpleEvaluator::Not::evaluate(EvaluationContext& context) const
364364
return bdld::Datum::createBoolean(!value.theBoolean());
365365
}
366366

367+
// ---------------------------------
368+
// class SimpleEvaluator::Abs
369+
// ---------------------------------
370+
371+
bdld::Datum
372+
SimpleEvaluator::Abs::evaluate(EvaluationContext& context) const
373+
{
374+
bdld::Datum expr = d_expression->evaluate(context);
375+
if (context.d_stop) {
376+
return bdld::Datum::createNull(); // RETURN
377+
}
378+
379+
bsls::Types::Int64 value;
380+
if (expr.isInteger64()) {
381+
value = expr.theInteger64();
382+
}
383+
384+
else if (expr.isInteger()) {
385+
value = expr.theInteger();
386+
}
387+
else {
388+
context.d_lastError = ErrorType::e_TYPE;
389+
return context.stop(); // RETURN
390+
}
391+
392+
value = abs(value);
393+
return bdld::Datum::createInteger64(value, context.d_allocator);
394+
}
395+
367396
// --------------------------
368397
// class SimpleEvaluator::Exists
369398
// --------------------------

src/groups/bmq/bmqeval/bmqeval_simpleevaluator.h

+36
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,33 @@ class SimpleEvaluator {
451451
evaluate(EvaluationContext& context) const BSLS_KEYWORD_OVERRIDE;
452452
};
453453

454+
// ----------
455+
// Abs
456+
// ----------
457+
458+
class Abs : public Expression {
459+
private:
460+
// DATA
461+
462+
// The expression to negate.
463+
ExpressionPtr d_expression;
464+
465+
public:
466+
// CREATORS
467+
468+
/// Create an object that implements arithmetic negation.
469+
explicit Abs(ExpressionPtr expression);
470+
471+
// ACCESSORS
472+
473+
/// Evaluate `expression` passed to the constructor. If it is an
474+
/// integer, return the negated value as an Int64 Datum. Otherwise,
475+
/// set the error in the context to e_TYPE, stop the evaluation,
476+
/// and return a null datum.
477+
bdld::Datum
478+
evaluate(EvaluationContext& context) const BSLS_KEYWORD_OVERRIDE;
479+
};
480+
454481
// ---
455482
// Not
456483
// ---
@@ -995,6 +1022,15 @@ inline SimpleEvaluator::Not::Not(ExpressionPtr expression)
9951022
{
9961023
}
9971024

1025+
// ------------------------------------------
1026+
// template class SimpleEvaluator::Abs
1027+
// ------------------------------------------
1028+
1029+
inline SimpleEvaluator::Abs::Abs(ExpressionPtr expression)
1030+
: d_expression(expression)
1031+
{
1032+
}
1033+
9981034
// ------------------------
9991035
// class CompilationContext
10001036
// ------------------------

src/groups/bmq/bmqeval/bmqeval_simpleevaluator.t.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class MockPropertiesReader : public PropertiesReader {
5353
d_map["i_2"] = bdld::Datum::createInteger(2);
5454
d_map["i_3"] = bdld::Datum::createInteger(3);
5555
d_map["i_42"] = bdld::Datum::createInteger(42);
56+
d_map["i_n42"] = bdld::Datum::createInteger(-42);
5657
d_map["i64_42"] = bdld::Datum::createInteger64(42, allocator);
5758
d_map["s_foo"] = bdld::Datum::createStringRef("foo", allocator);
5859
d_map["exists"] = bdld::Datum::createInteger(42);
@@ -428,6 +429,13 @@ static void test3_evaluation()
428429
// mixed integer types
429430
{"i_42 == 42", true},
430431

432+
// abs function
433+
{"i_n42 == -42", true},
434+
{"-i_n42 == 42", true},
435+
{"abs(i_n42) == 42", true},
436+
{"abs(i_n42) == i_42", true},
437+
{"abs(i_42) == i_42", true},
438+
431439
// string comparisons
432440
{"s_foo == \"foo\"", true},
433441
{"s_foo != \"foo\"", false},

src/groups/bmq/bmqeval/bmqeval_simpleevaluatorparser.y

+8
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
%token TIMES "*" DIVIDES "/" MODULUS "%";
7777
%token EQ "=" NE "<>" LT "<" LE "<=" GE ">=" GT ">";
7878
%token <bsl::string> EXISTS "exists";
79+
%token <bsl::string> ABS "abs";
7980

8081
%left OR;
8182
%left AND;
@@ -108,6 +109,11 @@ variable
108109
++ctx.d_numProperties;
109110
$$ = $1;
110111
}
112+
| ABS
113+
{
114+
++ctx.d_numProperties;
115+
$$ = $1;
116+
}
111117

112118
expression
113119
: variable {
@@ -158,6 +164,8 @@ expression
158164
{ $$ = ctx.makeBooleanBinaryExpression<SimpleEvaluator::Or>($1, $3); }
159165
| NOT expression
160166
{ $$ = ctx.makeUnaryExpression<SimpleEvaluator::Not>($2); }
167+
| ABS LPAR expression RPAR
168+
{ $$ = ctx.makeUnaryExpression<SimpleEvaluator::Abs>($3); }
161169
| expression PLUS expression
162170
{ $$ = ctx.makeNumBinaryExpression<bsl::plus>($1, $3); }
163171
| expression MINUS expression

src/groups/bmq/bmqeval/bmqeval_simpleevaluatorscanner.l

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
return SimpleEvaluatorParser::make_EXISTS(yytext);
3838
}
3939

40+
"abs" {
41+
updatePosition();
42+
return SimpleEvaluatorParser::make_ABS(yytext);
43+
}
44+
4045
[a-zA-Z][a-zA-Z0-9_.]* {
4146
updatePosition();
4247
return SimpleEvaluatorParser::make_PROPERTY(yytext);

src/groups/bmq/bmqu/bmqu_operationchain.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,11 @@
192192

193193
#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
194194
// Include version that can be compiled with C++03
195-
// Generated on Tue Oct 15 17:39:53 2024
195+
// Generated on Fri Feb 14 17:43:15 2025
196196
// Command line: sim_cpp11_features.pl bmqu_operationchain.h
197-
#define COMPILING_BMQU_OPERATIONCHAIN_H
198-
#include <bmqu_operationchain_cpp03.h>
199-
#undef COMPILING_BMQU_OPERATIONCHAIN_H
197+
# define COMPILING_BMQU_OPERATIONCHAIN_H
198+
# include <bmqu_operationchain_cpp03.h>
199+
# undef COMPILING_BMQU_OPERATIONCHAIN_H
200200
#else
201201

202202
namespace BloombergLP {
@@ -301,7 +301,7 @@ class OperationChain_CompletionCallbackWrapper {
301301

302302
public:
303303
// ACCESSORS
304-
#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=9
304+
#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=9
305305

306306
/// Invoke the associated completion callback with the specified `args`
307307
/// arguments and notify the associated operation chain. Propagate any
@@ -806,7 +806,7 @@ inline OperationChain_CompletionCallbackWrapper<CO_CALLBACK>::
806806
}
807807

808808
// ACCESSORS
809-
#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=9
809+
#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=9
810810
template <class CO_CALLBACK>
811811
template <class... ARGS>
812812
inline void OperationChain_CompletionCallbackWrapper<CO_CALLBACK>::operator()(
@@ -1021,6 +1021,6 @@ inline void bmqu::swap(OperationChainLink& lhs,
10211021

10221022
} // close enterprise namespace
10231023

1024-
#endif // End C++11 code
1024+
#endif // End C++11 code
10251025

10261026
#endif

0 commit comments

Comments
 (0)