Skip to content

Commit

Permalink
Implement support for exists() in BISON expressions
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitrii Petukhov <dpetukhov@bloomberg.net>
  • Loading branch information
bbpetukhov committed Feb 24, 2025
1 parent d43b473 commit eb395e9
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 4 deletions.
29 changes: 29 additions & 0 deletions src/groups/bmq/bmqeval/bmqeval_simpleevaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,5 +364,34 @@ bdld::Datum SimpleEvaluator::Not::evaluate(EvaluationContext& context) const
return bdld::Datum::createBoolean(!value.theBoolean());
}

// --------------------------
// class SimpleEvaluator::Exists
// --------------------------

SimpleEvaluator::Exists::Exists(const bsl::string& name)
: d_name(name)
{
}

#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) && \
defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT)
SimpleEvaluator::Exists::Exists(bsl::string&& name) noexcept
: d_name(bsl::move(name))
{
}
#endif

bdld::Datum SimpleEvaluator::Exists::evaluate(EvaluationContext& context) const
{
bdld::Datum value = context.d_propertiesReader->get(d_name,
context.d_allocator);

if (value.isError()) {
return bdld::Datum::createBoolean(false);
}

return bdld::Datum::createBoolean(true);
}

} // close package namespace
} // close enterprise namespace
36 changes: 36 additions & 0 deletions src/groups/bmq/bmqeval/bmqeval_simpleevaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,41 @@ class SimpleEvaluator {
evaluate(EvaluationContext& context) const BSLS_KEYWORD_OVERRIDE;
};

// ---
// Exists
// ---

class Exists : public Expression {
private:
// DATA

// The name of the property.
bsl::string d_name;

public:
// CREATORS

/// Create an object that evaluates property `name`, in the
/// evaluation context, as a boolean.
explicit Exists(const bsl::string& name);

#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) && \
defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT)
/// Create an object that evaluates property `name`, in the
/// evaluation context, as a boolean.
explicit Exists(bsl::string&& name) noexcept;
#endif

// ACCESSORS

/// Evaluate `expression` passed to the constructor. If it is a
/// boolean, return the negated value as a boolean Datum.
/// Otherwise, set the error in the context to e_TYPE, stop the
/// evaluation, and return a null datum.
bdld::Datum
evaluate(EvaluationContext& context) const BSLS_KEYWORD_OVERRIDE;
};

private:
// SimpleEvaluator(const SimpleEvaluator& other) BSLS_KEYWORD_DELETED;
// SimpleEvaluator& operator=(const SimpleEvaluator& other)
Expand Down Expand Up @@ -549,6 +584,7 @@ class SimpleEvaluator {
friend class SimpleEvaluatorScanner; // for access to Expression hierarchy
friend class CompilationContext; // for access to ExpressionPtr
};

// ========================
// class CompilationContext
// ========================
Expand Down
9 changes: 9 additions & 0 deletions src/groups/bmq/bmqeval/bmqeval_simpleevaluator.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class MockPropertiesReader : public PropertiesReader {
d_map["i_42"] = bdld::Datum::createInteger(42);
d_map["i64_42"] = bdld::Datum::createInteger64(42, allocator);
d_map["s_foo"] = bdld::Datum::createStringRef("foo", allocator);
d_map["exists"] = bdld::Datum::createInteger(42);
}
// Destroy this object.

Expand Down Expand Up @@ -520,6 +521,14 @@ static void test3_evaluation()
{"i_0 != -9223372036854775807", true}, // -(2 ** 63) + 1
{"i_0 != 9223372036854775807", true}, // 2 ** 63 - 1
{"i_0 != -9223372036854775808", true}, // -(2 ** 63)

// exists
{"exists(i_42)", true},
{"exists(non_existing_property)", false},
{"exists(i_42) && i_42 > 41", true},
{"exists(non_existing_property) && non_existing_property > 41", false},
{"exists == 42", true},
{"exists(exists)", true},
};
const TestParameters* testParametersEnd = testParameters +
sizeof(testParameters) /
Expand Down
27 changes: 23 additions & 4 deletions src/groups/bmq/bmqeval/bmqeval_simpleevaluatorparser.y
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
%token PLUS "+" MINUS "-";
%token TIMES "*" DIVIDES "/" MODULUS "%";
%token EQ "=" NE "<>" LT "<" LE "<=" GE ">=" GT ">";
%token <bsl::string> EXISTS "exists";

%left OR;
%left AND;
Expand All @@ -84,6 +85,7 @@
%left TIMES DIVIDES MODULUS;
%right NOT "!";

%type<bsl::string> variable;
%type<SimpleEvaluator::ExpressionPtr> expression;
%type<SimpleEvaluator::ExpressionPtr> predicate;
%start predicate
Expand All @@ -95,18 +97,35 @@ predicate : expression END
ctx.d_expression = $1;
}

expression
variable
: PROPERTY
{
++ctx.d_numProperties;
$$ = $1;
}
| EXISTS
{
++ctx.d_numProperties;
$$ = $1;
}

#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) \
expression
: variable {
#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) \
&& defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT)
$$ = ctx.makeUnaryExpression<SimpleEvaluator::Property, bsl::string>(bsl::move($1));
#else
$$ = ctx.makeUnaryExpression<SimpleEvaluator::Property, bsl::string>($1);
#endif

++ctx.d_numProperties;
}
| EXISTS LPAR variable RPAR
{
#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) \
&& defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT)
$$ = ctx.makeUnaryExpression<SimpleEvaluator::Exists, bsl::string>(bsl::move($3));
#else
$$ = ctx.makeUnaryExpression<SimpleEvaluator::Exists, bsl::string>($3);
#endif
}
| INTEGER
{ $$ = ctx.makeLiteral<SimpleEvaluator::IntegerLiteral>($1); }
Expand Down
5 changes: 5 additions & 0 deletions src/groups/bmq/bmqeval/bmqeval_simpleevaluatorscanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
return SimpleEvaluatorParser::make_FALSE();
}

"exists" {
updatePosition();
return SimpleEvaluatorParser::make_EXISTS(yytext);
}

[a-zA-Z][a-zA-Z0-9_.]* {
updatePosition();
return SimpleEvaluatorParser::make_PROPERTY(yytext);
Expand Down

0 comments on commit eb395e9

Please sign in to comment.