Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/core/math/expression.cpp
9903 views
1
/**************************************************************************/
2
/* expression.cpp */
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
#include "expression.h"
32
33
#include "core/object/class_db.h"
34
35
Error Expression::_get_token(Token &r_token) {
36
while (true) {
37
#define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++])
38
39
char32_t cchar = GET_CHAR();
40
41
switch (cchar) {
42
case 0: {
43
r_token.type = TK_EOF;
44
return OK;
45
}
46
case '{': {
47
r_token.type = TK_CURLY_BRACKET_OPEN;
48
return OK;
49
}
50
case '}': {
51
r_token.type = TK_CURLY_BRACKET_CLOSE;
52
return OK;
53
}
54
case '[': {
55
r_token.type = TK_BRACKET_OPEN;
56
return OK;
57
}
58
case ']': {
59
r_token.type = TK_BRACKET_CLOSE;
60
return OK;
61
}
62
case '(': {
63
r_token.type = TK_PARENTHESIS_OPEN;
64
return OK;
65
}
66
case ')': {
67
r_token.type = TK_PARENTHESIS_CLOSE;
68
return OK;
69
}
70
case ',': {
71
r_token.type = TK_COMMA;
72
return OK;
73
}
74
case ':': {
75
r_token.type = TK_COLON;
76
return OK;
77
}
78
case '$': {
79
r_token.type = TK_INPUT;
80
int index = 0;
81
do {
82
if (!is_digit(expression[str_ofs])) {
83
_set_error("Expected number after '$'");
84
r_token.type = TK_ERROR;
85
return ERR_PARSE_ERROR;
86
}
87
index *= 10;
88
index += expression[str_ofs] - '0';
89
str_ofs++;
90
91
} while (is_digit(expression[str_ofs]));
92
93
r_token.value = index;
94
return OK;
95
}
96
case '=': {
97
cchar = GET_CHAR();
98
if (cchar == '=') {
99
r_token.type = TK_OP_EQUAL;
100
} else {
101
_set_error("Expected '='");
102
r_token.type = TK_ERROR;
103
return ERR_PARSE_ERROR;
104
}
105
return OK;
106
}
107
case '!': {
108
if (expression[str_ofs] == '=') {
109
r_token.type = TK_OP_NOT_EQUAL;
110
str_ofs++;
111
} else {
112
r_token.type = TK_OP_NOT;
113
}
114
return OK;
115
}
116
case '>': {
117
if (expression[str_ofs] == '=') {
118
r_token.type = TK_OP_GREATER_EQUAL;
119
str_ofs++;
120
} else if (expression[str_ofs] == '>') {
121
r_token.type = TK_OP_SHIFT_RIGHT;
122
str_ofs++;
123
} else {
124
r_token.type = TK_OP_GREATER;
125
}
126
return OK;
127
}
128
case '<': {
129
if (expression[str_ofs] == '=') {
130
r_token.type = TK_OP_LESS_EQUAL;
131
str_ofs++;
132
} else if (expression[str_ofs] == '<') {
133
r_token.type = TK_OP_SHIFT_LEFT;
134
str_ofs++;
135
} else {
136
r_token.type = TK_OP_LESS;
137
}
138
return OK;
139
}
140
case '+': {
141
r_token.type = TK_OP_ADD;
142
return OK;
143
}
144
case '-': {
145
r_token.type = TK_OP_SUB;
146
return OK;
147
}
148
case '/': {
149
r_token.type = TK_OP_DIV;
150
return OK;
151
}
152
case '*': {
153
if (expression[str_ofs] == '*') {
154
r_token.type = TK_OP_POW;
155
str_ofs++;
156
} else {
157
r_token.type = TK_OP_MUL;
158
}
159
return OK;
160
}
161
case '%': {
162
r_token.type = TK_OP_MOD;
163
return OK;
164
}
165
case '&': {
166
if (expression[str_ofs] == '&') {
167
r_token.type = TK_OP_AND;
168
str_ofs++;
169
} else {
170
r_token.type = TK_OP_BIT_AND;
171
}
172
return OK;
173
}
174
case '|': {
175
if (expression[str_ofs] == '|') {
176
r_token.type = TK_OP_OR;
177
str_ofs++;
178
} else {
179
r_token.type = TK_OP_BIT_OR;
180
}
181
return OK;
182
}
183
case '^': {
184
r_token.type = TK_OP_BIT_XOR;
185
186
return OK;
187
}
188
case '~': {
189
r_token.type = TK_OP_BIT_INVERT;
190
191
return OK;
192
}
193
case '\'':
194
case '"': {
195
String str;
196
char32_t prev = 0;
197
while (true) {
198
char32_t ch = GET_CHAR();
199
200
if (ch == 0) {
201
_set_error("Unterminated String");
202
r_token.type = TK_ERROR;
203
return ERR_PARSE_ERROR;
204
} else if (ch == cchar) {
205
// cchar contain a corresponding quote symbol
206
break;
207
} else if (ch == '\\') {
208
//escaped characters...
209
210
char32_t next = GET_CHAR();
211
if (next == 0) {
212
_set_error("Unterminated String");
213
r_token.type = TK_ERROR;
214
return ERR_PARSE_ERROR;
215
}
216
char32_t res = 0;
217
218
switch (next) {
219
case 'b':
220
res = 8;
221
break;
222
case 't':
223
res = 9;
224
break;
225
case 'n':
226
res = 10;
227
break;
228
case 'f':
229
res = 12;
230
break;
231
case 'r':
232
res = 13;
233
break;
234
case 'U':
235
case 'u': {
236
// Hexadecimal sequence.
237
int hex_len = (next == 'U') ? 6 : 4;
238
for (int j = 0; j < hex_len; j++) {
239
char32_t c = GET_CHAR();
240
241
if (c == 0) {
242
_set_error("Unterminated String");
243
r_token.type = TK_ERROR;
244
return ERR_PARSE_ERROR;
245
}
246
if (!is_hex_digit(c)) {
247
_set_error("Malformed hex constant in string");
248
r_token.type = TK_ERROR;
249
return ERR_PARSE_ERROR;
250
}
251
char32_t v;
252
if (is_digit(c)) {
253
v = c - '0';
254
} else if (c >= 'a' && c <= 'f') {
255
v = c - 'a';
256
v += 10;
257
} else if (c >= 'A' && c <= 'F') {
258
v = c - 'A';
259
v += 10;
260
} else {
261
ERR_PRINT("Bug parsing hex constant.");
262
v = 0;
263
}
264
265
res <<= 4;
266
res |= v;
267
}
268
269
} break;
270
default: {
271
res = next;
272
} break;
273
}
274
275
// Parse UTF-16 pair.
276
if ((res & 0xfffffc00) == 0xd800) {
277
if (prev == 0) {
278
prev = res;
279
continue;
280
} else {
281
_set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
282
r_token.type = TK_ERROR;
283
return ERR_PARSE_ERROR;
284
}
285
} else if ((res & 0xfffffc00) == 0xdc00) {
286
if (prev == 0) {
287
_set_error("Invalid UTF-16 sequence in string, unpaired trail surrogate");
288
r_token.type = TK_ERROR;
289
return ERR_PARSE_ERROR;
290
} else {
291
res = (prev << 10UL) + res - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
292
prev = 0;
293
}
294
}
295
if (prev != 0) {
296
_set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
297
r_token.type = TK_ERROR;
298
return ERR_PARSE_ERROR;
299
}
300
str += res;
301
} else {
302
if (prev != 0) {
303
_set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
304
r_token.type = TK_ERROR;
305
return ERR_PARSE_ERROR;
306
}
307
str += ch;
308
}
309
}
310
if (prev != 0) {
311
_set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
312
r_token.type = TK_ERROR;
313
return ERR_PARSE_ERROR;
314
}
315
316
r_token.type = TK_CONSTANT;
317
r_token.value = str;
318
return OK;
319
320
} break;
321
default: {
322
if (cchar <= 32) {
323
break;
324
}
325
326
char32_t next_char = (str_ofs >= expression.length()) ? 0 : expression[str_ofs];
327
if (is_digit(cchar) || (cchar == '.' && is_digit(next_char))) {
328
//a number
329
330
String num;
331
#define READING_SIGN 0
332
#define READING_INT 1
333
#define READING_HEX 2
334
#define READING_BIN 3
335
#define READING_DEC 4
336
#define READING_EXP 5
337
#define READING_DONE 6
338
int reading = READING_INT;
339
340
char32_t c = cchar;
341
bool exp_sign = false;
342
bool exp_beg = false;
343
bool bin_beg = false;
344
bool hex_beg = false;
345
bool is_float = false;
346
bool is_first_char = true;
347
348
while (true) {
349
switch (reading) {
350
case READING_INT: {
351
if (is_digit(c)) {
352
if (is_first_char && c == '0') {
353
if (next_char == 'b' || next_char == 'B') {
354
reading = READING_BIN;
355
} else if (next_char == 'x' || next_char == 'X') {
356
reading = READING_HEX;
357
}
358
}
359
} else if (c == '.') {
360
reading = READING_DEC;
361
is_float = true;
362
} else if (c == 'e' || c == 'E') {
363
reading = READING_EXP;
364
is_float = true;
365
} else {
366
reading = READING_DONE;
367
}
368
369
} break;
370
case READING_BIN: {
371
if (bin_beg && !is_binary_digit(c)) {
372
reading = READING_DONE;
373
} else if (c == 'b' || c == 'B') {
374
bin_beg = true;
375
}
376
377
} break;
378
case READING_HEX: {
379
if (hex_beg && !is_hex_digit(c)) {
380
reading = READING_DONE;
381
} else if (c == 'x' || c == 'X') {
382
hex_beg = true;
383
}
384
385
} break;
386
case READING_DEC: {
387
if (is_digit(c)) {
388
} else if (c == 'e' || c == 'E') {
389
reading = READING_EXP;
390
} else {
391
reading = READING_DONE;
392
}
393
394
} break;
395
case READING_EXP: {
396
if (is_digit(c)) {
397
exp_beg = true;
398
399
} else if ((c == '-' || c == '+') && !exp_sign && !exp_beg) {
400
exp_sign = true;
401
402
} else {
403
reading = READING_DONE;
404
}
405
} break;
406
}
407
408
if (reading == READING_DONE) {
409
break;
410
}
411
num += c;
412
c = GET_CHAR();
413
is_first_char = false;
414
}
415
416
if (c != 0) {
417
str_ofs--;
418
}
419
420
r_token.type = TK_CONSTANT;
421
422
if (is_float) {
423
r_token.value = num.to_float();
424
} else if (bin_beg) {
425
r_token.value = num.bin_to_int();
426
} else if (hex_beg) {
427
r_token.value = num.hex_to_int();
428
} else {
429
r_token.value = num.to_int();
430
}
431
return OK;
432
433
} else if (is_unicode_identifier_start(cchar)) {
434
String id = String::chr(cchar);
435
cchar = GET_CHAR();
436
437
while (is_unicode_identifier_continue(cchar)) {
438
id += cchar;
439
cchar = GET_CHAR();
440
}
441
442
str_ofs--; //go back one
443
444
if (id == "in") {
445
r_token.type = TK_OP_IN;
446
} else if (id == "null") {
447
r_token.type = TK_CONSTANT;
448
r_token.value = Variant();
449
} else if (id == "true") {
450
r_token.type = TK_CONSTANT;
451
r_token.value = true;
452
} else if (id == "false") {
453
r_token.type = TK_CONSTANT;
454
r_token.value = false;
455
} else if (id == "PI") {
456
r_token.type = TK_CONSTANT;
457
r_token.value = Math::PI;
458
} else if (id == "TAU") {
459
r_token.type = TK_CONSTANT;
460
r_token.value = Math::TAU;
461
} else if (id == "INF") {
462
r_token.type = TK_CONSTANT;
463
r_token.value = Math::INF;
464
} else if (id == "NAN") {
465
r_token.type = TK_CONSTANT;
466
r_token.value = Math::NaN;
467
} else if (id == "not") {
468
r_token.type = TK_OP_NOT;
469
} else if (id == "or") {
470
r_token.type = TK_OP_OR;
471
} else if (id == "and") {
472
r_token.type = TK_OP_AND;
473
} else if (id == "self") {
474
r_token.type = TK_SELF;
475
} else {
476
{
477
const Variant::Type type = Variant::get_type_by_name(id);
478
if (type < Variant::VARIANT_MAX) {
479
r_token.type = TK_BASIC_TYPE;
480
r_token.value = type;
481
return OK;
482
}
483
}
484
485
if (Variant::has_utility_function(id)) {
486
r_token.type = TK_BUILTIN_FUNC;
487
r_token.value = id;
488
return OK;
489
}
490
491
r_token.type = TK_IDENTIFIER;
492
r_token.value = id;
493
}
494
495
return OK;
496
497
} else if (cchar == '.') {
498
// Handled down there as we support '.[0-9]' as numbers above
499
r_token.type = TK_PERIOD;
500
return OK;
501
502
} else {
503
_set_error("Unexpected character.");
504
r_token.type = TK_ERROR;
505
return ERR_PARSE_ERROR;
506
}
507
}
508
}
509
#undef GET_CHAR
510
}
511
512
r_token.type = TK_ERROR;
513
return ERR_PARSE_ERROR;
514
}
515
516
const char *Expression::token_name[TK_MAX] = {
517
"CURLY BRACKET OPEN",
518
"CURLY BRACKET CLOSE",
519
"BRACKET OPEN",
520
"BRACKET CLOSE",
521
"PARENTHESIS OPEN",
522
"PARENTHESIS CLOSE",
523
"IDENTIFIER",
524
"BUILTIN FUNC",
525
"SELF",
526
"CONSTANT",
527
"BASIC TYPE",
528
"COLON",
529
"COMMA",
530
"PERIOD",
531
"OP IN",
532
"OP EQUAL",
533
"OP NOT EQUAL",
534
"OP LESS",
535
"OP LESS EQUAL",
536
"OP GREATER",
537
"OP GREATER EQUAL",
538
"OP AND",
539
"OP OR",
540
"OP NOT",
541
"OP ADD",
542
"OP SUB",
543
"OP MUL",
544
"OP DIV",
545
"OP MOD",
546
"OP POW",
547
"OP SHIFT LEFT",
548
"OP SHIFT RIGHT",
549
"OP BIT AND",
550
"OP BIT OR",
551
"OP BIT XOR",
552
"OP BIT INVERT",
553
"OP INPUT",
554
"EOF",
555
"ERROR"
556
};
557
558
Expression::ENode *Expression::_parse_expression() {
559
Vector<ExpressionNode> expression_nodes;
560
561
while (true) {
562
//keep appending stuff to expression
563
ENode *expr = nullptr;
564
565
Token tk;
566
_get_token(tk);
567
if (error_set) {
568
return nullptr;
569
}
570
571
switch (tk.type) {
572
case TK_CURLY_BRACKET_OPEN: {
573
//a dictionary
574
DictionaryNode *dn = alloc_node<DictionaryNode>();
575
576
while (true) {
577
int cofs = str_ofs;
578
_get_token(tk);
579
if (tk.type == TK_CURLY_BRACKET_CLOSE) {
580
break;
581
}
582
str_ofs = cofs; //revert
583
//parse an expression
584
ENode *subexpr = _parse_expression();
585
if (!subexpr) {
586
return nullptr;
587
}
588
dn->dict.push_back(subexpr);
589
590
_get_token(tk);
591
if (tk.type != TK_COLON) {
592
_set_error("Expected ':'");
593
return nullptr;
594
}
595
596
subexpr = _parse_expression();
597
if (!subexpr) {
598
return nullptr;
599
}
600
601
dn->dict.push_back(subexpr);
602
603
cofs = str_ofs;
604
_get_token(tk);
605
if (tk.type == TK_COMMA) {
606
//all good
607
} else if (tk.type == TK_CURLY_BRACKET_CLOSE) {
608
str_ofs = cofs;
609
} else {
610
_set_error("Expected ',' or '}'");
611
}
612
}
613
614
expr = dn;
615
} break;
616
case TK_BRACKET_OPEN: {
617
//an array
618
619
ArrayNode *an = alloc_node<ArrayNode>();
620
621
while (true) {
622
int cofs = str_ofs;
623
_get_token(tk);
624
if (tk.type == TK_BRACKET_CLOSE) {
625
break;
626
}
627
str_ofs = cofs; //revert
628
//parse an expression
629
ENode *subexpr = _parse_expression();
630
if (!subexpr) {
631
return nullptr;
632
}
633
an->array.push_back(subexpr);
634
635
cofs = str_ofs;
636
_get_token(tk);
637
if (tk.type == TK_COMMA) {
638
//all good
639
} else if (tk.type == TK_BRACKET_CLOSE) {
640
str_ofs = cofs;
641
} else {
642
_set_error("Expected ',' or ']'");
643
}
644
}
645
646
expr = an;
647
} break;
648
case TK_PARENTHESIS_OPEN: {
649
//a suexpression
650
ENode *e = _parse_expression();
651
if (error_set) {
652
return nullptr;
653
}
654
_get_token(tk);
655
if (tk.type != TK_PARENTHESIS_CLOSE) {
656
_set_error("Expected ')'");
657
return nullptr;
658
}
659
660
expr = e;
661
662
} break;
663
case TK_IDENTIFIER: {
664
String identifier = tk.value;
665
666
int cofs = str_ofs;
667
_get_token(tk);
668
if (tk.type == TK_PARENTHESIS_OPEN) {
669
//function call
670
CallNode *func_call = alloc_node<CallNode>();
671
func_call->method = identifier;
672
SelfNode *self_node = alloc_node<SelfNode>();
673
func_call->base = self_node;
674
675
while (true) {
676
int cofs2 = str_ofs;
677
_get_token(tk);
678
if (tk.type == TK_PARENTHESIS_CLOSE) {
679
break;
680
}
681
str_ofs = cofs2; //revert
682
//parse an expression
683
ENode *subexpr = _parse_expression();
684
if (!subexpr) {
685
return nullptr;
686
}
687
688
func_call->arguments.push_back(subexpr);
689
690
cofs2 = str_ofs;
691
_get_token(tk);
692
if (tk.type == TK_COMMA) {
693
//all good
694
} else if (tk.type == TK_PARENTHESIS_CLOSE) {
695
str_ofs = cofs2;
696
} else {
697
_set_error("Expected ',' or ')'");
698
}
699
}
700
701
expr = func_call;
702
} else {
703
//named indexing
704
str_ofs = cofs;
705
706
int input_index = -1;
707
for (int i = 0; i < input_names.size(); i++) {
708
if (input_names[i] == identifier) {
709
input_index = i;
710
break;
711
}
712
}
713
714
if (input_index != -1) {
715
InputNode *input = alloc_node<InputNode>();
716
input->index = input_index;
717
expr = input;
718
} else {
719
NamedIndexNode *index = alloc_node<NamedIndexNode>();
720
SelfNode *self_node = alloc_node<SelfNode>();
721
index->base = self_node;
722
index->name = identifier;
723
expr = index;
724
}
725
}
726
} break;
727
case TK_INPUT: {
728
InputNode *input = alloc_node<InputNode>();
729
input->index = tk.value;
730
expr = input;
731
} break;
732
case TK_SELF: {
733
SelfNode *self = alloc_node<SelfNode>();
734
expr = self;
735
} break;
736
case TK_CONSTANT: {
737
ConstantNode *constant = alloc_node<ConstantNode>();
738
constant->value = tk.value;
739
expr = constant;
740
} break;
741
case TK_BASIC_TYPE: {
742
//constructor..
743
744
Variant::Type bt = Variant::Type(int(tk.value));
745
_get_token(tk);
746
if (tk.type != TK_PARENTHESIS_OPEN) {
747
_set_error("Expected '('");
748
return nullptr;
749
}
750
751
ConstructorNode *constructor = alloc_node<ConstructorNode>();
752
constructor->data_type = bt;
753
754
while (true) {
755
int cofs = str_ofs;
756
_get_token(tk);
757
if (tk.type == TK_PARENTHESIS_CLOSE) {
758
break;
759
}
760
str_ofs = cofs; //revert
761
//parse an expression
762
ENode *subexpr = _parse_expression();
763
if (!subexpr) {
764
return nullptr;
765
}
766
767
constructor->arguments.push_back(subexpr);
768
769
cofs = str_ofs;
770
_get_token(tk);
771
if (tk.type == TK_COMMA) {
772
//all good
773
} else if (tk.type == TK_PARENTHESIS_CLOSE) {
774
str_ofs = cofs;
775
} else {
776
_set_error("Expected ',' or ')'");
777
}
778
}
779
780
expr = constructor;
781
782
} break;
783
case TK_BUILTIN_FUNC: {
784
//builtin function
785
786
StringName func = tk.value;
787
788
_get_token(tk);
789
if (tk.type != TK_PARENTHESIS_OPEN) {
790
_set_error("Expected '('");
791
return nullptr;
792
}
793
794
BuiltinFuncNode *bifunc = alloc_node<BuiltinFuncNode>();
795
bifunc->func = func;
796
797
while (true) {
798
int cofs = str_ofs;
799
_get_token(tk);
800
if (tk.type == TK_PARENTHESIS_CLOSE) {
801
break;
802
}
803
str_ofs = cofs; //revert
804
//parse an expression
805
ENode *subexpr = _parse_expression();
806
if (!subexpr) {
807
return nullptr;
808
}
809
810
bifunc->arguments.push_back(subexpr);
811
812
cofs = str_ofs;
813
_get_token(tk);
814
if (tk.type == TK_COMMA) {
815
//all good
816
} else if (tk.type == TK_PARENTHESIS_CLOSE) {
817
str_ofs = cofs;
818
} else {
819
_set_error("Expected ',' or ')'");
820
}
821
}
822
823
if (!Variant::is_utility_function_vararg(bifunc->func)) {
824
int expected_args = Variant::get_utility_function_argument_count(bifunc->func);
825
if (expected_args != bifunc->arguments.size()) {
826
_set_error("Builtin func '" + String(bifunc->func) + "' expects " + itos(expected_args) + " argument(s).");
827
}
828
}
829
830
expr = bifunc;
831
832
} break;
833
case TK_OP_SUB: {
834
ExpressionNode e;
835
e.is_op = true;
836
e.op = Variant::OP_NEGATE;
837
expression_nodes.push_back(e);
838
continue;
839
} break;
840
case TK_OP_NOT: {
841
ExpressionNode e;
842
e.is_op = true;
843
e.op = Variant::OP_NOT;
844
expression_nodes.push_back(e);
845
continue;
846
} break;
847
848
default: {
849
_set_error("Expected expression.");
850
return nullptr;
851
} break;
852
}
853
854
//before going to operators, must check indexing!
855
856
while (true) {
857
int cofs2 = str_ofs;
858
_get_token(tk);
859
if (error_set) {
860
return nullptr;
861
}
862
863
bool done = false;
864
865
switch (tk.type) {
866
case TK_BRACKET_OPEN: {
867
//value indexing
868
869
IndexNode *index = alloc_node<IndexNode>();
870
index->base = expr;
871
872
ENode *what = _parse_expression();
873
if (!what) {
874
return nullptr;
875
}
876
877
index->index = what;
878
879
_get_token(tk);
880
if (tk.type != TK_BRACKET_CLOSE) {
881
_set_error("Expected ']' at end of index.");
882
return nullptr;
883
}
884
expr = index;
885
886
} break;
887
case TK_PERIOD: {
888
//named indexing or function call
889
_get_token(tk);
890
if (tk.type != TK_IDENTIFIER && tk.type != TK_BUILTIN_FUNC) {
891
_set_error("Expected identifier after '.'");
892
return nullptr;
893
}
894
895
StringName identifier = tk.value;
896
897
int cofs = str_ofs;
898
_get_token(tk);
899
if (tk.type == TK_PARENTHESIS_OPEN) {
900
//function call
901
CallNode *func_call = alloc_node<CallNode>();
902
func_call->method = identifier;
903
func_call->base = expr;
904
905
while (true) {
906
int cofs3 = str_ofs;
907
_get_token(tk);
908
if (tk.type == TK_PARENTHESIS_CLOSE) {
909
break;
910
}
911
str_ofs = cofs3; //revert
912
//parse an expression
913
ENode *subexpr = _parse_expression();
914
if (!subexpr) {
915
return nullptr;
916
}
917
918
func_call->arguments.push_back(subexpr);
919
920
cofs3 = str_ofs;
921
_get_token(tk);
922
if (tk.type == TK_COMMA) {
923
//all good
924
} else if (tk.type == TK_PARENTHESIS_CLOSE) {
925
str_ofs = cofs3;
926
} else {
927
_set_error("Expected ',' or ')'");
928
}
929
}
930
931
expr = func_call;
932
} else {
933
//named indexing
934
str_ofs = cofs;
935
936
NamedIndexNode *index = alloc_node<NamedIndexNode>();
937
index->base = expr;
938
index->name = identifier;
939
expr = index;
940
}
941
942
} break;
943
default: {
944
str_ofs = cofs2;
945
done = true;
946
} break;
947
}
948
949
if (done) {
950
break;
951
}
952
}
953
954
//push expression
955
{
956
ExpressionNode e;
957
e.is_op = false;
958
e.node = expr;
959
expression_nodes.push_back(e);
960
}
961
962
//ok finally look for an operator
963
964
int cofs = str_ofs;
965
_get_token(tk);
966
if (error_set) {
967
return nullptr;
968
}
969
970
Variant::Operator op = Variant::OP_MAX;
971
972
switch (tk.type) {
973
case TK_OP_IN:
974
op = Variant::OP_IN;
975
break;
976
case TK_OP_EQUAL:
977
op = Variant::OP_EQUAL;
978
break;
979
case TK_OP_NOT_EQUAL:
980
op = Variant::OP_NOT_EQUAL;
981
break;
982
case TK_OP_LESS:
983
op = Variant::OP_LESS;
984
break;
985
case TK_OP_LESS_EQUAL:
986
op = Variant::OP_LESS_EQUAL;
987
break;
988
case TK_OP_GREATER:
989
op = Variant::OP_GREATER;
990
break;
991
case TK_OP_GREATER_EQUAL:
992
op = Variant::OP_GREATER_EQUAL;
993
break;
994
case TK_OP_AND:
995
op = Variant::OP_AND;
996
break;
997
case TK_OP_OR:
998
op = Variant::OP_OR;
999
break;
1000
case TK_OP_NOT:
1001
op = Variant::OP_NOT;
1002
break;
1003
case TK_OP_ADD:
1004
op = Variant::OP_ADD;
1005
break;
1006
case TK_OP_SUB:
1007
op = Variant::OP_SUBTRACT;
1008
break;
1009
case TK_OP_MUL:
1010
op = Variant::OP_MULTIPLY;
1011
break;
1012
case TK_OP_DIV:
1013
op = Variant::OP_DIVIDE;
1014
break;
1015
case TK_OP_MOD:
1016
op = Variant::OP_MODULE;
1017
break;
1018
case TK_OP_POW:
1019
op = Variant::OP_POWER;
1020
break;
1021
case TK_OP_SHIFT_LEFT:
1022
op = Variant::OP_SHIFT_LEFT;
1023
break;
1024
case TK_OP_SHIFT_RIGHT:
1025
op = Variant::OP_SHIFT_RIGHT;
1026
break;
1027
case TK_OP_BIT_AND:
1028
op = Variant::OP_BIT_AND;
1029
break;
1030
case TK_OP_BIT_OR:
1031
op = Variant::OP_BIT_OR;
1032
break;
1033
case TK_OP_BIT_XOR:
1034
op = Variant::OP_BIT_XOR;
1035
break;
1036
case TK_OP_BIT_INVERT:
1037
op = Variant::OP_BIT_NEGATE;
1038
break;
1039
default: {
1040
}
1041
}
1042
1043
if (op == Variant::OP_MAX) { //stop appending stuff
1044
str_ofs = cofs;
1045
break;
1046
}
1047
1048
//push operator and go on
1049
{
1050
ExpressionNode e;
1051
e.is_op = true;
1052
e.op = op;
1053
expression_nodes.push_back(e);
1054
}
1055
}
1056
1057
/* Reduce the set of expressions and place them in an operator tree, respecting precedence */
1058
1059
while (expression_nodes.size() > 1) {
1060
int next_op = -1;
1061
int min_priority = 0xFFFFF;
1062
bool is_unary = false;
1063
1064
for (int i = 0; i < expression_nodes.size(); i++) {
1065
if (!expression_nodes[i].is_op) {
1066
continue;
1067
}
1068
1069
int priority;
1070
1071
bool unary = false;
1072
1073
switch (expression_nodes[i].op) {
1074
case Variant::OP_POWER:
1075
priority = 0;
1076
break;
1077
case Variant::OP_BIT_NEGATE:
1078
priority = 1;
1079
unary = true;
1080
break;
1081
case Variant::OP_NEGATE:
1082
priority = 2;
1083
unary = true;
1084
break;
1085
case Variant::OP_MULTIPLY:
1086
case Variant::OP_DIVIDE:
1087
case Variant::OP_MODULE:
1088
priority = 3;
1089
break;
1090
case Variant::OP_ADD:
1091
case Variant::OP_SUBTRACT:
1092
priority = 4;
1093
break;
1094
case Variant::OP_SHIFT_LEFT:
1095
case Variant::OP_SHIFT_RIGHT:
1096
priority = 5;
1097
break;
1098
case Variant::OP_BIT_AND:
1099
priority = 6;
1100
break;
1101
case Variant::OP_BIT_XOR:
1102
priority = 7;
1103
break;
1104
case Variant::OP_BIT_OR:
1105
priority = 8;
1106
break;
1107
case Variant::OP_LESS:
1108
case Variant::OP_LESS_EQUAL:
1109
case Variant::OP_GREATER:
1110
case Variant::OP_GREATER_EQUAL:
1111
case Variant::OP_EQUAL:
1112
case Variant::OP_NOT_EQUAL:
1113
priority = 9;
1114
break;
1115
case Variant::OP_IN:
1116
priority = 11;
1117
break;
1118
case Variant::OP_NOT:
1119
priority = 12;
1120
unary = true;
1121
break;
1122
case Variant::OP_AND:
1123
priority = 13;
1124
break;
1125
case Variant::OP_OR:
1126
priority = 14;
1127
break;
1128
default: {
1129
_set_error("Parser bug, invalid operator in expression: " + itos(expression_nodes[i].op));
1130
return nullptr;
1131
}
1132
}
1133
1134
if (priority < min_priority) {
1135
// < is used for left to right (default)
1136
// <= is used for right to left
1137
1138
next_op = i;
1139
min_priority = priority;
1140
is_unary = unary;
1141
}
1142
}
1143
1144
if (next_op == -1) {
1145
_set_error("Yet another parser bug....");
1146
ERR_FAIL_V(nullptr);
1147
}
1148
1149
// OK! create operator..
1150
if (is_unary) {
1151
int expr_pos = next_op;
1152
while (expression_nodes[expr_pos].is_op) {
1153
expr_pos++;
1154
if (expr_pos == expression_nodes.size()) {
1155
//can happen..
1156
_set_error("Unexpected end of expression...");
1157
return nullptr;
1158
}
1159
}
1160
1161
//consecutively do unary operators
1162
for (int i = expr_pos - 1; i >= next_op; i--) {
1163
OperatorNode *op = alloc_node<OperatorNode>();
1164
op->op = expression_nodes[i].op;
1165
op->nodes[0] = expression_nodes[i + 1].node;
1166
op->nodes[1] = nullptr;
1167
expression_nodes.write[i].is_op = false;
1168
expression_nodes.write[i].node = op;
1169
expression_nodes.remove_at(i + 1);
1170
}
1171
1172
} else {
1173
if (next_op < 1 || next_op >= (expression_nodes.size() - 1)) {
1174
_set_error("Parser bug...");
1175
ERR_FAIL_V(nullptr);
1176
}
1177
1178
OperatorNode *op = alloc_node<OperatorNode>();
1179
op->op = expression_nodes[next_op].op;
1180
1181
if (expression_nodes[next_op - 1].is_op) {
1182
_set_error("Parser bug...");
1183
ERR_FAIL_V(nullptr);
1184
}
1185
1186
if (expression_nodes[next_op + 1].is_op) {
1187
// this is not invalid and can really appear
1188
// but it becomes invalid anyway because no binary op
1189
// can be followed by a unary op in a valid combination,
1190
// due to how precedence works, unaries will always disappear first
1191
1192
_set_error("Unexpected two consecutive operators.");
1193
return nullptr;
1194
}
1195
1196
op->nodes[0] = expression_nodes[next_op - 1].node; //expression goes as left
1197
op->nodes[1] = expression_nodes[next_op + 1].node; //next expression goes as right
1198
1199
//replace all 3 nodes by this operator and make it an expression
1200
expression_nodes.write[next_op - 1].node = op;
1201
expression_nodes.remove_at(next_op);
1202
expression_nodes.remove_at(next_op);
1203
}
1204
}
1205
1206
return expression_nodes[0].node;
1207
}
1208
1209
bool Expression::_compile_expression() {
1210
if (!expression_dirty) {
1211
return error_set;
1212
}
1213
1214
if (nodes) {
1215
memdelete(nodes);
1216
nodes = nullptr;
1217
root = nullptr;
1218
}
1219
1220
error_str = String();
1221
error_set = false;
1222
str_ofs = 0;
1223
1224
root = _parse_expression();
1225
1226
if (error_set) {
1227
root = nullptr;
1228
if (nodes) {
1229
memdelete(nodes);
1230
}
1231
nodes = nullptr;
1232
return true;
1233
}
1234
1235
expression_dirty = false;
1236
return false;
1237
}
1238
1239
bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression::ENode *p_node, Variant &r_ret, bool p_const_calls_only, String &r_error_str) {
1240
switch (p_node->type) {
1241
case Expression::ENode::TYPE_INPUT: {
1242
const Expression::InputNode *in = static_cast<const Expression::InputNode *>(p_node);
1243
if (in->index < 0 || in->index >= p_inputs.size()) {
1244
r_error_str = vformat(RTR("Invalid input %d (not passed) in expression"), in->index);
1245
return true;
1246
}
1247
r_ret = p_inputs[in->index];
1248
} break;
1249
case Expression::ENode::TYPE_CONSTANT: {
1250
const Expression::ConstantNode *c = static_cast<const Expression::ConstantNode *>(p_node);
1251
r_ret = c->value;
1252
1253
} break;
1254
case Expression::ENode::TYPE_SELF: {
1255
if (!p_instance) {
1256
r_error_str = RTR("self can't be used because instance is null (not passed)");
1257
return true;
1258
}
1259
r_ret = p_instance;
1260
} break;
1261
case Expression::ENode::TYPE_OPERATOR: {
1262
const Expression::OperatorNode *op = static_cast<const Expression::OperatorNode *>(p_node);
1263
1264
Variant a;
1265
bool ret = _execute(p_inputs, p_instance, op->nodes[0], a, p_const_calls_only, r_error_str);
1266
if (ret) {
1267
return true;
1268
}
1269
1270
Variant b;
1271
1272
if (op->nodes[1]) {
1273
ret = _execute(p_inputs, p_instance, op->nodes[1], b, p_const_calls_only, r_error_str);
1274
if (ret) {
1275
return true;
1276
}
1277
}
1278
1279
bool valid = true;
1280
Variant::evaluate(op->op, a, b, r_ret, valid);
1281
if (!valid) {
1282
r_error_str = vformat(RTR("Invalid operands to operator %s, %s and %s."), Variant::get_operator_name(op->op), Variant::get_type_name(a.get_type()), Variant::get_type_name(b.get_type()));
1283
return true;
1284
}
1285
1286
} break;
1287
case Expression::ENode::TYPE_INDEX: {
1288
const Expression::IndexNode *index = static_cast<const Expression::IndexNode *>(p_node);
1289
1290
Variant base;
1291
bool ret = _execute(p_inputs, p_instance, index->base, base, p_const_calls_only, r_error_str);
1292
if (ret) {
1293
return true;
1294
}
1295
1296
Variant idx;
1297
1298
ret = _execute(p_inputs, p_instance, index->index, idx, p_const_calls_only, r_error_str);
1299
if (ret) {
1300
return true;
1301
}
1302
1303
bool valid;
1304
r_ret = base.get(idx, &valid);
1305
if (!valid) {
1306
r_error_str = vformat(RTR("Invalid index of type %s for base type %s"), Variant::get_type_name(idx.get_type()), Variant::get_type_name(base.get_type()));
1307
return true;
1308
}
1309
1310
} break;
1311
case Expression::ENode::TYPE_NAMED_INDEX: {
1312
const Expression::NamedIndexNode *index = static_cast<const Expression::NamedIndexNode *>(p_node);
1313
1314
Variant base;
1315
bool ret = _execute(p_inputs, p_instance, index->base, base, p_const_calls_only, r_error_str);
1316
if (ret) {
1317
return true;
1318
}
1319
1320
bool valid;
1321
r_ret = base.get_named(index->name, valid);
1322
if (!valid) {
1323
r_error_str = vformat(RTR("Invalid named index '%s' for base type %s"), String(index->name), Variant::get_type_name(base.get_type()));
1324
return true;
1325
}
1326
1327
} break;
1328
case Expression::ENode::TYPE_ARRAY: {
1329
const Expression::ArrayNode *array = static_cast<const Expression::ArrayNode *>(p_node);
1330
1331
Array arr;
1332
arr.resize(array->array.size());
1333
for (int i = 0; i < array->array.size(); i++) {
1334
Variant value;
1335
bool ret = _execute(p_inputs, p_instance, array->array[i], value, p_const_calls_only, r_error_str);
1336
1337
if (ret) {
1338
return true;
1339
}
1340
arr[i] = value;
1341
}
1342
1343
r_ret = arr;
1344
1345
} break;
1346
case Expression::ENode::TYPE_DICTIONARY: {
1347
const Expression::DictionaryNode *dictionary = static_cast<const Expression::DictionaryNode *>(p_node);
1348
1349
Dictionary d;
1350
for (int i = 0; i < dictionary->dict.size(); i += 2) {
1351
Variant key;
1352
bool ret = _execute(p_inputs, p_instance, dictionary->dict[i + 0], key, p_const_calls_only, r_error_str);
1353
1354
if (ret) {
1355
return true;
1356
}
1357
1358
Variant value;
1359
ret = _execute(p_inputs, p_instance, dictionary->dict[i + 1], value, p_const_calls_only, r_error_str);
1360
if (ret) {
1361
return true;
1362
}
1363
1364
d[key] = value;
1365
}
1366
1367
r_ret = d;
1368
} break;
1369
case Expression::ENode::TYPE_CONSTRUCTOR: {
1370
const Expression::ConstructorNode *constructor = static_cast<const Expression::ConstructorNode *>(p_node);
1371
1372
Vector<Variant> arr;
1373
Vector<const Variant *> argp;
1374
arr.resize(constructor->arguments.size());
1375
argp.resize(constructor->arguments.size());
1376
1377
for (int i = 0; i < constructor->arguments.size(); i++) {
1378
Variant value;
1379
bool ret = _execute(p_inputs, p_instance, constructor->arguments[i], value, p_const_calls_only, r_error_str);
1380
1381
if (ret) {
1382
return true;
1383
}
1384
arr.write[i] = value;
1385
argp.write[i] = &arr[i];
1386
}
1387
1388
Callable::CallError ce;
1389
Variant::construct(constructor->data_type, r_ret, (const Variant **)argp.ptr(), argp.size(), ce);
1390
1391
if (ce.error != Callable::CallError::CALL_OK) {
1392
r_error_str = vformat(RTR("Invalid arguments to construct '%s'"), Variant::get_type_name(constructor->data_type));
1393
return true;
1394
}
1395
1396
} break;
1397
case Expression::ENode::TYPE_BUILTIN_FUNC: {
1398
const Expression::BuiltinFuncNode *bifunc = static_cast<const Expression::BuiltinFuncNode *>(p_node);
1399
1400
Vector<Variant> arr;
1401
Vector<const Variant *> argp;
1402
arr.resize(bifunc->arguments.size());
1403
argp.resize(bifunc->arguments.size());
1404
1405
for (int i = 0; i < bifunc->arguments.size(); i++) {
1406
Variant value;
1407
bool ret = _execute(p_inputs, p_instance, bifunc->arguments[i], value, p_const_calls_only, r_error_str);
1408
if (ret) {
1409
return true;
1410
}
1411
arr.write[i] = value;
1412
argp.write[i] = &arr[i];
1413
}
1414
1415
r_ret = Variant(); //may not return anything
1416
Callable::CallError ce;
1417
Variant::call_utility_function(bifunc->func, &r_ret, (const Variant **)argp.ptr(), argp.size(), ce);
1418
if (ce.error != Callable::CallError::CALL_OK) {
1419
r_error_str = "Builtin call failed: " + Variant::get_call_error_text(bifunc->func, (const Variant **)argp.ptr(), argp.size(), ce);
1420
return true;
1421
}
1422
1423
} break;
1424
case Expression::ENode::TYPE_CALL: {
1425
const Expression::CallNode *call = static_cast<const Expression::CallNode *>(p_node);
1426
1427
Variant base;
1428
bool ret = _execute(p_inputs, p_instance, call->base, base, p_const_calls_only, r_error_str);
1429
1430
if (ret) {
1431
return true;
1432
}
1433
1434
Vector<Variant> arr;
1435
Vector<const Variant *> argp;
1436
arr.resize(call->arguments.size());
1437
argp.resize(call->arguments.size());
1438
1439
for (int i = 0; i < call->arguments.size(); i++) {
1440
Variant value;
1441
ret = _execute(p_inputs, p_instance, call->arguments[i], value, p_const_calls_only, r_error_str);
1442
1443
if (ret) {
1444
return true;
1445
}
1446
arr.write[i] = value;
1447
argp.write[i] = &arr[i];
1448
}
1449
1450
Callable::CallError ce;
1451
if (p_const_calls_only) {
1452
base.call_const(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce);
1453
} else {
1454
base.callp(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce);
1455
}
1456
1457
if (ce.error != Callable::CallError::CALL_OK) {
1458
r_error_str = vformat(RTR("On call to '%s':"), String(call->method));
1459
return true;
1460
}
1461
1462
} break;
1463
}
1464
return false;
1465
}
1466
1467
Error Expression::parse(const String &p_expression, const Vector<String> &p_input_names) {
1468
if (nodes) {
1469
memdelete(nodes);
1470
nodes = nullptr;
1471
root = nullptr;
1472
}
1473
1474
error_str = String();
1475
error_set = false;
1476
str_ofs = 0;
1477
input_names = p_input_names;
1478
1479
expression = p_expression;
1480
root = _parse_expression();
1481
1482
if (error_set) {
1483
root = nullptr;
1484
if (nodes) {
1485
memdelete(nodes);
1486
}
1487
nodes = nullptr;
1488
return ERR_INVALID_PARAMETER;
1489
}
1490
1491
return OK;
1492
}
1493
1494
Variant Expression::execute(const Array &p_inputs, Object *p_base, bool p_show_error, bool p_const_calls_only) {
1495
ERR_FAIL_COND_V_MSG(error_set, Variant(), vformat("There was previously a parse error: %s.", error_str));
1496
1497
execution_error = false;
1498
Variant output;
1499
String error_txt;
1500
bool err = _execute(p_inputs, p_base, root, output, p_const_calls_only, error_txt);
1501
if (err) {
1502
execution_error = true;
1503
error_str = error_txt;
1504
ERR_FAIL_COND_V_MSG(p_show_error, Variant(), error_str);
1505
}
1506
1507
return output;
1508
}
1509
1510
bool Expression::has_execute_failed() const {
1511
return execution_error;
1512
}
1513
1514
String Expression::get_error_text() const {
1515
return error_str;
1516
}
1517
1518
void Expression::_bind_methods() {
1519
ClassDB::bind_method(D_METHOD("parse", "expression", "input_names"), &Expression::parse, DEFVAL(Vector<String>()));
1520
ClassDB::bind_method(D_METHOD("execute", "inputs", "base_instance", "show_error", "const_calls_only"), &Expression::execute, DEFVAL(Array()), DEFVAL(Variant()), DEFVAL(true), DEFVAL(false));
1521
ClassDB::bind_method(D_METHOD("has_execute_failed"), &Expression::has_execute_failed);
1522
ClassDB::bind_method(D_METHOD("get_error_text"), &Expression::get_error_text);
1523
}
1524
1525
Expression::~Expression() {
1526
if (nodes) {
1527
memdelete(nodes);
1528
}
1529
}
1530
1531