Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/core/math/expression.h
9903 views
1
/**************************************************************************/
2
/* expression.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/object/ref_counted.h"
34
35
class Expression : public RefCounted {
36
GDCLASS(Expression, RefCounted);
37
38
private:
39
struct Input {
40
Variant::Type type = Variant::NIL;
41
String name;
42
43
Input() {}
44
};
45
46
Vector<Input> inputs;
47
Variant::Type output_type = Variant::NIL;
48
49
String expression;
50
51
bool sequenced = false;
52
int str_ofs = 0;
53
bool expression_dirty = false;
54
55
bool _compile_expression();
56
57
enum TokenType {
58
TK_CURLY_BRACKET_OPEN,
59
TK_CURLY_BRACKET_CLOSE,
60
TK_BRACKET_OPEN,
61
TK_BRACKET_CLOSE,
62
TK_PARENTHESIS_OPEN,
63
TK_PARENTHESIS_CLOSE,
64
TK_IDENTIFIER,
65
TK_BUILTIN_FUNC,
66
TK_SELF,
67
TK_CONSTANT,
68
TK_BASIC_TYPE,
69
TK_COLON,
70
TK_COMMA,
71
TK_PERIOD,
72
TK_OP_IN,
73
TK_OP_EQUAL,
74
TK_OP_NOT_EQUAL,
75
TK_OP_LESS,
76
TK_OP_LESS_EQUAL,
77
TK_OP_GREATER,
78
TK_OP_GREATER_EQUAL,
79
TK_OP_AND,
80
TK_OP_OR,
81
TK_OP_NOT,
82
TK_OP_ADD,
83
TK_OP_SUB,
84
TK_OP_MUL,
85
TK_OP_DIV,
86
TK_OP_MOD,
87
TK_OP_POW,
88
TK_OP_SHIFT_LEFT,
89
TK_OP_SHIFT_RIGHT,
90
TK_OP_BIT_AND,
91
TK_OP_BIT_OR,
92
TK_OP_BIT_XOR,
93
TK_OP_BIT_INVERT,
94
TK_INPUT,
95
TK_EOF,
96
TK_ERROR,
97
TK_MAX
98
};
99
100
static const char *token_name[TK_MAX];
101
struct Token {
102
TokenType type;
103
Variant value;
104
};
105
106
void _set_error(const String &p_err) {
107
if (error_set) {
108
return;
109
}
110
error_str = p_err;
111
error_set = true;
112
}
113
114
Error _get_token(Token &r_token);
115
116
String error_str;
117
bool error_set = true;
118
119
struct ENode {
120
enum Type {
121
TYPE_INPUT,
122
TYPE_CONSTANT,
123
TYPE_SELF,
124
TYPE_OPERATOR,
125
TYPE_INDEX,
126
TYPE_NAMED_INDEX,
127
TYPE_ARRAY,
128
TYPE_DICTIONARY,
129
TYPE_CONSTRUCTOR,
130
TYPE_BUILTIN_FUNC,
131
TYPE_CALL
132
};
133
134
ENode *next = nullptr;
135
136
Type type = TYPE_INPUT;
137
138
ENode() {}
139
virtual ~ENode() {
140
if (next) {
141
memdelete(next);
142
}
143
}
144
};
145
146
struct ExpressionNode {
147
bool is_op = false;
148
union {
149
Variant::Operator op;
150
ENode *node = nullptr;
151
};
152
};
153
154
ENode *_parse_expression();
155
156
struct InputNode : public ENode {
157
int index = 0;
158
InputNode() {
159
type = TYPE_INPUT;
160
}
161
};
162
163
struct ConstantNode : public ENode {
164
Variant value = Variant::NIL;
165
ConstantNode() {
166
type = TYPE_CONSTANT;
167
}
168
};
169
170
struct OperatorNode : public ENode {
171
Variant::Operator op = Variant::Operator::OP_ADD;
172
173
ENode *nodes[2] = { nullptr, nullptr };
174
175
OperatorNode() {
176
type = TYPE_OPERATOR;
177
}
178
};
179
180
struct SelfNode : public ENode {
181
SelfNode() {
182
type = TYPE_SELF;
183
}
184
};
185
186
struct IndexNode : public ENode {
187
ENode *base = nullptr;
188
ENode *index = nullptr;
189
190
IndexNode() {
191
type = TYPE_INDEX;
192
}
193
};
194
195
struct NamedIndexNode : public ENode {
196
ENode *base = nullptr;
197
StringName name;
198
199
NamedIndexNode() {
200
type = TYPE_NAMED_INDEX;
201
}
202
};
203
204
struct ConstructorNode : public ENode {
205
Variant::Type data_type = Variant::Type::NIL;
206
Vector<ENode *> arguments;
207
208
ConstructorNode() {
209
type = TYPE_CONSTRUCTOR;
210
}
211
};
212
213
struct CallNode : public ENode {
214
ENode *base = nullptr;
215
StringName method;
216
Vector<ENode *> arguments;
217
218
CallNode() {
219
type = TYPE_CALL;
220
}
221
};
222
223
struct ArrayNode : public ENode {
224
Vector<ENode *> array;
225
ArrayNode() {
226
type = TYPE_ARRAY;
227
}
228
};
229
230
struct DictionaryNode : public ENode {
231
Vector<ENode *> dict;
232
DictionaryNode() {
233
type = TYPE_DICTIONARY;
234
}
235
};
236
237
struct BuiltinFuncNode : public ENode {
238
StringName func;
239
Vector<ENode *> arguments;
240
BuiltinFuncNode() {
241
type = TYPE_BUILTIN_FUNC;
242
}
243
};
244
245
template <typename T>
246
T *alloc_node() {
247
T *node = memnew(T);
248
node->next = nodes;
249
nodes = node;
250
return node;
251
}
252
253
ENode *root = nullptr;
254
ENode *nodes = nullptr;
255
256
Vector<String> input_names;
257
258
bool execution_error = false;
259
bool _execute(const Array &p_inputs, Object *p_instance, Expression::ENode *p_node, Variant &r_ret, bool p_const_calls_only, String &r_error_str);
260
261
protected:
262
static void _bind_methods();
263
264
public:
265
Error parse(const String &p_expression, const Vector<String> &p_input_names = Vector<String>());
266
Variant execute(const Array &p_inputs = Array(), Object *p_base = nullptr, bool p_show_error = true, bool p_const_calls_only = false);
267
bool has_execute_failed() const;
268
String get_error_text() const;
269
270
Expression() {}
271
~Expression();
272
};
273
274