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 ExprIntParser {
00023 private:
00024 map<icstring,double> variables;
00025
00026 class Context {
00027 public:
00028
00030 map<icstring,double> &variables;
00031 double val;
00032
00033 Context( map<icstring,double> &aVar )
00034 : variables( aVar ) , val( 0.0 )
00035 { }
00036
00037 Context( Context &ctx )
00038 : variables( ctx.variables ) , val( 0.0 )
00039 { }
00040
00041
00042 Context &operator=( Context &ctx )
00043 {
00044 val = ctx.val;
00045 return *this;
00046 }
00047
00048 Context &operator+=( Context &ctx )
00049 {
00050 val += ctx.val;
00051 return *this;
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 = (int)val | (int)ctx.val;
00071 return *this;
00072 }
00073 };
00074
00075 Interpret *itp;
00076 public:
00077
00078 ExprIntParser( void )
00079 : itp( 0 )
00080 {
00081 Init();
00082 }
00083
00084 ~ExprIntParser( void )
00085 {
00086 if( itp )
00087 delete itp;
00088 itp = 0;
00089 }
00090
00091 TreeNode *Eval( const string &aBuffer )
00092 {
00093 if( itp )
00094 delete itp;
00095 itp = 0;
00096
00097 ExprInt lex( aBuffer );
00098 itp = new Interpret( lex );
00099 itp->Run();
00100 return itp->back();
00101 }
00102
00103 int Apply( TreeNode *tn )
00104 {
00105 Context ctx( variables );
00106 WalkTree( tn , ctx );
00107 return (int)ctx.val;
00108 }
00109
00110 private:
00111
00112 void Init( void )
00113 {
00114 Cfg::Handler &h = Cfg::GetCfg();
00115 variables.insert( make_pair( icstring( "scrw" ) , h.GetCfgInt( "SetupScreen" , "screenw" ) ) );
00116 variables.insert( make_pair( icstring( "scrh" ) , h.GetCfgInt( "SetupScreen" , "screenh" ) ) );
00117 }
00118
00119 void WalkTree( TreeNode *tn , Context &ctx )
00120 {
00121 if( tn )
00122 {
00123 Context lctx( ctx );
00124 if( tn->child != 0 )
00125 WalkTree( tn->child , lctx );
00126
00127 Context rctx( ctx );
00128 if( tn->next != 0 )
00129 WalkTree( tn->next , rctx );
00130
00131 if( tn->symbolId == 9 )
00132 ctx.val = atof( tn->constant.c_str() );
00133 else if( tn->symbolId == 5 )
00134 {
00135 map<icstring,double>::iterator pos = ctx.variables.find( icstring( tn->constant.c_str() ) );
00136 if( pos != ctx.variables.end() )
00137 ctx.val = pos->second;
00138 }
00139 else
00140 {
00141 ctx = lctx;
00142
00143 switch( tn->constant.c_str()[0] )
00144 {
00145 case '+' : ctx += rctx; break;
00146 case '-' : ctx -= rctx; break;
00147 case '*' : ctx *= rctx; break;
00148 case '/' : ctx /= rctx; break;
00149 case '|' : ctx |= rctx; break;
00150 default:
00151 if( lctx.val != 0 )
00152 ctx = lctx;
00153 if( rctx.val != 0 )
00154 if( ctx.val == 0 )
00155 ctx = rctx;
00156 else
00157 printf( "ERROR\n" );
00158 break;
00159 }
00160 }
00161 }
00162 }
00163 };
00164
00165 }
00166
00167 #endif