Back to index

scribus-ng  1.3.4.dfsg+svn20071115
fparser.h
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 /***************************************************************************\
00008 |* Function parser v2.8 by Warp                                            *|
00009 |* ----------------------------                                            *|
00010 |* Parses and evaluates the given function with the given variable values. *|
00011 |* See fparser.txt for details.                                            *|
00012 |*                                                                         *|
00013 \***************************************************************************/
00014 
00015 #ifndef ONCE_FPARSER_H_
00016 #define ONCE_FPARSER_H_
00017 
00018 #include <string>
00019 #include <map>
00020 #include <vector>
00021 
00022 #ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT
00023 #include <iostream>
00024 #endif
00025 
00026 class FunctionParser
00027 {
00028 public:
00029     enum ParseErrorType
00030     {
00031         SYNTAX_ERROR=0, MISM_PARENTH, MISSING_PARENTH, EMPTY_PARENTH,
00032         EXPECT_OPERATOR, OUT_OF_MEMORY, UNEXPECTED_ERROR, INVALID_VARS,
00033         ILL_PARAMS_AMOUNT, PREMATURE_EOS, EXPECT_PARENTH_FUNC,
00034         FP_NO_ERROR
00035     };
00036 
00037 
00038     int Parse(const std::string& Function, const std::string& Vars,
00039               bool useDegrees = false);
00040     const char* ErrorMsg() const;
00041     inline ParseErrorType GetParseErrorType() const { return parseErrorType; }
00042 
00043     double Eval(const double* Vars);
00044     inline int EvalError() const { return evalErrorType; }
00045 
00046     bool AddConstant(const std::string& name, double value);
00047 
00048     typedef double (*FunctionPtr)(const double*);
00049 
00050     bool AddFunction(const std::string& name,
00051                      FunctionPtr, unsigned paramsAmount);
00052     bool AddFunction(const std::string& name, FunctionParser&);
00053 
00054     void Optimize();
00055 
00056 
00057     FunctionParser();
00058     ~FunctionParser();
00059 
00060     // Copy constructor and assignment operator (implemented using the
00061     // copy-on-write technique for efficiency):
00062     FunctionParser(const FunctionParser&);
00063     FunctionParser& operator=(const FunctionParser&);
00064 
00065 
00066 #ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT
00067     // For debugging purposes only:
00068     void PrintByteCode(std::ostream& dest) const;
00069 #endif
00070 
00071 
00072 
00073 //========================================================================
00074 private:
00075 //========================================================================
00076 
00077 // Private data:
00078 // ------------
00079     ParseErrorType parseErrorType;
00080     int evalErrorType;
00081 
00082     struct Data
00083     {
00084         unsigned referenceCounter;
00085 
00086         int varAmount;
00087         bool useDegreeConversion;
00088 
00089         typedef std::map<std::string, unsigned> VarMap_t;
00090         VarMap_t Variables;
00091 
00092         typedef std::map<std::string, double> ConstMap_t;
00093         ConstMap_t Constants;
00094 
00095         VarMap_t FuncPtrNames;
00096         struct FuncPtrData
00097         {
00098             FunctionPtr ptr; unsigned params;
00099             FuncPtrData(FunctionPtr p, unsigned par): ptr(p), params(par) {}
00100         };
00101         std::vector<FuncPtrData> FuncPtrs;
00102 
00103         VarMap_t FuncParserNames;
00104         std::vector<FunctionParser*> FuncParsers;
00105 
00106         unsigned* ByteCode;
00107         unsigned ByteCodeSize;
00108         double* Immed;
00109         unsigned ImmedSize;
00110         double* Stack;
00111         unsigned StackSize;
00112 
00113         Data();
00114         ~Data();
00115         Data(const Data&);
00116 
00117         Data& operator=(const Data&); // not implemented on purpose
00118     };
00119 
00120     Data* data;
00121     unsigned evalRecursionLevel;
00122 
00123     // Temp data needed in Compile():
00124     unsigned StackPtr;
00125     std::vector<unsigned>* tempByteCode;
00126     std::vector<double>* tempImmed;
00127 
00128 
00129 // Private methods:
00130 // ---------------
00131     void copyOnWrite();
00132 
00133 
00134     bool checkRecursiveLinking(const FunctionParser*) const;
00135 
00136     bool isValidName(const std::string&) const;
00137     Data::VarMap_t::const_iterator FindVariable(const char*,
00138                                                 const Data::VarMap_t&) const;
00139     Data::ConstMap_t::const_iterator FindConstant(const char*) const;
00140     int CheckSyntax(const char*);
00141     bool Compile(const char*);
00142     bool IsVariable(int);
00143     void AddCompiledByte(unsigned);
00144     void AddImmediate(double);
00145     void AddFunctionOpcode(unsigned);
00146     inline void incStackPtr();
00147     int CompileIf(const char*, int);
00148     int CompileFunctionParams(const char*, int, unsigned);
00149     int CompileElement(const char*, int);
00150     int CompilePow(const char*, int);
00151     int CompileUnaryMinus(const char*, int);
00152     int CompileMult(const char*, int);
00153     int CompileAddition(const char*, int);
00154     int CompileComparison(const char*, int);
00155     int CompileAnd(const char*, int);
00156     int CompileOr(const char*, int);
00157     int CompileExpression(const char*, int, bool=false);
00158 
00159 
00160     void MakeTree(void*) const;
00161 };
00162 
00163 #endif