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