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