Planeshift
|
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