/src/muparser/include/muParserToken.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | |
3 | | _____ __ _____________ _______ ______ ___________ |
4 | | / \| | \____ \__ \\_ __ \/ ___// __ \_ __ \ |
5 | | | Y Y \ | / |_> > __ \| | \/\___ \\ ___/| | \/ |
6 | | |__|_| /____/| __(____ /__| /____ >\___ >__| |
7 | | \/ |__| \/ \/ \/ |
8 | | Copyright (C) 2004 - 2022 Ingo Berg |
9 | | |
10 | | Redistribution and use in source and binary forms, with or without modification, are permitted |
11 | | provided that the following conditions are met: |
12 | | |
13 | | * Redistributions of source code must retain the above copyright notice, this list of |
14 | | conditions and the following disclaimer. |
15 | | * Redistributions in binary form must reproduce the above copyright notice, this list of |
16 | | conditions and the following disclaimer in the documentation and/or other materials provided |
17 | | with the distribution. |
18 | | |
19 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR |
20 | | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
21 | | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
22 | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
23 | | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
24 | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
25 | | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
26 | | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | | */ |
28 | | |
29 | | #ifndef MU_PARSER_TOKEN_H |
30 | | #define MU_PARSER_TOKEN_H |
31 | | |
32 | | #include <string> |
33 | | #include <stack> |
34 | | #include <vector> |
35 | | #include <memory> |
36 | | #include <utility> |
37 | | #include <type_traits> |
38 | | #include <cstddef> |
39 | | |
40 | | #if defined(_MSC_VER) |
41 | | #pragma warning(push) |
42 | | #pragma warning(disable : 26812) |
43 | | #endif |
44 | | |
45 | | #include "muParserError.h" |
46 | | #include "muParserCallback.h" |
47 | | |
48 | | /** \file |
49 | | \brief This file contains the parser token definition. |
50 | | */ |
51 | | |
52 | | namespace mu |
53 | | { |
54 | | template <std::size_t NbParams> struct TplCallType; |
55 | | template <> struct TplCallType<0> { using fun_type = fun_type0; using fun_userdata_type = fun_userdata_type0; using bulkfun_type = bulkfun_type0; using bulkfun_userdata_type = bulkfun_userdata_type0; }; |
56 | | template <> struct TplCallType<1> { using fun_type = fun_type1; using fun_userdata_type = fun_userdata_type1; using bulkfun_type = bulkfun_type1; using bulkfun_userdata_type = bulkfun_userdata_type1; using strfun_type = strfun_type1; using strfun_userdata_type = strfun_userdata_type1; }; |
57 | | template <> struct TplCallType<2> { using fun_type = fun_type2; using fun_userdata_type = fun_userdata_type2; using bulkfun_type = bulkfun_type2; using bulkfun_userdata_type = bulkfun_userdata_type2; using strfun_type = strfun_type2; using strfun_userdata_type = strfun_userdata_type2; }; |
58 | | template <> struct TplCallType<3> { using fun_type = fun_type3; using fun_userdata_type = fun_userdata_type3; using bulkfun_type = bulkfun_type3; using bulkfun_userdata_type = bulkfun_userdata_type3; using strfun_type = strfun_type3; using strfun_userdata_type = strfun_userdata_type3; }; |
59 | | template <> struct TplCallType<4> { using fun_type = fun_type4; using fun_userdata_type = fun_userdata_type4; using bulkfun_type = bulkfun_type4; using bulkfun_userdata_type = bulkfun_userdata_type4; using strfun_type = strfun_type4; using strfun_userdata_type = strfun_userdata_type4; }; |
60 | | template <> struct TplCallType<5> { using fun_type = fun_type5; using fun_userdata_type = fun_userdata_type5; using bulkfun_type = bulkfun_type5; using bulkfun_userdata_type = bulkfun_userdata_type5; using strfun_type = strfun_type5; using strfun_userdata_type = strfun_userdata_type5; }; |
61 | | template <> struct TplCallType<6> { using fun_type = fun_type6; using fun_userdata_type = fun_userdata_type6; using bulkfun_type = bulkfun_type6; using bulkfun_userdata_type = bulkfun_userdata_type6; using strfun_type = strfun_type6; using strfun_userdata_type = strfun_userdata_type6; }; |
62 | | template <> struct TplCallType<7> { using fun_type = fun_type7; using fun_userdata_type = fun_userdata_type7; using bulkfun_type = bulkfun_type7; using bulkfun_userdata_type = bulkfun_userdata_type7; }; |
63 | | template <> struct TplCallType<8> { using fun_type = fun_type8; using fun_userdata_type = fun_userdata_type8; using bulkfun_type = bulkfun_type8; using bulkfun_userdata_type = bulkfun_userdata_type8; }; |
64 | | template <> struct TplCallType<9> { using fun_type = fun_type9; using fun_userdata_type = fun_userdata_type9; using bulkfun_type = bulkfun_type9; using bulkfun_userdata_type = bulkfun_userdata_type9; }; |
65 | | template <> struct TplCallType<10> { using fun_type = fun_type10; using fun_userdata_type = fun_userdata_type10; using bulkfun_type = bulkfun_type10; using bulkfun_userdata_type = bulkfun_userdata_type10; }; |
66 | | |
67 | | struct generic_callable_type |
68 | | { |
69 | | // Note: we keep generic_callable_type a pod for the purpose of layout |
70 | | |
71 | | erased_fun_type _pRawFun; |
72 | | void* _pUserData; |
73 | | |
74 | | template <std::size_t NbParams, typename... Args> |
75 | | value_type call_fun(Args&&... args) const |
76 | 11.9k | { |
77 | 11.9k | static_assert(NbParams == sizeof...(Args), "mismatch between NbParams and Args"); |
78 | 11.9k | if (_pUserData == nullptr) |
79 | 11.9k | { |
80 | 11.9k | auto fun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_type>(_pRawFun); |
81 | 11.9k | return (*fun_typed_ptr)(std::forward<Args>(args)...); |
82 | 11.9k | } |
83 | 0 | else |
84 | 0 | { |
85 | 0 | auto fun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_userdata_type>(_pRawFun); |
86 | 0 | return (*fun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...); |
87 | 0 | } |
88 | 11.9k | } double mu::generic_callable_type::call_fun<0ul>() const Line | Count | Source | 76 | 616 | { | 77 | 616 | static_assert(NbParams == sizeof...(Args), "mismatch between NbParams and Args"); | 78 | 616 | if (_pUserData == nullptr) | 79 | 616 | { | 80 | 616 | auto fun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_type>(_pRawFun); | 81 | 616 | return (*fun_typed_ptr)(std::forward<Args>(args)...); | 82 | 616 | } | 83 | 0 | else | 84 | 0 | { | 85 | 0 | auto fun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_userdata_type>(_pRawFun); | 86 | 0 | return (*fun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...); | 87 | 0 | } | 88 | 616 | } |
double mu::generic_callable_type::call_fun<1ul, double&>(double&) const Line | Count | Source | 76 | 10.9k | { | 77 | 10.9k | static_assert(NbParams == sizeof...(Args), "mismatch between NbParams and Args"); | 78 | 10.9k | if (_pUserData == nullptr) | 79 | 10.9k | { | 80 | 10.9k | auto fun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_type>(_pRawFun); | 81 | 10.9k | return (*fun_typed_ptr)(std::forward<Args>(args)...); | 82 | 10.9k | } | 83 | 0 | else | 84 | 0 | { | 85 | 0 | auto fun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_userdata_type>(_pRawFun); | 86 | 0 | return (*fun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...); | 87 | 0 | } | 88 | 10.9k | } |
double mu::generic_callable_type::call_fun<2ul, double&, double&>(double&, double&) const Line | Count | Source | 76 | 395 | { | 77 | 395 | static_assert(NbParams == sizeof...(Args), "mismatch between NbParams and Args"); | 78 | 395 | if (_pUserData == nullptr) | 79 | 395 | { | 80 | 395 | auto fun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_type>(_pRawFun); | 81 | 395 | return (*fun_typed_ptr)(std::forward<Args>(args)...); | 82 | 395 | } | 83 | 0 | else | 84 | 0 | { | 85 | 0 | auto fun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_userdata_type>(_pRawFun); | 86 | 0 | return (*fun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...); | 87 | 0 | } | 88 | 395 | } |
Unexecuted instantiation: double mu::generic_callable_type::call_fun<3ul, double&, double&, double&>(double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_fun<4ul, double&, double&, double&, double&>(double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_fun<5ul, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_fun<6ul, double&, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_fun<7ul, double&, double&, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_fun<8ul, double&, double&, double&, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_fun<9ul, double&, double&, double&, double&, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_fun<10ul, double&, double&, double&, double&, double&, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&, double&, double&, double&, double&, double&) const |
89 | | |
90 | | template <std::size_t NbParams, typename... Args> |
91 | | value_type call_bulkfun(Args&&... args) const |
92 | 0 | { |
93 | 0 | static_assert(NbParams == sizeof...(Args) - 2, "mismatch between NbParams and Args"); |
94 | 0 | if (_pUserData == nullptr) { |
95 | 0 | auto bulkfun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::bulkfun_type>(_pRawFun); |
96 | 0 | return (*bulkfun_typed_ptr)(std::forward<Args>(args)...); |
97 | 0 | } else { |
98 | 0 | auto bulkfun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::bulkfun_userdata_type>(_pRawFun); |
99 | 0 | return (*bulkfun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...); |
100 | 0 | } |
101 | 0 | } Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<0ul, int&, int&>(int&, int&) const Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<1ul, int&, int&, double&>(int&, int&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<2ul, int&, int&, double&, double&>(int&, int&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<3ul, int&, int&, double&, double&, double&>(int&, int&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<4ul, int&, int&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<5ul, int&, int&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<6ul, int&, int&, double&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<7ul, int&, int&, double&, double&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<8ul, int&, int&, double&, double&, double&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<9ul, int&, int&, double&, double&, double&, double&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<10ul, int&, int&, double&, double&, double&, double&, double&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&, double&, double&, double&, double&, double&) const |
102 | | |
103 | | value_type call_multfun(const value_type* a_afArg, int a_iArgc) const |
104 | 3.44k | { |
105 | 3.44k | if (_pUserData == nullptr) { |
106 | 3.44k | auto multfun_typed_ptr = reinterpret_cast<multfun_type>(_pRawFun); |
107 | 3.44k | return (*multfun_typed_ptr)(a_afArg, a_iArgc); |
108 | 3.44k | } else { |
109 | 0 | auto multfun_userdata_typed_ptr = reinterpret_cast<multfun_userdata_type>(_pRawFun); |
110 | 0 | return (*multfun_userdata_typed_ptr)(_pUserData, a_afArg, a_iArgc); |
111 | 0 | } |
112 | 3.44k | } |
113 | | |
114 | | template <std::size_t NbParams, typename... Args> |
115 | | value_type call_strfun(Args&&... args) const |
116 | 0 | { |
117 | 0 | static_assert(NbParams == sizeof...(Args), "mismatch between NbParams and Args"); |
118 | 0 | if (_pUserData == nullptr) |
119 | 0 | { |
120 | 0 | auto strfun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::strfun_type>(_pRawFun); |
121 | 0 | return (*strfun_typed_ptr)(std::forward<Args>(args)...); |
122 | 0 | } |
123 | 0 | else |
124 | 0 | { |
125 | 0 | auto strfun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::strfun_userdata_type>(_pRawFun); |
126 | 0 | return (*strfun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...); |
127 | 0 | } |
128 | 0 | } Unexecuted instantiation: double mu::generic_callable_type::call_strfun<1ul, char const*>(char const*&&) const Unexecuted instantiation: double mu::generic_callable_type::call_strfun<2ul, char const*, double&>(char const*&&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_strfun<3ul, char const*, double&, double&>(char const*&&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_strfun<4ul, char const*, double&, double&, double&>(char const*&&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_strfun<5ul, char const*, double&, double&, double&, double&>(char const*&&, double&, double&, double&, double&) const Unexecuted instantiation: double mu::generic_callable_type::call_strfun<6ul, char const*, double&, double&, double&, double&, double&>(char const*&&, double&, double&, double&, double&, double&) const |
129 | | |
130 | | bool operator==(generic_callable_type other) const |
131 | 58.4k | { |
132 | 58.4k | return _pRawFun == other._pRawFun && _pUserData == other._pUserData; |
133 | 58.4k | } |
134 | | |
135 | | explicit operator bool() const |
136 | 0 | { |
137 | 0 | return _pRawFun != nullptr; |
138 | 0 | } |
139 | | |
140 | | bool operator==(std::nullptr_t) const |
141 | 62.8k | { |
142 | 62.8k | return _pRawFun == nullptr; |
143 | 62.8k | } |
144 | | |
145 | | bool operator!=(std::nullptr_t) const |
146 | 115k | { |
147 | 115k | return _pRawFun != nullptr; |
148 | 115k | } |
149 | | }; |
150 | | |
151 | | static_assert(std::is_trivial<generic_callable_type>::value, "generic_callable_type shall be trivial"); |
152 | | static_assert(std::is_standard_layout<generic_callable_type>::value, "generic_callable_type shall have standard layout"); |
153 | | // C++17: static_assert(std::is_aggregate<generic_callable_type>::value, "generic_callable_type shall be an aggregate"); |
154 | | |
155 | | /** \brief Encapsulation of the data for a single formula token. |
156 | | |
157 | | Formula token implementation. Part of the Math Parser Package. |
158 | | Formula tokens can be either one of the following: |
159 | | <ul> |
160 | | <li>value</li> |
161 | | <li>variable</li> |
162 | | <li>function with numerical arguments</li> |
163 | | <li>functions with a string as argument</li> |
164 | | <li>prefix operators</li> |
165 | | <li>infix operators</li> |
166 | | <li>binary operator</li> |
167 | | </ul> |
168 | | */ |
169 | | template<typename TBase, typename TString> |
170 | | class ParserToken final |
171 | | { |
172 | | private: |
173 | | |
174 | | ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode. |
175 | | ETypeCode m_iType; |
176 | | void* m_pTok; ///< Stores Token pointer; not applicable for all tokens |
177 | | int m_iIdx; ///< An otional index to an external buffer storing the token data |
178 | | TString m_strTok; ///< Token string |
179 | | TString m_strVal; ///< Value for string variables |
180 | | value_type m_fVal; ///< the value |
181 | | std::unique_ptr<ParserCallback> m_pCallback; |
182 | | |
183 | | public: |
184 | | |
185 | | /** \brief Constructor (default). |
186 | | |
187 | | Sets token to an neutral state of type cmUNKNOWN. |
188 | | \throw nothrow |
189 | | \sa ECmdCode |
190 | | */ |
191 | | ParserToken() |
192 | 2.71M | :m_iCode(cmUNKNOWN) |
193 | 2.71M | , m_iType(tpVOID) |
194 | 2.71M | , m_pTok(0) |
195 | 2.71M | , m_iIdx(-1) |
196 | 2.71M | , m_strTok() |
197 | 2.71M | , m_strVal() |
198 | 2.71M | , m_fVal(0) |
199 | 2.71M | , m_pCallback() |
200 | 2.71M | {} |
201 | | |
202 | | //------------------------------------------------------------------------------ |
203 | | /** \brief Create token from another one. |
204 | | |
205 | | Implemented by calling Assign(...) |
206 | | \throw nothrow |
207 | | \post m_iType==cmUNKNOWN |
208 | | \sa #Assign |
209 | | */ |
210 | | ParserToken(const ParserToken& a_Tok) |
211 | 5.74M | { |
212 | 5.74M | Assign(a_Tok); |
213 | 5.74M | } |
214 | | |
215 | | |
216 | | /** \brief Assignment operator. |
217 | | |
218 | | Copy token state from another token and return this. |
219 | | Implemented by calling Assign(...). |
220 | | \throw nothrow |
221 | | */ |
222 | | ParserToken& operator=(const ParserToken& a_Tok) |
223 | 7.23M | { |
224 | 7.23M | Assign(a_Tok); |
225 | 7.23M | return *this; |
226 | 7.23M | } |
227 | | |
228 | | |
229 | | /** \brief Copy token information from argument. |
230 | | |
231 | | \throw nothrow |
232 | | */ |
233 | | void Assign(const ParserToken& a_Tok) |
234 | 12.9M | { |
235 | 12.9M | m_iCode = a_Tok.m_iCode; |
236 | 12.9M | m_pTok = a_Tok.m_pTok; |
237 | 12.9M | m_strTok = a_Tok.m_strTok; |
238 | 12.9M | m_iIdx = a_Tok.m_iIdx; |
239 | 12.9M | m_strVal = a_Tok.m_strVal; |
240 | 12.9M | m_iType = a_Tok.m_iType; |
241 | 12.9M | m_fVal = a_Tok.m_fVal; |
242 | | // create new callback object if a_Tok has one |
243 | 12.9M | m_pCallback.reset(a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0); |
244 | 12.9M | } |
245 | | |
246 | | //------------------------------------------------------------------------------ |
247 | | /** \brief Assign a token type. |
248 | | |
249 | | Token may not be of type value, variable or function. Those have separate set functions. |
250 | | |
251 | | \pre [assert] a_iType!=cmVAR |
252 | | \pre [assert] a_iType!=cmVAL |
253 | | \pre [assert] a_iType!=cmFUNC |
254 | | \post m_fVal = 0 |
255 | | \post m_pTok = 0 |
256 | | */ |
257 | | ParserToken& Set(ECmdCode a_iType, const TString& a_strTok = TString()) |
258 | 1.73M | { |
259 | | // The following types can't be set this way, they have special Set functions |
260 | 1.73M | MUP_ASSERT(a_iType != cmVAR); |
261 | 1.73M | MUP_ASSERT(a_iType != cmVAL); |
262 | 1.73M | MUP_ASSERT(a_iType != cmFUNC); |
263 | | |
264 | 1.73M | m_iCode = a_iType; |
265 | 1.73M | m_iType = tpVOID; |
266 | 1.73M | m_pTok = 0; |
267 | 1.73M | m_strTok = a_strTok; |
268 | 1.73M | m_iIdx = -1; |
269 | | |
270 | 1.73M | return *this; |
271 | 1.73M | } |
272 | | |
273 | | //------------------------------------------------------------------------------ |
274 | | /** \brief Set Callback type. */ |
275 | | ParserToken& Set(const ParserCallback& a_pCallback, const TString& a_sTok) |
276 | 66.9k | { |
277 | 66.9k | MUP_ASSERT(a_pCallback.IsValid()); |
278 | | |
279 | 66.9k | m_iCode = a_pCallback.GetCode(); |
280 | 66.9k | m_iType = tpVOID; |
281 | 66.9k | m_strTok = a_sTok; |
282 | 66.9k | m_pCallback.reset(new ParserCallback(a_pCallback)); |
283 | | |
284 | 66.9k | m_pTok = 0; |
285 | 66.9k | m_iIdx = -1; |
286 | | |
287 | 66.9k | return *this; |
288 | 66.9k | } |
289 | | |
290 | | //------------------------------------------------------------------------------ |
291 | | /** \brief Make this token a value token. |
292 | | |
293 | | Member variables not necessary for value tokens will be invalidated. |
294 | | \throw nothrow |
295 | | */ |
296 | | ParserToken& SetVal(TBase a_fVal, const TString& a_strTok = TString()) |
297 | 739k | { |
298 | 739k | m_iCode = cmVAL; |
299 | 739k | m_iType = tpDBL; |
300 | 739k | m_fVal = a_fVal; |
301 | 739k | m_strTok = a_strTok; |
302 | 739k | m_iIdx = -1; |
303 | | |
304 | 739k | m_pTok = 0; |
305 | 739k | m_pCallback.reset(0); |
306 | | |
307 | 739k | return *this; |
308 | 739k | } |
309 | | |
310 | | //------------------------------------------------------------------------------ |
311 | | /** \brief make this token a variable token. |
312 | | |
313 | | Member variables not necessary for variable tokens will be invalidated. |
314 | | \throw nothrow |
315 | | */ |
316 | | ParserToken& SetVar(TBase* a_pVar, const TString& a_strTok) |
317 | 0 | { |
318 | 0 | m_iCode = cmVAR; |
319 | 0 | m_iType = tpDBL; |
320 | 0 | m_strTok = a_strTok; |
321 | 0 | m_iIdx = -1; |
322 | 0 | m_pTok = (void*)a_pVar; |
323 | 0 | m_pCallback.reset(0); |
324 | 0 | return *this; |
325 | 0 | } |
326 | | |
327 | | //------------------------------------------------------------------------------ |
328 | | /** \brief Make this token a variable token. |
329 | | |
330 | | Member variables not necessary for variable tokens will be invalidated. |
331 | | \throw nothrow |
332 | | */ |
333 | | ParserToken& SetString(const TString& a_strTok, std::size_t a_iSize) |
334 | 11.0k | { |
335 | 11.0k | m_iCode = cmSTRING; |
336 | 11.0k | m_iType = tpSTR; |
337 | 11.0k | m_strTok = a_strTok; |
338 | 11.0k | m_iIdx = static_cast<int>(a_iSize); |
339 | | |
340 | 11.0k | m_pTok = 0; |
341 | 11.0k | m_pCallback.reset(0); |
342 | 11.0k | return *this; |
343 | 11.0k | } |
344 | | |
345 | | //------------------------------------------------------------------------------ |
346 | | /** \brief Set an index associated with the token related data. |
347 | | |
348 | | In cmSTRFUNC - This is the index to a string table in the main parser. |
349 | | \param a_iIdx The index the string function result will take in the bytecode parser. |
350 | | \throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING |
351 | | */ |
352 | | void SetIdx(int a_iIdx) |
353 | 10.8k | { |
354 | 10.8k | if (m_iCode != cmSTRING || a_iIdx < 0) |
355 | 0 | throw ParserError(ecINTERNAL_ERROR); |
356 | | |
357 | 10.8k | m_iIdx = a_iIdx; |
358 | 10.8k | } |
359 | | |
360 | | //------------------------------------------------------------------------------ |
361 | | /** \brief Return Index associated with the token related data. |
362 | | |
363 | | In cmSTRFUNC - This is the index to a string table in the main parser. |
364 | | |
365 | | \throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING |
366 | | \return The index the result will take in the Bytecode calculatin array (#m_iIdx). |
367 | | */ |
368 | | int GetIdx() const |
369 | 0 | { |
370 | 0 | if (m_iIdx < 0 || m_iCode != cmSTRING) |
371 | 0 | throw ParserError(ecINTERNAL_ERROR); |
372 | | |
373 | 0 | return m_iIdx; |
374 | 0 | } |
375 | | |
376 | | //------------------------------------------------------------------------------ |
377 | | /** \brief Return the token type. |
378 | | |
379 | | \return #m_iType |
380 | | \throw nothrow |
381 | | */ |
382 | | ECmdCode GetCode() const |
383 | 10.2M | { |
384 | 10.2M | if (m_pCallback.get()) |
385 | 793k | { |
386 | 793k | return m_pCallback->GetCode(); |
387 | 793k | } |
388 | 9.48M | else |
389 | 9.48M | { |
390 | 9.48M | return m_iCode; |
391 | 9.48M | } |
392 | 10.2M | } |
393 | | |
394 | | //------------------------------------------------------------------------------ |
395 | | ETypeCode GetType() const |
396 | 861k | { |
397 | 861k | if (m_pCallback.get()) |
398 | 125k | { |
399 | 125k | return m_pCallback->GetType(); |
400 | 125k | } |
401 | 735k | else |
402 | 735k | { |
403 | 735k | return m_iType; |
404 | 735k | } |
405 | 861k | } |
406 | | |
407 | | //------------------------------------------------------------------------------ |
408 | | int GetPri() const |
409 | 47.8k | { |
410 | 47.8k | if (!m_pCallback.get()) |
411 | 0 | throw ParserError(ecINTERNAL_ERROR); |
412 | | |
413 | 47.8k | if (m_pCallback->GetCode() != cmOPRT_BIN && m_pCallback->GetCode() != cmOPRT_INFIX) |
414 | 0 | throw ParserError(ecINTERNAL_ERROR); |
415 | | |
416 | 47.8k | return m_pCallback->GetPri(); |
417 | 47.8k | } |
418 | | |
419 | | //------------------------------------------------------------------------------ |
420 | | EOprtAssociativity GetAssociativity() const |
421 | 0 | { |
422 | 0 | if (m_pCallback.get() == nullptr || m_pCallback->GetCode() != cmOPRT_BIN) |
423 | 0 | throw ParserError(ecINTERNAL_ERROR); |
424 | | |
425 | 0 | return m_pCallback->GetAssociativity(); |
426 | 0 | } |
427 | | |
428 | | //------------------------------------------------------------------------------ |
429 | | /** \brief Return the address of the callback function assoziated with |
430 | | function and operator tokens. |
431 | | |
432 | | \return The pointer stored in #m_pTok. |
433 | | \throw exception_type if token type is non of: |
434 | | <ul> |
435 | | <li>cmFUNC</li> |
436 | | <li>cmSTRFUNC</li> |
437 | | <li>cmPOSTOP</li> |
438 | | <li>cmINFIXOP</li> |
439 | | <li>cmOPRT_BIN</li> |
440 | | </ul> |
441 | | \sa ECmdCode |
442 | | */ |
443 | | generic_callable_type GetFuncAddr() const |
444 | 240k | { |
445 | 240k | return (m_pCallback.get()) |
446 | 240k | ? generic_callable_type{(erased_fun_type)m_pCallback->GetAddr(), |
447 | 200k | m_pCallback->GetUserData()} |
448 | 240k | : generic_callable_type{}; |
449 | 240k | } |
450 | | |
451 | | //------------------------------------------------------------------------------ |
452 | | /** \biref Get value of the token. |
453 | | |
454 | | Only applicable to variable and value tokens. |
455 | | \throw exception_type if token is no value/variable token. |
456 | | */ |
457 | | TBase GetVal() const |
458 | 585k | { |
459 | 585k | switch (m_iCode) |
460 | 585k | { |
461 | 585k | case cmVAL: return m_fVal; |
462 | 0 | case cmVAR: return *((TBase*)m_pTok); |
463 | 1 | default: throw ParserError(ecVAL_EXPECTED); |
464 | 585k | } |
465 | 585k | } |
466 | | |
467 | | //------------------------------------------------------------------------------ |
468 | | /** \brief Get address of a variable token. |
469 | | |
470 | | Valid only if m_iType==CmdVar. |
471 | | \throw exception_type if token is no variable token. |
472 | | */ |
473 | | TBase* GetVar() const |
474 | 0 | { |
475 | 0 | if (m_iCode != cmVAR) |
476 | 0 | throw ParserError(ecINTERNAL_ERROR); |
477 | | |
478 | 0 | return (TBase*)m_pTok; |
479 | 0 | } |
480 | | |
481 | | //------------------------------------------------------------------------------ |
482 | | /** \brief Return the number of function arguments. |
483 | | |
484 | | Valid only if m_iType==CmdFUNC. |
485 | | */ |
486 | | int GetArgCount() const |
487 | 251k | { |
488 | 251k | MUP_ASSERT(m_pCallback.get()); |
489 | | |
490 | 251k | if (!m_pCallback->IsValid()) |
491 | 0 | throw ParserError(ecINTERNAL_ERROR); |
492 | | |
493 | 251k | return m_pCallback->GetArgc(); |
494 | 251k | } |
495 | | |
496 | | //------------------------------------------------------------------------------ |
497 | | /** \brief Return true if the token is a function token that can be optimized. |
498 | | */ |
499 | | bool IsOptimizable() const |
500 | 62.8k | { |
501 | 62.8k | return m_pCallback->IsValid() && m_pCallback->IsOptimizable(); |
502 | 62.8k | } |
503 | | |
504 | | //------------------------------------------------------------------------------ |
505 | | /** \brief Return the token identifier. |
506 | | |
507 | | If #m_iType is cmSTRING the token identifier is the value of the string argument |
508 | | for a string function. |
509 | | \return #m_strTok |
510 | | \throw nothrow |
511 | | \sa m_strTok |
512 | | */ |
513 | | const TString& GetAsString() const |
514 | 11.1k | { |
515 | 11.1k | return m_strTok; |
516 | 11.1k | } |
517 | | }; |
518 | | } // namespace mu |
519 | | |
520 | | #if defined(_MSC_VER) |
521 | | #pragma warning(pop) |
522 | | #endif |
523 | | |
524 | | #endif |