Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 /* 26 /* 27 * =========================================== 27 * ============================================================================= 28 * 28 * 29 * Filename: CexmcAST.cc 29 * Filename: CexmcAST.cc 30 * 30 * 31 * Description: abstract syntax tree for c 31 * Description: abstract syntax tree for custom filter scripting language 32 * 32 * 33 * Version: 1.0 33 * Version: 1.0 34 * Created: 17.07.2010 14:45:14 34 * Created: 17.07.2010 14:45:14 35 * Revision: none 35 * Revision: none 36 * Compiler: gcc 36 * Compiler: gcc 37 * 37 * 38 * Author: Alexey Radkov (), 38 * Author: Alexey Radkov (), 39 * Company: PNPI 39 * Company: PNPI 40 * 40 * 41 * =========================================== 41 * ============================================================================= 42 */ 42 */ 43 43 44 #ifdef CEXMC_USE_CUSTOM_FILTER 44 #ifdef CEXMC_USE_CUSTOM_FILTER 45 45 46 #include <iostream> 46 #include <iostream> 47 #include <sstream> 47 #include <sstream> 48 #include <string> 48 #include <string> 49 #include <cmath> 49 #include <cmath> 50 #include <boost/variant/get.hpp> 50 #include <boost/variant/get.hpp> 51 #include <boost/format.hpp> 51 #include <boost/format.hpp> 52 #include "CexmcAST.hh" 52 #include "CexmcAST.hh" 53 #include "CexmcException.hh" 53 #include "CexmcException.hh" 54 54 55 55 56 namespace CexmcAST 56 namespace CexmcAST 57 { 57 { 58 void Subtree::Print( int level ) const 58 void Subtree::Print( int level ) const 59 { 59 { 60 static const std::string opId[] = 60 static const std::string opId[] = 61 { "UNINITIALIZED", "TOP", "u -", " 61 { "UNINITIALIZED", "TOP", "u -", "!", "*", "/", "+", "-", "<", "<=", 62 ">", ">=", "=", "!=", "&", "|" } 62 ">", ">=", "=", "!=", "&", "|" }; 63 63 64 std::stringstream value; 64 std::stringstream value; 65 const Operator * op( boost::g 65 const Operator * op( boost::get< Operator >( &type ) ); 66 66 67 if ( op ) 67 if ( op ) 68 { 68 { 69 value << "-op- " << opId[ op->type 69 value << "-op- " << opId[ op->type ]; 70 } 70 } 71 else 71 else 72 { 72 { 73 const Function * fun( boost::get< 73 const Function * fun( boost::get< Function >( &type ) ); 74 value << "-fun- " << *fun; 74 value << "-fun- " << *fun; 75 } 75 } 76 76 77 std::stringstream format; 77 std::stringstream format; 78 format << "%|" << level * printIndent 78 format << "%|" << level * printIndent << "t|"; 79 std::cout << boost::format( format.str 79 std::cout << boost::format( format.str() ) << value.str() << std::endl; 80 80 81 for ( std::vector< Node >::const_itera 81 for ( std::vector< Node >::const_iterator k( children.begin() ); 82 82 k != children.end(); ++k ) 83 { 83 { 84 const Subtree * subtree( boost::g 84 const Subtree * subtree( boost::get< Subtree >( &*k ) ); 85 85 86 if ( subtree ) 86 if ( subtree ) 87 { 87 { 88 subtree->Print( level + 1 ); 88 subtree->Print( level + 1 ); 89 } 89 } 90 else 90 else 91 { 91 { 92 const Leaf * leaf( boost::get 92 const Leaf * leaf( boost::get< Leaf >( &*k ) ); 93 if ( leaf ) 93 if ( leaf ) 94 PrintLeaf( leaf, level + 1 94 PrintLeaf( leaf, level + 1 ); 95 } 95 } 96 } 96 } 97 } 97 } 98 98 99 99 100 void Subtree::PrintLeaf( const Leaf * le 100 void Subtree::PrintLeaf( const Leaf * leaf, int level ) const 101 { 101 { 102 const Variable * variable( NULL ); 102 const Variable * variable( NULL ); 103 std::stringstream value; 103 std::stringstream value; 104 104 105 if ( ( variable = boost::get< Variable 105 if ( ( variable = boost::get< Variable >( leaf ) ) ) 106 { 106 { 107 value << variable->name; 107 value << variable->name; 108 if ( variable->index1 > 0 ) 108 if ( variable->index1 > 0 ) 109 { 109 { 110 value << "[" << variable->inde 110 value << "[" << variable->index1; 111 if ( variable->index2 > 0 ) 111 if ( variable->index2 > 0 ) 112 value << "," << variable-> 112 value << "," << variable->index2; 113 value << "]"; 113 value << "]"; 114 } 114 } 115 } 115 } 116 else 116 else 117 { 117 { 118 const Constant * constant( boost: 118 const Constant * constant( boost::get< Constant >( leaf ) ); 119 const int * intConstant( boo 119 const int * intConstant( boost::get< int >( constant ) ); 120 const double * doubleConstant( 120 const double * doubleConstant( boost::get< double >( 121 121 constant ) ); 122 122 123 value << ( intConstant ? *intConst 123 value << ( intConstant ? *intConstant : *doubleConstant ); 124 } 124 } 125 125 126 std::stringstream format; 126 std::stringstream format; 127 format << "%|" << level * printIndent 127 format << "%|" << level * printIndent << "t|"; 128 std::cout << boost::format( format.str 128 std::cout << boost::format( format.str() ) << value.str() << std::endl; 129 } 129 } 130 130 131 131 132 BasicEval::~BasicEval() 132 BasicEval::~BasicEval() 133 { 133 { 134 } 134 } 135 135 136 136 137 bool BasicEval::operator()( const Subtree 137 bool BasicEval::operator()( const Subtree & ast ) const 138 { 138 { 139 ScalarValueType retval( GetScalarValu 139 ScalarValueType retval( GetScalarValue( ast ) ); 140 int * intRetval( NULL ); 140 int * intRetval( NULL ); 141 double * doubleRetval( NULL ); 141 double * doubleRetval( NULL ); 142 142 143 intRetval = boost::get< int >( &retval 143 intRetval = boost::get< int >( &retval ); 144 144 145 if ( ! intRetval ) 145 if ( ! intRetval ) 146 doubleRetval = boost::get< double 146 doubleRetval = boost::get< double >( &retval ); 147 147 148 return doubleRetval ? bool( *doubleRet 148 return doubleRetval ? bool( *doubleRetval ) : bool( *intRetval ); 149 } 149 } 150 150 151 151 152 BasicEval::ScalarValueType BasicEval::Get 152 BasicEval::ScalarValueType BasicEval::GetScalarValue( 153 153 const Node & node ) const 154 { 154 { 155 const Subtree * ast( boost::get< Subt 155 const Subtree * ast( boost::get< Subtree >( &node ) ); 156 156 157 if ( ast ) 157 if ( ast ) 158 { 158 { 159 const Operator * op( boost::get< 159 const Operator * op( boost::get< Operator >( &ast->type ) ); 160 if ( op ) 160 if ( op ) 161 { 161 { 162 ScalarValueType left 162 ScalarValueType left( 0 ); 163 ScalarValueType righ 163 ScalarValueType right( 0 ); 164 int * intL 164 int * intLeft( NULL ); 165 double * doub 165 double * doubleLeft( NULL ); 166 int * intR 166 int * intRight( NULL ); 167 double * doub 167 double * doubleRight( NULL ); 168 bool isDo 168 bool isDoubleRetval( false ); 169 169 170 if ( ast->children.size() > 0 170 if ( ast->children.size() > 0 ) 171 { 171 { 172 left = GetScalarValue( ast 172 left = GetScalarValue( ast->children[ 0 ] ); 173 intLeft = boost::get< int 173 intLeft = boost::get< int >( &left ); 174 if ( ! intLeft ) 174 if ( ! intLeft ) 175 { 175 { 176 doubleLeft = boost::ge 176 doubleLeft = boost::get< double >( &left ); 177 if ( ! doubleLeft ) 177 if ( ! doubleLeft ) 178 throw CexmcExcepti 178 throw CexmcException( CexmcCFUnexpectedContext ); 179 } 179 } 180 } 180 } 181 181 182 switch ( op->type ) 182 switch ( op->type ) 183 { 183 { 184 case And : 184 case And : 185 case Or : 185 case Or : 186 break; 186 break; 187 default : 187 default : 188 if ( ast->children.size() 188 if ( ast->children.size() > 1 ) 189 { 189 { 190 right = GetScalarValue 190 right = GetScalarValue( ast->children[ 1 ] ); 191 intRight = boost::get< 191 intRight = boost::get< int >( &right ); 192 if ( ! intRight ) 192 if ( ! intRight ) 193 { 193 { 194 doubleRight = boos 194 doubleRight = boost::get< double >( &right ); 195 if ( ! doubleRight 195 if ( ! doubleRight ) 196 throw CexmcExc 196 throw CexmcException( 197 197 CexmcCFUnexpectedContext ); 198 } 198 } 199 } 199 } 200 isDoubleRetval = doubleLef 200 isDoubleRetval = doubleLeft || doubleRight; 201 break; 201 break; 202 } 202 } 203 203 204 switch ( op->type ) 204 switch ( op->type ) 205 { 205 { 206 case Uninitialized : 206 case Uninitialized : 207 return 1; 207 return 1; 208 case Top : 208 case Top : 209 return left; 209 return left; 210 case UMinus : 210 case UMinus : 211 if ( doubleLeft ) 211 if ( doubleLeft ) 212 return - *doubleLeft; 212 return - *doubleLeft; 213 else 213 else 214 return - *intLeft; 214 return - *intLeft; 215 case Not : 215 case Not : 216 if ( doubleLeft ) 216 if ( doubleLeft ) 217 return ! *doubleLeft; 217 return ! *doubleLeft; 218 else 218 else 219 return ! *intLeft; 219 return ! *intLeft; 220 case Mult : 220 case Mult : 221 if ( isDoubleRetval ) 221 if ( isDoubleRetval ) 222 return ( doubleLeft ? 222 return ( doubleLeft ? *doubleLeft : *intLeft ) * 223 ( doubleRight ? 223 ( doubleRight ? *doubleRight : *intRight ); 224 else 224 else 225 return *intLeft * *int 225 return *intLeft * *intRight; 226 case Div : 226 case Div : 227 if ( isDoubleRetval ) 227 if ( isDoubleRetval ) 228 return ( doubleLeft ? 228 return ( doubleLeft ? *doubleLeft : *intLeft ) / 229 ( doubleRight ? 229 ( doubleRight ? *doubleRight : *intRight ); 230 else 230 else 231 return *intLeft / *int 231 return *intLeft / *intRight; 232 case Plus : 232 case Plus : 233 if ( isDoubleRetval ) 233 if ( isDoubleRetval ) 234 return ( doubleLeft ? 234 return ( doubleLeft ? *doubleLeft : *intLeft ) + 235 ( doubleRight ? 235 ( doubleRight ? *doubleRight : *intRight ); 236 else 236 else 237 return *intLeft + *int 237 return *intLeft + *intRight; 238 case Minus : 238 case Minus : 239 if ( isDoubleRetval ) 239 if ( isDoubleRetval ) 240 return ( doubleLeft ? 240 return ( doubleLeft ? *doubleLeft : *intLeft ) - 241 ( doubleRight ? 241 ( doubleRight ? *doubleRight : *intRight ); 242 else 242 else 243 return *intLeft - *int 243 return *intLeft - *intRight; 244 case Less : 244 case Less : 245 if ( isDoubleRetval ) 245 if ( isDoubleRetval ) 246 return ( doubleLeft ? 246 return ( doubleLeft ? *doubleLeft : *intLeft ) < 247 ( doubleRight ? 247 ( doubleRight ? *doubleRight : *intRight ); 248 else 248 else 249 return *intLeft < *int 249 return *intLeft < *intRight; 250 case LessEq : 250 case LessEq : 251 if ( isDoubleRetval ) 251 if ( isDoubleRetval ) 252 return ( doubleLeft ? 252 return ( doubleLeft ? *doubleLeft : *intLeft ) <= 253 ( doubleRight ? 253 ( doubleRight ? *doubleRight : *intRight ); 254 else 254 else 255 return *intLeft <= *in 255 return *intLeft <= *intRight; 256 case More : 256 case More : 257 if ( isDoubleRetval ) 257 if ( isDoubleRetval ) 258 return ( doubleLeft ? 258 return ( doubleLeft ? *doubleLeft : *intLeft ) > 259 ( doubleRight ? 259 ( doubleRight ? *doubleRight : *intRight ); 260 else 260 else 261 return *intLeft > *int 261 return *intLeft > *intRight; 262 case MoreEq : 262 case MoreEq : 263 if ( isDoubleRetval ) 263 if ( isDoubleRetval ) 264 return ( doubleLeft ? 264 return ( doubleLeft ? *doubleLeft : *intLeft ) >= 265 ( doubleRight ? 265 ( doubleRight ? *doubleRight : *intRight ); 266 else 266 else 267 return *intLeft >= *in 267 return *intLeft >= *intRight; 268 case Eq : 268 case Eq : 269 if ( isDoubleRetval ) 269 if ( isDoubleRetval ) 270 return ( doubleLeft ? 270 return ( doubleLeft ? *doubleLeft : *intLeft ) == 271 ( doubleRight ? 271 ( doubleRight ? *doubleRight : *intRight ); 272 else 272 else 273 return *intLeft == *in 273 return *intLeft == *intRight; 274 case NotEq : 274 case NotEq : 275 if ( isDoubleRetval ) 275 if ( isDoubleRetval ) 276 return ( doubleLeft ? 276 return ( doubleLeft ? *doubleLeft : *intLeft ) != 277 ( doubleRight ? 277 ( doubleRight ? *doubleRight : *intRight ); 278 else 278 else 279 return *intLeft != *in 279 return *intLeft != *intRight; 280 case And : 280 case And : 281 if ( doubleLeft ) 281 if ( doubleLeft ) 282 { 282 { 283 if ( ! *doubleLeft ) 283 if ( ! *doubleLeft ) 284 return 0; 284 return 0; 285 } 285 } 286 else 286 else 287 { 287 { 288 if ( ! *intLeft ) 288 if ( ! *intLeft ) 289 return 0; 289 return 0; 290 } 290 } 291 right = GetScalarValue( as 291 right = GetScalarValue( ast->children[ 1 ] ); 292 intRight = boost::get< int 292 intRight = boost::get< int >( &right ); 293 if ( ! intRight ) 293 if ( ! intRight ) 294 { 294 { 295 doubleRight = boost::g 295 doubleRight = boost::get< double >( &right ); 296 if ( ! doubleRight ) 296 if ( ! doubleRight ) 297 throw CexmcExcepti 297 throw CexmcException( CexmcCFUnexpectedContext ); 298 } 298 } 299 if ( doubleRight ) 299 if ( doubleRight ) 300 { 300 { 301 if ( *doubleRight ) 301 if ( *doubleRight ) 302 return 1; 302 return 1; 303 } 303 } 304 else 304 else 305 { 305 { 306 if ( *intRight ) 306 if ( *intRight ) 307 return 1; 307 return 1; 308 } 308 } 309 return 0; 309 return 0; 310 case Or : 310 case Or : 311 if ( doubleLeft ) 311 if ( doubleLeft ) 312 { 312 { 313 if ( *doubleLeft ) 313 if ( *doubleLeft ) 314 return 1; 314 return 1; 315 } 315 } 316 else 316 else 317 { 317 { 318 if ( *intLeft ) 318 if ( *intLeft ) 319 return 1; 319 return 1; 320 } 320 } 321 right = GetScalarValue( as 321 right = GetScalarValue( ast->children[ 1 ] ); 322 intRight = boost::get< int 322 intRight = boost::get< int >( &right ); 323 if ( ! intRight ) 323 if ( ! intRight ) 324 { 324 { 325 doubleRight = boost::g 325 doubleRight = boost::get< double >( &right ); 326 if ( ! doubleRight ) 326 if ( ! doubleRight ) 327 throw CexmcExcepti 327 throw CexmcException( CexmcCFUnexpectedContext ); 328 } 328 } 329 if ( doubleRight ) 329 if ( doubleRight ) 330 { 330 { 331 if ( *doubleRight ) 331 if ( *doubleRight ) 332 return 1; 332 return 1; 333 } 333 } 334 else 334 else 335 { 335 { 336 if ( *intRight ) 336 if ( *intRight ) 337 return 1; 337 return 1; 338 } 338 } 339 return 0; 339 return 0; 340 default : 340 default : 341 return 0; 341 return 0; 342 } 342 } 343 } 343 } 344 else 344 else 345 { 345 { 346 return GetFunScalarValue( *ast 346 return GetFunScalarValue( *ast ); 347 } 347 } 348 } 348 } 349 else 349 else 350 { 350 { 351 const Leaf & leaf( boost::get 351 const Leaf & leaf( boost::get< Leaf >( node ) ); 352 const Constant * constant( boost: 352 const Constant * constant( boost::get< Constant >( &leaf ) ); 353 353 354 if ( constant ) 354 if ( constant ) 355 { 355 { 356 return *constant; 356 return *constant; 357 } 357 } 358 else 358 else 359 { 359 { 360 const Variable & variable( bo 360 const Variable & variable( boost::get< Variable >( leaf ) ); 361 return GetVarScalarValue( vari 361 return GetVarScalarValue( variable ); 362 } 362 } 363 } 363 } 364 364 365 return 0; 365 return 0; 366 } 366 } 367 367 368 368 369 BasicEval::ScalarValueType BasicEval::Get 369 BasicEval::ScalarValueType BasicEval::GetFunScalarValue( 370 370 const Subtree & ast ) const 371 { 371 { 372 bool evalResult( false ); 372 bool evalResult( false ); 373 ScalarValueType result( GetBasicFunSc 373 ScalarValueType result( GetBasicFunScalarValue( ast, evalResult ) ); 374 374 375 if ( evalResult ) 375 if ( evalResult ) 376 return result; 376 return result; 377 377 378 throw CexmcException( CexmcCFUnexpecte 378 throw CexmcException( CexmcCFUnexpectedFunction ); 379 379 380 return 0; 380 return 0; 381 } 381 } 382 382 383 383 384 BasicEval::ScalarValueType BasicEval::Get 384 BasicEval::ScalarValueType BasicEval::GetVarScalarValue( 385 385 const Variable & ) const 386 { 386 { 387 throw CexmcException( CexmcCFUnexpecte 387 throw CexmcException( CexmcCFUnexpectedVariable ); 388 388 389 return 0; 389 return 0; 390 } 390 } 391 391 392 392 393 BasicEval::ScalarValueType BasicEval::Get 393 BasicEval::ScalarValueType BasicEval::GetBasicFunScalarValue( 394 const Subt 394 const Subtree & ast, bool & result ) const 395 { 395 { 396 const Function & fun( boost::get< Fun 396 const Function & fun( boost::get< Function >( ast.type ) ); 397 397 398 result = true; 398 result = true; 399 399 400 ScalarValueType arg( GetScalarValue( 400 ScalarValueType arg( GetScalarValue( ast.children[ 0 ] ) ); 401 int * intArg( NULL ); 401 int * intArg( NULL ); 402 double * doubleArg( NULL ); 402 double * doubleArg( NULL ); 403 403 404 intArg = boost::get< int >( &arg ); 404 intArg = boost::get< int >( &arg ); 405 if ( ! intArg ) 405 if ( ! intArg ) 406 doubleArg = boost::get< double >( 406 doubleArg = boost::get< double >( &arg ); 407 407 408 if ( fun == "Sqr" ) 408 if ( fun == "Sqr" ) 409 { 409 { 410 if ( doubleArg ) 410 if ( doubleArg ) 411 return *doubleArg * *doubleArg 411 return *doubleArg * *doubleArg; 412 else 412 else 413 return *intArg * *intArg; 413 return *intArg * *intArg; 414 } 414 } 415 if ( fun == "Sqrt" ) 415 if ( fun == "Sqrt" ) 416 { 416 { 417 if ( doubleArg ) 417 if ( doubleArg ) 418 return std::sqrt( *doubleArg ) 418 return std::sqrt( *doubleArg ); 419 else 419 else 420 return std::sqrt( *intArg ); 420 return std::sqrt( *intArg ); 421 } 421 } 422 422 423 result = false; 423 result = false; 424 424 425 return 0; 425 return 0; 426 } 426 } 427 } 427 } 428 428 429 #endif 429 #endif 430 430 431 431