10 :
Expression(attributeRegistry.limexHandle, expression, attributeRegistry, newTarget)
16 : attributeRegistry(attributeRegistry)
18 , expression(expression)
19 , compiled(getExpression(expression))
22 if (
auto name =
compiled.getTarget(); name.has_value() ) {
23 if ( name.value() == BPMNOS::Keyword::Undefined ) {
24 throw std::runtime_error(
"Expression: illegal assignment '" + expression +
"'");
31 for (
auto& name : compiled.getVariables() ) {
32 if ( name != BPMNOS::Keyword::Undefined ) {
33 auto attribute = attributeRegistry[ name ];
34 inputs.insert(attribute);
35 variables.push_back(attribute);
38 for (
auto& name : compiled.getCollections() ) {
39 if ( name == BPMNOS::Keyword::Undefined ) {
40 throw std::runtime_error(
"Expression: illegal expression '" + expression +
"'");
42 auto attribute = attributeRegistry[ name ];
43 inputs.insert(attribute);
44 collections.push_back(attribute);
48LIMEX::Expression<double> Expression::getExpression(
const std::string& input)
const {
52 catch (
const std::exception& error ) {
53 throw std::runtime_error(
"Expression: illegal expression '" + input +
"'.\n" + error.what());
58 auto& variableNames =
compiled.getVariables();
59 assert(
compiled.getRoot().operands.size() == 1 );
60 assert(
compiled.getRoot().type == LIMEX::Type::group );
63 assert( !root.operands.empty() );
64 auto& node = std::get< LIMEX::Node<double> >(root.operands[0]);
70 if ( node.type == LIMEX::Type::assign ) {
71 assert( node.operands.size() == 1 );
73 !std::holds_alternative< LIMEX::Node<double> >(node.operands[0]) ||
74 std::get< LIMEX::Node<double> >(node.operands[0]).type != LIMEX::Type::variable
76 throw std::runtime_error(
"Expression: illegal assignment '" +
expression +
"'");
81 if ( node.type != LIMEX::Type::equal_to && node.type != LIMEX::Type::not_equal_to ) {
82 throw std::runtime_error(
"Expression: illegal expression '" +
expression +
"'");
85 assert( node.operands.size() == 2 );
86 assert( std::holds_alternative< LIMEX::Node<double> >(node.operands[0]) );
87 assert( std::holds_alternative< LIMEX::Node<double> >(node.operands[1]) );
88 auto& lhs = std::get< LIMEX::Node<double> >(node.operands[0]);
89 auto& rhs = std::get< LIMEX::Node<double> >(node.operands[1]);
90 assert( !lhs.operands.empty() );
91 assert( !rhs.operands.empty() );
94 lhs.type != LIMEX::Type::variable ||
96 rhs.type != LIMEX::Type::variable ||
99 throw std::runtime_error(
"Expression: illegal comparison '" +
expression +
"'");
109 assert(
compiled.getRoot().operands.size() == 1 );
110 assert(
compiled.getRoot().type == LIMEX::Type::group );
112 auto& node = std::get< LIMEX::Node<double> >(root.operands[0]);
113 if ( node.type == LIMEX::Type::variable ) {
120template <
typename DataType>
128 return number( (
double)!value.has_value() );
133 return number( (
double)value.has_value() );
137 std::vector< double > variableValues;
140 if ( !value.has_value() ) {
144 variableValues.push_back( (
double)value.value() );
148 std::vector< std::vector< double > > collectionValues;
150 collectionValues.push_back( {} );
152 if ( !collection.has_value() ) {
157 collectionValues.back().push_back( value );
162 return number(
compiled.evaluate(variableValues,collectionValues));
164 catch (
const std::runtime_error& e) {
165 std::string arguments;
167 if (attribute !=
variables.front()) arguments +=
", ";
168 arguments += attribute->name +
" = ";
170 assert( value.has_value() );
173 throw std::runtime_error(std::format(
"Expression: failed to evaluate '{}' with {}\n{}",
expression, arguments, e.what()));
CollectionRegistry collectionRegistry
std::optional< BPMNOS::number > getValue(const Attribute *attribute, const Values &status, const Values &data, const Values &globals) const
Class representing a mathematical expression.
const AttributeRegistry & attributeRegistry
Expression(const std::string expression, const AttributeRegistry &attributeRegistry, bool newTarget=false)
Construct expression using attributeRegistry's limexHandle.
const Attribute * isAttribute() const
Returns pointer to the attribute if and only if expression contains nothing else.
std::set< const Attribute * > inputs
Vector containing all input attributes and collections used by the expression.
std::optional< const Attribute * > target
const LIMEX::Expression< double > compiled
std::vector< const Attribute * > variables
Vector containing all input attributes used by the expression.
const std::string expression
std::vector< const Attribute * > collections
Vector containing all input collections used by the expression.
const LIMEX::Handle< double > & handle
std::optional< BPMNOS::number > execute(const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
const std::string Undefined
std::string to_string(number numericValue, const ValueType &type)
Converts a number to a string.
std::string encodeQuotedStrings(std::string text)
BPMNOS_NUMBER_TYPE number