Planeshift

fparser.h

Go to the documentation of this file.
00001 /***************************************************************************\
00002 |* Function Parser for C++ v4.5.2                                          *|
00003 |*-------------------------------------------------------------------------*|
00004 |* Copyright: Juha Nieminen, Joel Yliluoma                                 *|
00005 |*                                                                         *|
00006 |* This library is distributed under the terms of the                      *|
00007 |* GNU Lesser General Public License version 3.                            *|
00008 |* (See lgpl.txt and gpl.txt for the license text.)                        *|
00009 \***************************************************************************/
00010 
00011 #ifndef ONCE_FPARSER_H_
00012 #define ONCE_FPARSER_H_
00013 
00014 #include <string>
00015 #include <vector>
00016 
00017 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
00018 #include <iostream>
00019 #endif
00020 
00021 #ifdef _MSC_VER
00022 // Visual Studio's warning about missing definitions for the explicit
00023 // FunctionParserBase instantiations is irrelevant here.
00024 #pragma warning(disable : 4661)
00025 #endif
00026 
00027 namespace FPoptimizer_CodeTree { template<typename Value_t> class CodeTree; }
00028 
00029 template<typename Value_t>
00030 class FunctionParserBase
00031 {
00032  public:
00033     enum ParseErrorType
00034     {
00035         SYNTAX_ERROR=0, MISM_PARENTH, MISSING_PARENTH, EMPTY_PARENTH,
00036         EXPECT_OPERATOR, OUT_OF_MEMORY, UNEXPECTED_ERROR, INVALID_VARS,
00037         ILL_PARAMS_AMOUNT, PREMATURE_EOS, EXPECT_PARENTH_FUNC,
00038         UNKNOWN_IDENTIFIER,
00039         NO_FUNCTION_PARSED_YET,
00040         FP_NO_ERROR
00041     };
00042 
00043     typedef Value_t value_type;
00044 
00045 
00046     int Parse(const char* Function, const std::string& Vars,
00047               bool useDegrees = false);
00048     int Parse(const std::string& Function, const std::string& Vars,
00049               bool useDegrees = false);
00050 
00051     void setDelimiterChar(char);
00052 
00053     static Value_t epsilon();
00054     static void setEpsilon(Value_t);
00055 
00056     const char* ErrorMsg() const;
00057     ParseErrorType GetParseErrorType() const;
00058 
00059     Value_t Eval(const Value_t* Vars);
00060     int EvalError() const;
00061 
00062     bool AddConstant(const std::string& name, Value_t value);
00063     bool AddUnit(const std::string& name, Value_t value);
00064 
00065     typedef Value_t (*FunctionPtr)(const Value_t*);
00066 
00067     bool AddFunction(const std::string& name,
00068                      FunctionPtr, unsigned paramsAmount);
00069     bool AddFunction(const std::string& name, FunctionParserBase&);
00070 
00071     class FunctionWrapper;
00072 
00073     template<typename DerivedWrapper>
00074     bool AddFunctionWrapper(const std::string& name, const DerivedWrapper&,
00075                             unsigned paramsAmount);
00076 
00077     FunctionWrapper* GetFunctionWrapper(const std::string& name);
00078 
00079     bool RemoveIdentifier(const std::string& name);
00080 
00081     void Optimize();
00082 
00083 
00084     int ParseAndDeduceVariables(const std::string& function,
00085                                 int* amountOfVariablesFound = 0,
00086                                 bool useDegrees = false);
00087     int ParseAndDeduceVariables(const std::string& function,
00088                                 std::string& resultVarString,
00089                                 int* amountOfVariablesFound = 0,
00090                                 bool useDegrees = false);
00091     int ParseAndDeduceVariables(const std::string& function,
00092                                 std::vector<std::string>& resultVars,
00093                                 bool useDegrees = false);
00094 
00095 
00096     FunctionParserBase();
00097     ~FunctionParserBase();
00098 
00099     // Copy constructor and assignment operator (implemented using the
00100     // copy-on-write technique for efficiency):
00101     FunctionParserBase(const FunctionParserBase&);
00102     FunctionParserBase& operator=(const FunctionParserBase&);
00103 
00104 
00105     void ForceDeepCopy();
00106 
00107 
00108 
00109 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
00110     // For debugging purposes only.
00111     // Performs no sanity checks or anything. If the values are wrong, the
00112     // library will crash. Do not use unless you know what you are doing.
00113     void InjectRawByteCode(const unsigned* bytecode, unsigned bytecodeAmount,
00114                            const Value_t* immed, unsigned immedAmount,
00115                            unsigned stackSize);
00116 
00117     void PrintByteCode(std::ostream& dest, bool showExpression = true) const;
00118 #endif
00119 
00120 
00121 
00122 //========================================================================
00123  protected:
00124 //========================================================================
00125     // A derived class can implement its own evaluation logic by using
00126     // the parser data (found in fptypes.hh).
00127     struct Data;
00128     Data* getParserData();
00129 
00130 
00131 //========================================================================
00132  private:
00133 //========================================================================
00134 
00135     friend class FPoptimizer_CodeTree::CodeTree<Value_t>;
00136 
00137 // Private data:
00138 // ------------
00139     Data* mData;
00140     unsigned mStackPtr;
00141 
00142 
00143 // Private methods:
00144 // ---------------
00145     void CopyOnWrite();
00146     bool CheckRecursiveLinking(const FunctionParserBase*) const;
00147     bool NameExists(const char*, unsigned);
00148     bool ParseVariables(const std::string&);
00149     int ParseFunction(const char*, bool);
00150     const char* SetErrorType(ParseErrorType, const char*);
00151 
00152     void AddFunctionOpcode(unsigned);
00153     void AddImmedOpcode(Value_t v);
00154     void incStackPtr();
00155     void CompilePowi(long);
00156     bool TryCompilePowi(Value_t);
00157 
00158     const char* CompileIf(const char*);
00159     const char* CompileFunctionParams(const char*, unsigned);
00160     const char* CompileElement(const char*);
00161     const char* CompilePossibleUnit(const char*);
00162     const char* CompilePow(const char*);
00163     const char* CompileUnaryMinus(const char*);
00164     const char* CompileMult(const char*);
00165     const char* CompileAddition(const char*);
00166     const char* CompileComparison(const char*);
00167     const char* CompileAnd(const char*);
00168     const char* CompileExpression(const char*);
00169     inline const char* CompileFunction(const char*, unsigned);
00170     inline const char* CompileParenthesis(const char*);
00171     inline const char* CompileLiteral(const char*);
00172     template<bool SetFlag>
00173     inline void PushOpcodeParam(unsigned);
00174     template<bool SetFlag>
00175     inline void PutOpcodeParamAt(unsigned, unsigned offset);
00176     const char* Compile(const char*);
00177 
00178     bool addFunctionWrapperPtr(const std::string&, FunctionWrapper*, unsigned);
00179     static void incFuncWrapperRefCount(FunctionWrapper*);
00180     static unsigned decFuncWrapperRefCount(FunctionWrapper*);
00181 
00182 protected:
00183     // Parsing utility functions
00184     static std::pair<const char*, Value_t> ParseLiteral(const char*);
00185     static unsigned ParseIdentifier(const char*);
00186 };
00187 
00188 class FunctionParser: public FunctionParserBase<double> {};
00189 class FunctionParser_f: public FunctionParserBase<float> {};
00190 class FunctionParser_ld: public FunctionParserBase<long double> {};
00191 class FunctionParser_li: public FunctionParserBase<long> {};
00192 
00193 #include <complex>
00194 class FunctionParser_cd: public FunctionParserBase<std::complex<double> > {};
00195 class FunctionParser_cf: public FunctionParserBase<std::complex<float> > {};
00196 class FunctionParser_cld: public FunctionParserBase<std::complex<long double> > {};
00197 
00198 
00199 
00200 template<typename Value_t>
00201 class FunctionParserBase<Value_t>::FunctionWrapper
00202 {
00203     unsigned mReferenceCount;
00204     friend class FunctionParserBase<Value_t>;
00205 
00206  public:
00207     FunctionWrapper(): mReferenceCount(1) {}
00208     FunctionWrapper(const FunctionWrapper&): mReferenceCount(1) {}
00209     virtual ~FunctionWrapper() {}
00210     FunctionWrapper& operator=(const FunctionWrapper&) { return *this; }
00211 
00212     virtual Value_t callFunction(const Value_t*) = 0;
00213 };
00214 
00215 template<typename Value_t>
00216 template<typename DerivedWrapper>
00217 bool FunctionParserBase<Value_t>::AddFunctionWrapper
00218 (const std::string& name, const DerivedWrapper& wrapper, unsigned paramsAmount)
00219 {
00220     return addFunctionWrapperPtr
00221         (name, new DerivedWrapper(wrapper), paramsAmount);
00222 }
00223 #endif