00001 #if !defined( __EXPRINT_H__ )
00002 #define __EXPRINT_H__
00003
00004 namespace Ars
00005 {
00006 class ExprInt : public Lexer {
00007
00008 static const char sr[10][10];
00009
00010
00011 public:
00012
00013 ExprInt( const string &aBuffer );
00014
00015 virtual const char atSr( const int ati , const int atj ) { return sr[ati][atj]; }
00016 virtual const int EofId( void ) const;
00017 virtual const int IdentifierId( void ) const;
00018 virtual const int NumberId( void ) const;
00019
00020 };
00021
00022 class ExprParser {
00023 private:
00024
00025 class Context {
00026 public:
00027
00029 map<icstring,double> &variables;
00030 double val;
00031
00032 Context( map<string,double> &aVar )
00033 : variables( aVar ) , val( 0.0 )
00034 { Init(); }
00035
00036 Context( Context &ctx )
00037 : variables( ctx.variables ) , val( 0.0 )
00038 { Init(); }
00039
00040 void Init( void )
00041 {
00042 Cfg::Handler &h = Cfg::GetCfg();
00043 variables.insert( make_pair( icstring( "scrw" ) , h.GetCfgInt( "SetupScreen" , "screenw" ) ) );
00044 variables.insert( make_pair( icstring( "scrh" ) , h.GetCfgInt( "SetupScreen" , "screenh" ) ) );
00045 }
00046
00047 Context &operator=( Context &ctx )
00048 {
00049 val = ctx.val;
00050 return *this;
00051 }
00052
00053 Context &operator+=( Context &ctx )
00054 {
00055 val += ctx.val;
00056 return *this;
00057 }
00058 Context &operator-=( Context &ctx )
00059 {
00060 val -= ctx.val;
00061 return *this;
00062 }
00063 Context &operator*=( Context &ctx )
00064 {
00065 val *= ctx.val;
00066 return *this;
00067 }
00068 Context &operator/=( Context &ctx )
00069 {
00070 val /= ctx.val;
00071 return *this;
00072 }
00073 Context &operator|=( Context &ctx )
00074 {
00075 val = (int)val | (int)ctx.val;
00076 return *this;
00077 }
00078 };
00079
00080
00081 public:
00082
00083 ExprParser( void )
00084 {
00085 }
00086
00087 TreeNode *Eval( const string &aBuffer )
00088 {
00089 Expr lex( aBuffer );
00090 Interpret itp( lex );
00091 itp.Run();
00092 return itp.back();
00093 }
00094
00095 SumRandom *Apply( TreeNode *tn )
00096 {
00097 Context ctx( variables );
00098 WalkTree( tn , ctx );
00099 return new SumRandom( *ctx.rdm );
00100 }
00101
00102 private:
00103
00104 void WalkTree( TreeNode *tn , Context &ctx )
00105 {
00106 if( tn )
00107 {
00108 Context lctx( ctx );
00109 if( tn->child != 0 )
00110 WalkTree( tn->child , lctx );
00111
00112 Context rctx( ctx );
00113 if( tn->next != 0 )
00114 WalkTree( tn->next , rctx );
00115
00116 if( tn->symbolId == 9 )
00117 ctx.val = atof( tn->constant.c_str() );
00118 else if( tn->symbolId == 5 )
00119 {
00120 map<string,double>::iterator pos = ctx.variables.find( tn->constant );
00121 if( pos != ctx.variables.end() )
00122 ctx.val = pos->second;
00123 }
00124 else
00125 {
00126 ctx = lctx;
00127
00128 switch( tn->constant.c_str()[0] )
00129 {
00130 case '+' : ctx += rctx; break;
00131 case '-' : ctx -= rctx; break;
00132 case '*' : ctx *= rctx; break;
00133 case '/' : ctx /= rctx; break;
00134 case '|' : ctx |= rctx; break;
00135 default:
00136 if( lctx.val != 0 )
00137 ctx = lctx;
00138 if( rctx.val != 0 )
00139 if( ctx.val == 0 )
00140 ctx = rctx;
00141 else
00142 printf( "ERROR\n" );
00143 break;
00144 }
00145 }
00146 }
00147 }
00148 };
00149
00150 }
00151
00152 #endif