]> Shamusworld >> Repos - architektonas/blob - fparser/fparser.hh
Adding fparser v4.3...
[architektonas] / fparser / fparser.hh
1 /***************************************************************************\
2 |* Function Parser for C++ v4.3                                            *|
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>
30 class FunctionParserBase
31 {
32 public:
33     enum ParseErrorType
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,
38         UNKNOWN_IDENTIFIER,
39         NO_FUNCTION_PARSED_YET,
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     const char* ErrorMsg() const;
54     inline ParseErrorType GetParseErrorType() const { return mParseErrorType; }
55
56     Value_t Eval(const Value_t* Vars);
57     inline int EvalError() const { return mEvalErrorType; }
58
59     bool AddConstant(const std::string& name, Value_t value);
60     bool AddUnit(const std::string& name, Value_t value);
61
62     typedef Value_t (*FunctionPtr)(const Value_t*);
63
64     bool AddFunction(const std::string& name,
65                      FunctionPtr, unsigned paramsAmount);
66     bool AddFunction(const std::string& name, FunctionParserBase&);
67
68     bool RemoveIdentifier(const std::string& name);
69
70     void Optimize();
71
72
73     int ParseAndDeduceVariables(const std::string& function,
74                                 int* amountOfVariablesFound = 0,
75                                 bool useDegrees = false);
76     int ParseAndDeduceVariables(const std::string& function,
77                                 std::string& resultVarString,
78                                 int* amountOfVariablesFound = 0,
79                                 bool useDegrees = false);
80     int ParseAndDeduceVariables(const std::string& function,
81                                 std::vector<std::string>& resultVars,
82                                 bool useDegrees = false);
83
84
85     FunctionParserBase();
86     ~FunctionParserBase();
87
88     // Copy constructor and assignment operator (implemented using the
89     // copy-on-write technique for efficiency):
90     FunctionParserBase(const FunctionParserBase&);
91     FunctionParserBase& operator=(const FunctionParserBase&);
92
93
94     void ForceDeepCopy();
95
96
97
98 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
99     // For debugging purposes only.
100     // Performs no sanity checks or anything. If the values are wrong, the
101     // library will crash. Do not use unless you know what you are doing.
102     void InjectRawByteCode(const unsigned* bytecode, unsigned bytecodeAmount,
103                            const Value_t* immed, unsigned immedAmount,
104                            unsigned stackSize);
105
106     void PrintByteCode(std::ostream& dest, bool showExpression = true) const;
107 #endif
108
109
110
111 //========================================================================
112 private:
113 //========================================================================
114
115     friend class FPoptimizer_CodeTree::CodeTree<Value_t>;
116
117 // Private data:
118 // ------------
119     char mDelimiterChar;
120     ParseErrorType mParseErrorType;
121     int mEvalErrorType;
122
123     struct Data;
124     Data* mData;
125
126     bool mUseDegreeConversion;
127     bool mHasByteCodeFlags;
128     unsigned mEvalRecursionLevel;
129     unsigned mStackPtr;
130     const char* mErrorLocation;
131
132
133 // Private methods:
134 // ---------------
135     void CopyOnWrite();
136     bool CheckRecursiveLinking(const FunctionParserBase*) const;
137     bool NameExists(const char*, unsigned);
138     bool ParseVariables(const std::string&);
139     int ParseFunction(const char*, bool);
140     const char* SetErrorType(ParseErrorType, const char*);
141
142     void AddFunctionOpcode(unsigned);
143     void AddImmedOpcode(Value_t v);
144     void incStackPtr();
145     void CompilePowi(long);
146     bool TryCompilePowi(Value_t);
147
148     const char* CompileIf(const char*);
149     const char* CompileFunctionParams(const char*, unsigned);
150     const char* CompileElement(const char*);
151     const char* CompilePossibleUnit(const char*);
152     const char* CompilePow(const char*);
153     const char* CompileUnaryMinus(const char*);
154     const char* CompileMult(const char*);
155     const char* CompileAddition(const char*);
156     const char* CompileComparison(const char*);
157     const char* CompileAnd(const char*);
158     const char* CompileExpression(const char*);
159     inline const char* CompileFunction(const char*, unsigned);
160     inline const char* CompileParenthesis(const char*);
161     inline const char* CompileLiteral(const char*);
162     template<bool SetFlag>
163     inline void PushOpcodeParam(unsigned);
164     template<bool SetFlag>
165     inline void PutOpcodeParamAt(unsigned, unsigned offset);
166     const char* Compile(const char*);
167
168 protected:
169     // Parsing utility functions
170     static std::pair<const char*, Value_t> ParseLiteral(const char*);
171     static unsigned ParseIdentifier(const char*);
172 };
173
174 class FunctionParser: public FunctionParserBase<double> {};
175 class FunctionParser_f: public FunctionParserBase<float> {};
176 class FunctionParser_ld: public FunctionParserBase<long double> {};
177 class FunctionParser_li: public FunctionParserBase<long> {};
178
179 #endif