Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 09:21:51

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /*
0027  * =============================================================================
0028  *
0029  *       Filename:  CexmcAST.cc
0030  *
0031  *    Description:  abstract syntax tree for custom filter scripting language
0032  *
0033  *        Version:  1.0
0034  *        Created:  17.07.2010 14:45:14
0035  *       Revision:  none
0036  *       Compiler:  gcc
0037  *
0038  *         Author:  Alexey Radkov (), 
0039  *        Company:  PNPI
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