Planeshift
fparser.h
Go to the documentation of this file.
1 /***************************************************************************\
2 |* Function Parser for C++ v4.5.2 *|
3 |*-------------------------------------------------------------------------*|
4 |* Copyright: Juha Nieminen, Joel Yliluoma *|
5 |* *|
6 |* This library is distributed under the terms of the *|
7 |* GNU Lesser General Public License version 3. *|
8 |* (See lgpl.txt and gpl.txt for the license text.) *|
9 \***************************************************************************/
10 
11 #ifndef ONCE_FPARSER_H_
12 #define ONCE_FPARSER_H_
13 
14 #include <string>
15 #include <vector>
16 
17 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
18 #include <iostream>
19 #endif
20 
21 #ifdef _MSC_VER
22 // Visual Studio's warning about missing definitions for the explicit
23 // FunctionParserBase instantiations is irrelevant here.
24 #pragma warning(disable : 4661)
25 #endif
26 
27 namespace FPoptimizer_CodeTree { template<typename Value_t> class CodeTree; }
28 
29 template<typename Value_t>
31 {
32  public:
34  {
35  SYNTAX_ERROR=0, MISM_PARENTH, MISSING_PARENTH, EMPTY_PARENTH,
36  EXPECT_OPERATOR, OUT_OF_MEMORY, UNEXPECTED_ERROR, INVALID_VARS,
37  ILL_PARAMS_AMOUNT, PREMATURE_EOS, EXPECT_PARENTH_FUNC,
40  FP_NO_ERROR
41  };
42 
43  typedef Value_t value_type;
44 
45 
46  int Parse(const char* Function, const std::string& Vars,
47  bool useDegrees = false);
48  int Parse(const std::string& Function, const std::string& Vars,
49  bool useDegrees = false);
50 
51  void setDelimiterChar(char);
52 
53  static Value_t epsilon();
54  static void setEpsilon(Value_t);
55 
56  const char* ErrorMsg() const;
57  ParseErrorType GetParseErrorType() const;
58 
59  Value_t Eval(const Value_t* Vars);
60  int EvalError() const;
61 
62  bool AddConstant(const std::string& name, Value_t value);
63  bool AddUnit(const std::string& name, Value_t value);
64 
65  typedef Value_t (*FunctionPtr)(const Value_t*);
66 
67  bool AddFunction(const std::string& name,
68  FunctionPtr, unsigned paramsAmount);
69  bool AddFunction(const std::string& name, FunctionParserBase&);
70 
71  class FunctionWrapper;
72 
73  template<typename DerivedWrapper>
74  bool AddFunctionWrapper(const std::string& name, const DerivedWrapper&,
75  unsigned paramsAmount);
76 
77  FunctionWrapper* GetFunctionWrapper(const std::string& name);
78 
79  bool RemoveIdentifier(const std::string& name);
80 
81  void Optimize();
82 
83 
84  int ParseAndDeduceVariables(const std::string& function,
85  int* amountOfVariablesFound = 0,
86  bool useDegrees = false);
87  int ParseAndDeduceVariables(const std::string& function,
88  std::string& resultVarString,
89  int* amountOfVariablesFound = 0,
90  bool useDegrees = false);
91  int ParseAndDeduceVariables(const std::string& function,
92  std::vector<std::string>& resultVars,
93  bool useDegrees = false);
94 
95 
98 
99  // Copy constructor and assignment operator (implemented using the
100  // copy-on-write technique for efficiency):
102  FunctionParserBase& operator=(const FunctionParserBase&);
103 
104 
105  void ForceDeepCopy();
106 
107 
108 
109 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
110  // For debugging purposes only.
111  // Performs no sanity checks or anything. If the values are wrong, the
112  // library will crash. Do not use unless you know what you are doing.
113  void InjectRawByteCode(const unsigned* bytecode, unsigned bytecodeAmount,
114  const Value_t* immed, unsigned immedAmount,
115  unsigned stackSize);
116 
117  void PrintByteCode(std::ostream& dest, bool showExpression = true) const;
118 #endif
119 
120 
121 
122 //========================================================================
123  protected:
124 //========================================================================
125  // A derived class can implement its own evaluation logic by using
126  // the parser data (found in fptypes.hh).
127  struct Data;
128  Data* getParserData();
129 
130 
131 //========================================================================
132  private:
133 //========================================================================
134 
135  friend class FPoptimizer_CodeTree::CodeTree<Value_t>;
136 
137 // Private data:
138 // ------------
139  Data* mData;
140  unsigned mStackPtr;
141 
142 
143 // Private methods:
144 // ---------------
145  void CopyOnWrite();
146  bool CheckRecursiveLinking(const FunctionParserBase*) const;
147  bool NameExists(const char*, unsigned);
148  bool ParseVariables(const std::string&);
149  int ParseFunction(const char*, bool);
150  const char* SetErrorType(ParseErrorType, const char*);
151 
152  void AddFunctionOpcode(unsigned);
153  void AddImmedOpcode(Value_t v);
154  void incStackPtr();
155  void CompilePowi(long);
156  bool TryCompilePowi(Value_t);
157 
158  const char* CompileIf(const char*);
159  const char* CompileFunctionParams(const char*, unsigned);
160  const char* CompileElement(const char*);
161  const char* CompilePossibleUnit(const char*);
162  const char* CompilePow(const char*);
163  const char* CompileUnaryMinus(const char*);
164  const char* CompileMult(const char*);
165  const char* CompileAddition(const char*);
166  const char* CompileComparison(const char*);
167  const char* CompileAnd(const char*);
168  const char* CompileExpression(const char*);
169  inline const char* CompileFunction(const char*, unsigned);
170  inline const char* CompileParenthesis(const char*);
171  inline const char* CompileLiteral(const char*);
172  template<bool SetFlag>
173  inline void PushOpcodeParam(unsigned);
174  template<bool SetFlag>
175  inline void PutOpcodeParamAt(unsigned, unsigned offset);
176  const char* Compile(const char*);
177 
178  bool addFunctionWrapperPtr(const std::string&, FunctionWrapper*, unsigned);
179  static void incFuncWrapperRefCount(FunctionWrapper*);
180  static unsigned decFuncWrapperRefCount(FunctionWrapper*);
181 
182 protected:
183  // Parsing utility functions
184  static std::pair<const char*, Value_t> ParseLiteral(const char*);
185  static unsigned ParseIdentifier(const char*);
186 };
187 
188 class FunctionParser: public FunctionParserBase<double> {};
189 class FunctionParser_f: public FunctionParserBase<float> {};
190 class FunctionParser_ld: public FunctionParserBase<long double> {};
191 class FunctionParser_li: public FunctionParserBase<long> {};
192 
193 #include <complex>
194 class FunctionParser_cd: public FunctionParserBase<std::complex<double> > {};
195 class FunctionParser_cf: public FunctionParserBase<std::complex<float> > {};
196 class FunctionParser_cld: public FunctionParserBase<std::complex<long double> > {};
197 
198 
199 
200 template<typename Value_t>
202 {
203  unsigned mReferenceCount;
204  friend class FunctionParserBase<Value_t>;
205 
206  public:
207  FunctionWrapper(): mReferenceCount(1) {}
208  FunctionWrapper(const FunctionWrapper&): mReferenceCount(1) {}
209  virtual ~FunctionWrapper() {}
210  FunctionWrapper& operator=(const FunctionWrapper&) { return *this; }
211 
212  virtual Value_t callFunction(const Value_t*) = 0;
213 };
214 
215 template<typename Value_t>
216 template<typename DerivedWrapper>
218 (const std::string& name, const DerivedWrapper& wrapper, unsigned paramsAmount)
219 {
220  return addFunctionWrapperPtr
221  (name, new DerivedWrapper(wrapper), paramsAmount);
222 }
223 #endif
FunctionWrapper & operator=(const FunctionWrapper &)
Definition: fparser.h:210
FunctionWrapper(const FunctionWrapper &)
Definition: fparser.h:208
Value_t value_type
Definition: fparser.h:43
bool AddFunctionWrapper(const std::string &name, const DerivedWrapper &, unsigned paramsAmount)
Definition: fparser.h:218