src/expression.h

Go to the documentation of this file.
00001 // $Id: expression.h 13 2007-08-16 15:50:09Z tb $
00004 #ifndef EXPRESSION_H
00005 #define EXPRESSION_H
00006 
00007 #include <map>
00008 #include <vector>
00009 #include <stdexcept>
00010 #include <cmath>
00011 
00014 class CalcNode
00015 {
00016 public:
00019     virtual ~CalcNode()
00020     {
00021     }
00022 
00025     virtual double      evaluate() const = 0;
00026 
00029     virtual void        print(std::ostream &os, unsigned int depth=0) const = 0;
00030 
00032     static inline std::string indent(unsigned int d)
00033     {
00034         return std::string(d * 2, ' ');
00035     }
00036 };
00037 
00039 class CNConstant : public CalcNode
00040 {
00042     double      value;
00043     
00044 public:
00046     explicit CNConstant(double _value)
00047         : CalcNode(), value(_value)
00048     {
00049     }
00050 
00051     virtual double evaluate() const
00052     {
00053         return value;
00054     }
00055 
00056     virtual void print(std::ostream &os, unsigned int depth) const
00057     {
00058         os << indent(depth) << value << std::endl;
00059     }
00060 };
00061 
00063 class CNNegate : public CalcNode
00064 {
00066     CalcNode*   node;
00067 
00068 public:
00069     explicit CNNegate(CalcNode* _node)
00070         : CalcNode(), node(_node)
00071     {
00072     }
00073 
00074     virtual ~CNNegate()
00075     {
00076         delete node;
00077     }
00078 
00079     virtual double evaluate() const
00080     {
00081         return - node->evaluate();
00082     }
00083 
00084     virtual void print(std::ostream &os, unsigned int depth) const
00085     {
00086         os << indent(depth) << "- negate" << std::endl;
00087         node->print(os, depth+1);
00088     }
00089 };
00090 
00092 class CNAdd : public CalcNode
00093 {
00095     CalcNode*   left;
00096 
00098     CalcNode*   right;
00099     
00100 public:
00101     explicit CNAdd(CalcNode* _left, CalcNode* _right)
00102         : CalcNode(), left(_left), right(_right)
00103     {
00104     }
00105 
00106     virtual ~CNAdd()
00107     {
00108         delete left;
00109         delete right;
00110     }
00111 
00112     virtual double evaluate() const
00113     {
00114         return left->evaluate() + right->evaluate();
00115     }
00116 
00117     virtual void print(std::ostream &os, unsigned int depth) const
00118     {
00119         os << indent(depth) << "+ add" << std::endl;
00120         left->print(os, depth+1);
00121         right->print(os, depth+1);
00122     }
00123 };
00124 
00126 class CNSubtract : public CalcNode
00127 {
00129     CalcNode*   left;
00130 
00132     CalcNode*   right;
00133     
00134 public:
00135     explicit CNSubtract(CalcNode* _left, CalcNode* _right)
00136         : CalcNode(), left(_left), right(_right)
00137     {
00138     }
00139 
00140     virtual ~CNSubtract()
00141     {
00142         delete left;
00143         delete right;
00144     }
00145 
00146     virtual double evaluate() const
00147     {
00148         return left->evaluate() - right->evaluate();
00149     }
00150 
00151     virtual void print(std::ostream &os, unsigned int depth) const
00152     {
00153         os << indent(depth) << "- subtract" << std::endl;
00154         left->print(os, depth+1);
00155         right->print(os, depth+1);
00156     }
00157 };
00158 
00160 class CNMultiply : public CalcNode
00161 {
00163     CalcNode*   left;
00164 
00166     CalcNode*   right;
00167     
00168 public:
00169     explicit CNMultiply(CalcNode* _left, CalcNode* _right)
00170         : CalcNode(), left(_left), right(_right)
00171     {
00172     }
00173 
00174     virtual ~CNMultiply()
00175     {
00176         delete left;
00177         delete right;
00178     }
00179 
00180     virtual double evaluate() const
00181     {
00182         return left->evaluate() * right->evaluate();
00183     }
00184 
00185     virtual void print(std::ostream &os, unsigned int depth) const
00186     {
00187         os << indent(depth) << "* multiply" << std::endl;
00188         left->print(os, depth+1);
00189         right->print(os, depth+1);
00190     }
00191 };
00192 
00194 class CNDivide : public CalcNode
00195 {
00197     CalcNode*   left;
00198 
00200     CalcNode*   right;
00201     
00202 public:
00203     explicit CNDivide(CalcNode* _left, CalcNode* _right)
00204         : CalcNode(), left(_left), right(_right)
00205     {
00206     }
00207 
00208     virtual ~CNDivide()
00209     {
00210         delete left;
00211         delete right;
00212     }
00213 
00214     virtual double evaluate() const
00215     {
00216         return left->evaluate() / right->evaluate();
00217     }
00218 
00219     virtual void print(std::ostream &os, unsigned int depth) const
00220     {
00221         os << indent(depth) << "/ divide" << std::endl;
00222         left->print(os, depth+1);
00223         right->print(os, depth+1);
00224     }
00225 };
00226 
00229 class CNModulo : public CalcNode
00230 {
00232     CalcNode*   left;
00233 
00235     CalcNode*   right;
00236     
00237 public:
00238     explicit CNModulo(CalcNode* _left, CalcNode* _right)
00239         : CalcNode(), left(_left), right(_right)
00240     {
00241     }
00242 
00243     virtual ~CNModulo()
00244     {
00245         delete left;
00246         delete right;
00247     }
00248 
00249     virtual double evaluate() const
00250     {
00251         return std::fmod(left->evaluate(), right->evaluate());
00252     }
00253 
00254     virtual void print(std::ostream &os, unsigned int depth) const
00255     {
00256         os << indent(depth) << "% modulo" << std::endl;
00257         left->print(os, depth+1);
00258         right->print(os, depth+1);
00259     }
00260 };
00261 
00263 class CNPower : public CalcNode
00264 {
00266     CalcNode*   left;
00267 
00269     CalcNode*   right;
00270     
00271 public:
00272     explicit CNPower(CalcNode* _left, CalcNode* _right)
00273         : CalcNode(), left(_left), right(_right)
00274     {
00275     }
00276 
00277     virtual ~CNPower()
00278     {
00279         delete left;
00280         delete right;
00281     }
00282 
00283     virtual double evaluate() const
00284     {
00285         return std::pow(left->evaluate(), right->evaluate());
00286     }
00287 
00288     virtual void print(std::ostream &os, unsigned int depth) const
00289     {
00290         os << indent(depth) << "^ power" << std::endl;
00291         left->print(os, depth+1);
00292         right->print(os, depth+1);
00293     }
00294 };
00295 
00299 class CalcContext
00300 {
00301 public:
00302 
00304     typedef std::map<std::string, double> variablemap_type;
00305 
00307     variablemap_type            variables;
00308 
00311     std::vector<CalcNode*>      expressions;
00312 
00314     ~CalcContext()
00315     {
00316         clearExpressions();
00317     }
00318 
00320     void        clearExpressions()
00321     {
00322         for(unsigned int i = 0; i < expressions.size(); ++i)
00323         {
00324             delete expressions[i];
00325         }
00326         expressions.clear();
00327     }
00328 
00330     bool        existsVariable(const std::string &varname) const
00331     {
00332         return variables.find(varname) != variables.end();
00333     }
00334     
00337     double      getVariable(const std::string &varname) const
00338     {
00339         variablemap_type::const_iterator vi = variables.find(varname);
00340         if (vi == variables.end())
00341             throw(std::runtime_error("Unknown variable."));
00342         else
00343             return vi->second;
00344     }
00345 };
00346 
00347 #endif // EXPRESSION_H

Generated on Mon Aug 20 13:34:21 2007 for Flex Bison C++ Example by  doxygen 1.5.2