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