File indexing completed on 2025-01-31 09:21:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 #ifdef CEXMC_USE_CUSTOM_FILTER
0045
0046 #include <iostream>
0047 #include <sstream>
0048 #include <string>
0049 #include <cmath>
0050 #include <boost/variant/get.hpp>
0051 #include <boost/format.hpp>
0052 #include "CexmcAST.hh"
0053 #include "CexmcException.hh"
0054
0055
0056 namespace CexmcAST
0057 {
0058 void Subtree::Print( int level ) const
0059 {
0060 static const std::string opId[] =
0061 { "UNINITIALIZED", "TOP", "u -", "!", "*", "/", "+", "-", "<", "<=",
0062 ">", ">=", "=", "!=", "&", "|" };
0063
0064 std::stringstream value;
0065 const Operator * op( boost::get< Operator >( &type ) );
0066
0067 if ( op )
0068 {
0069 value << "-op- " << opId[ op->type ];
0070 }
0071 else
0072 {
0073 const Function * fun( boost::get< Function >( &type ) );
0074 value << "-fun- " << *fun;
0075 }
0076
0077 std::stringstream format;
0078 format << "%|" << level * printIndent << "t|";
0079 std::cout << boost::format( format.str() ) << value.str() << std::endl;
0080
0081 for ( std::vector< Node >::const_iterator k( children.begin() );
0082 k != children.end(); ++k )
0083 {
0084 const Subtree * subtree( boost::get< Subtree >( &*k ) );
0085
0086 if ( subtree )
0087 {
0088 subtree->Print( level + 1 );
0089 }
0090 else
0091 {
0092 const Leaf * leaf( boost::get< Leaf >( &*k ) );
0093 if ( leaf )
0094 PrintLeaf( leaf, level + 1 );
0095 }
0096 }
0097 }
0098
0099
0100 void Subtree::PrintLeaf( const Leaf * leaf, int level ) const
0101 {
0102 const Variable * variable( NULL );
0103 std::stringstream value;
0104
0105 if ( ( variable = boost::get< Variable >( leaf ) ) )
0106 {
0107 value << variable->name;
0108 if ( variable->index1 > 0 )
0109 {
0110 value << "[" << variable->index1;
0111 if ( variable->index2 > 0 )
0112 value << "," << variable->index2;
0113 value << "]";
0114 }
0115 }
0116 else
0117 {
0118 const Constant * constant( boost::get< Constant >( leaf ) );
0119 const int * intConstant( boost::get< int >( constant ) );
0120 const double * doubleConstant( boost::get< double >(
0121 constant ) );
0122
0123 value << ( intConstant ? *intConstant : *doubleConstant );
0124 }
0125
0126 std::stringstream format;
0127 format << "%|" << level * printIndent << "t|";
0128 std::cout << boost::format( format.str() ) << value.str() << std::endl;
0129 }
0130
0131
0132 BasicEval::~BasicEval()
0133 {
0134 }
0135
0136
0137 bool BasicEval::operator()( const Subtree & ast ) const
0138 {
0139 ScalarValueType retval( GetScalarValue( ast ) );
0140 int * intRetval( NULL );
0141 double * doubleRetval( NULL );
0142
0143 intRetval = boost::get< int >( &retval );
0144
0145 if ( ! intRetval )
0146 doubleRetval = boost::get< double >( &retval );
0147
0148 return doubleRetval ? bool( *doubleRetval ) : bool( *intRetval );
0149 }
0150
0151
0152 BasicEval::ScalarValueType BasicEval::GetScalarValue(
0153 const Node & node ) const
0154 {
0155 const Subtree * ast( boost::get< Subtree >( &node ) );
0156
0157 if ( ast )
0158 {
0159 const Operator * op( boost::get< Operator >( &ast->type ) );
0160 if ( op )
0161 {
0162 ScalarValueType left( 0 );
0163 ScalarValueType right( 0 );
0164 int * intLeft( NULL );
0165 double * doubleLeft( NULL );
0166 int * intRight( NULL );
0167 double * doubleRight( NULL );
0168 bool isDoubleRetval( false );
0169
0170 if ( ast->children.size() > 0 )
0171 {
0172 left = GetScalarValue( ast->children[ 0 ] );
0173 intLeft = boost::get< int >( &left );
0174 if ( ! intLeft )
0175 {
0176 doubleLeft = boost::get< double >( &left );
0177 if ( ! doubleLeft )
0178 throw CexmcException( CexmcCFUnexpectedContext );
0179 }
0180 }
0181
0182 switch ( op->type )
0183 {
0184 case And :
0185 case Or :
0186 break;
0187 default :
0188 if ( ast->children.size() > 1 )
0189 {
0190 right = GetScalarValue( ast->children[ 1 ] );
0191 intRight = boost::get< int >( &right );
0192 if ( ! intRight )
0193 {
0194 doubleRight = boost::get< double >( &right );
0195 if ( ! doubleRight )
0196 throw CexmcException(
0197 CexmcCFUnexpectedContext );
0198 }
0199 }
0200 isDoubleRetval = doubleLeft || doubleRight;
0201 break;
0202 }
0203
0204 switch ( op->type )
0205 {
0206 case Uninitialized :
0207 return 1;
0208 case Top :
0209 return left;
0210 case UMinus :
0211 if ( doubleLeft )
0212 return - *doubleLeft;
0213 else
0214 return - *intLeft;
0215 case Not :
0216 if ( doubleLeft )
0217 return ! *doubleLeft;
0218 else
0219 return ! *intLeft;
0220 case Mult :
0221 if ( isDoubleRetval )
0222 return ( doubleLeft ? *doubleLeft : *intLeft ) *
0223 ( doubleRight ? *doubleRight : *intRight );
0224 else
0225 return *intLeft * *intRight;
0226 case Div :
0227 if ( isDoubleRetval )
0228 return ( doubleLeft ? *doubleLeft : *intLeft ) /
0229 ( doubleRight ? *doubleRight : *intRight );
0230 else
0231 return *intLeft / *intRight;
0232 case Plus :
0233 if ( isDoubleRetval )
0234 return ( doubleLeft ? *doubleLeft : *intLeft ) +
0235 ( doubleRight ? *doubleRight : *intRight );
0236 else
0237 return *intLeft + *intRight;
0238 case Minus :
0239 if ( isDoubleRetval )
0240 return ( doubleLeft ? *doubleLeft : *intLeft ) -
0241 ( doubleRight ? *doubleRight : *intRight );
0242 else
0243 return *intLeft - *intRight;
0244 case Less :
0245 if ( isDoubleRetval )
0246 return ( doubleLeft ? *doubleLeft : *intLeft ) <
0247 ( doubleRight ? *doubleRight : *intRight );
0248 else
0249 return *intLeft < *intRight;
0250 case LessEq :
0251 if ( isDoubleRetval )
0252 return ( doubleLeft ? *doubleLeft : *intLeft ) <=
0253 ( doubleRight ? *doubleRight : *intRight );
0254 else
0255 return *intLeft <= *intRight;
0256 case More :
0257 if ( isDoubleRetval )
0258 return ( doubleLeft ? *doubleLeft : *intLeft ) >
0259 ( doubleRight ? *doubleRight : *intRight );
0260 else
0261 return *intLeft > *intRight;
0262 case MoreEq :
0263 if ( isDoubleRetval )
0264 return ( doubleLeft ? *doubleLeft : *intLeft ) >=
0265 ( doubleRight ? *doubleRight : *intRight );
0266 else
0267 return *intLeft >= *intRight;
0268 case Eq :
0269 if ( isDoubleRetval )
0270 return ( doubleLeft ? *doubleLeft : *intLeft ) ==
0271 ( doubleRight ? *doubleRight : *intRight );
0272 else
0273 return *intLeft == *intRight;
0274 case NotEq :
0275 if ( isDoubleRetval )
0276 return ( doubleLeft ? *doubleLeft : *intLeft ) !=
0277 ( doubleRight ? *doubleRight : *intRight );
0278 else
0279 return *intLeft != *intRight;
0280 case And :
0281 if ( doubleLeft )
0282 {
0283 if ( ! *doubleLeft )
0284 return 0;
0285 }
0286 else
0287 {
0288 if ( ! *intLeft )
0289 return 0;
0290 }
0291 right = GetScalarValue( ast->children[ 1 ] );
0292 intRight = boost::get< int >( &right );
0293 if ( ! intRight )
0294 {
0295 doubleRight = boost::get< double >( &right );
0296 if ( ! doubleRight )
0297 throw CexmcException( CexmcCFUnexpectedContext );
0298 }
0299 if ( doubleRight )
0300 {
0301 if ( *doubleRight )
0302 return 1;
0303 }
0304 else
0305 {
0306 if ( *intRight )
0307 return 1;
0308 }
0309 return 0;
0310 case Or :
0311 if ( doubleLeft )
0312 {
0313 if ( *doubleLeft )
0314 return 1;
0315 }
0316 else
0317 {
0318 if ( *intLeft )
0319 return 1;
0320 }
0321 right = GetScalarValue( ast->children[ 1 ] );
0322 intRight = boost::get< int >( &right );
0323 if ( ! intRight )
0324 {
0325 doubleRight = boost::get< double >( &right );
0326 if ( ! doubleRight )
0327 throw CexmcException( CexmcCFUnexpectedContext );
0328 }
0329 if ( doubleRight )
0330 {
0331 if ( *doubleRight )
0332 return 1;
0333 }
0334 else
0335 {
0336 if ( *intRight )
0337 return 1;
0338 }
0339 return 0;
0340 default :
0341 return 0;
0342 }
0343 }
0344 else
0345 {
0346 return GetFunScalarValue( *ast );
0347 }
0348 }
0349 else
0350 {
0351 const Leaf & leaf( boost::get< Leaf >( node ) );
0352 const Constant * constant( boost::get< Constant >( &leaf ) );
0353
0354 if ( constant )
0355 {
0356 return *constant;
0357 }
0358 else
0359 {
0360 const Variable & variable( boost::get< Variable >( leaf ) );
0361 return GetVarScalarValue( variable );
0362 }
0363 }
0364
0365 return 0;
0366 }
0367
0368
0369 BasicEval::ScalarValueType BasicEval::GetFunScalarValue(
0370 const Subtree & ast ) const
0371 {
0372 bool evalResult( false );
0373 ScalarValueType result( GetBasicFunScalarValue( ast, evalResult ) );
0374
0375 if ( evalResult )
0376 return result;
0377
0378 throw CexmcException( CexmcCFUnexpectedFunction );
0379
0380 return 0;
0381 }
0382
0383
0384 BasicEval::ScalarValueType BasicEval::GetVarScalarValue(
0385 const Variable & ) const
0386 {
0387 throw CexmcException( CexmcCFUnexpectedVariable );
0388
0389 return 0;
0390 }
0391
0392
0393 BasicEval::ScalarValueType BasicEval::GetBasicFunScalarValue(
0394 const Subtree & ast, bool & result ) const
0395 {
0396 const Function & fun( boost::get< Function >( ast.type ) );
0397
0398 result = true;
0399
0400 ScalarValueType arg( GetScalarValue( ast.children[ 0 ] ) );
0401 int * intArg( NULL );
0402 double * doubleArg( NULL );
0403
0404 intArg = boost::get< int >( &arg );
0405 if ( ! intArg )
0406 doubleArg = boost::get< double >( &arg );
0407
0408 if ( fun == "Sqr" )
0409 {
0410 if ( doubleArg )
0411 return *doubleArg * *doubleArg;
0412 else
0413 return *intArg * *intArg;
0414 }
0415 if ( fun == "Sqrt" )
0416 {
0417 if ( doubleArg )
0418 return std::sqrt( *doubleArg );
0419 else
0420 return std::sqrt( *intArg );
0421 }
0422
0423 result = false;
0424
0425 return 0;
0426 }
0427 }
0428
0429 #endif
0430