2018-08-29 22:38:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*  expression.cpp                                                       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                       This file is part of:                           */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                           GODOT ENGINE                                */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                      https://godotengine.org                          */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*************************************************************************/  
						 
					
						
							
								
									
										
										
										
											2021-01-01 20:13:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */  
						 
					
						
							
								
									
										
										
										
											2018-08-29 22:38:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*                                                                       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Permission is hereby granted, free of charge, to any person obtaining */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* a copy of this software and associated documentation files (the       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* "Software"), to deal in the Software without restriction, including   */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* without limitation the rights to use, copy, modify, merge, publish,   */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* distribute, sublicense, and/or sell copies of the Software, and to    */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* permit persons to whom the Software is furnished to do so, subject to */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* the following conditions:                                             */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                                                                       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* The above copyright notice and this permission notice shall be        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* included in all copies or substantial portions of the Software.       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                                                                       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "expression.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 18:13:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/io/marshalls.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "core/math/math_funcs.h" 
  
						 
					
						
							
								
									
										
										
										
											2020-11-07 19:33:38 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/object/class_db.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "core/object/reference.h" 
  
						 
					
						
							
								
									
										
										
										
											2018-09-11 18:13:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/os/os.h" 
  
						 
					
						
							
								
									
										
										
										
											2020-11-07 19:33:38 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/variant/variant_parser.h" 
  
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  _is_number ( char32_t  c )  {  
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ( c  > =  ' 0 '  & &  c  < =  ' 9 ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								Error  Expression : : _get_token ( Token  & r_token )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++]) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										char32_t  cchar  =  GET_CHAR ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( cchar )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  0 :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_EOF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' { ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_CURLY_BRACKET_OPEN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' } ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_CURLY_BRACKET_CLOSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' [ ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_BRACKET_OPEN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' ] ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_BRACKET_CLOSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' ( ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_PARENTHESIS_OPEN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' ) ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_PARENTHESIS_CLOSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' , ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_COMMA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' : ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_COLON ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' $ ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_INPUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												int  index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												do  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! _is_number ( expression [ str_ofs ] ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														_set_error ( " Expected number after '$' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														return  ERR_PARSE_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													index  * =  10 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													index  + =  expression [ str_ofs ]  -  ' 0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  while  ( _is_number ( expression [ str_ofs ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . value  =  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' = ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cchar  =  GET_CHAR ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( cchar  = =  ' = ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_EQUAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_set_error ( " Expected '=' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  ERR_PARSE_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' ! ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( expression [ str_ofs ]  = =  ' = ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_NOT_EQUAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_NOT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' > ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( expression [ str_ofs ]  = =  ' = ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_GREATER_EQUAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( expression [ str_ofs ]  = =  ' > ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_SHIFT_RIGHT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_GREATER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' < ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( expression [ str_ofs ]  = =  ' = ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_LESS_EQUAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( expression [ str_ofs ]  = =  ' < ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_SHIFT_LEFT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_LESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' + ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_OP_ADD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' - ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_OP_SUB ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' / ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_OP_DIV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' * ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_OP_MUL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' % ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_OP_MOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' & ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( expression [ str_ofs ]  = =  ' & ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_AND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_BIT_AND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' | ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( expression [ str_ofs ]  = =  ' | ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_OR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_OP_BIT_OR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' ^ ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_OP_BIT_XOR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' ~ ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_OP_BIT_INVERT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-02 02:02:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  ' \' ' : 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  ' " ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												String  str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												while  ( true )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													char32_t  ch  =  GET_CHAR ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ch  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														_set_error ( " Unterminated String " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														return  ERR_PARSE_ERROR ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-02 02:02:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													}  else  if  ( ch  = =  cchar )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														// cchar contain a corresponding quote symbol
 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( ch  = =  ' \\ ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														//escaped characters...
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														char32_t  next  =  GET_CHAR ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														if  ( next  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															_set_error ( " Unterminated String " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															r_token . type  =  TK_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															return  ERR_PARSE_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														char32_t  res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														switch  ( next )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-10 13:00:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															case  ' b ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																res  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															case  ' t ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																res  =  9 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															case  ' n ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																res  =  10 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															case  ' f ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																res  =  12 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															case  ' r ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																res  =  13 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																break ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															case  ' u ' :  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-13 11:37:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																// hex number
 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
																for  ( int  j  =  0 ;  j  <  4 ;  j + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																	char32_t  c  =  GET_CHAR ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	if  ( c  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																		_set_error ( " Unterminated String " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																		r_token . type  =  TK_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																		return  ERR_PARSE_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																	if  ( ! ( _is_number ( c )  | |  ( c  > =  ' a '  & &  c  < =  ' f ' )  | |  ( c  > =  ' A '  & &  c  < =  ' F ' ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
																		_set_error ( " Malformed hex constant in string " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																		r_token . type  =  TK_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																		return  ERR_PARSE_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	} 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																	char32_t  v ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																	if  ( _is_number ( c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
																		v  =  c  -  ' 0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	}  else  if  ( c  > =  ' a '  & &  c  < =  ' f ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																		v  =  c  -  ' a ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																		v  + =  10 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	}  else  if  ( c  > =  ' A '  & &  c  < =  ' F ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																		v  =  c  -  ' A ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																		v  + =  10 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-13 11:37:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																		ERR_PRINT ( " Bug parsing hex constant. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
																		v  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	res  < < =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	res  | =  v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															default :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																res  =  next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														str  + =  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														str  + =  ch ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . type  =  TK_CONSTANT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_token . value  =  str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( cchar  < =  32 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												char32_t  next_char  =  ( str_ofs  > =  expression . length ( ) )  ?  0  :  expression [ str_ofs ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( _is_number ( cchar )  | |  ( cchar  = =  ' . '  & &  _is_number ( next_char ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													//a number
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													String  num ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define READING_SIGN 0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define READING_INT 1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define READING_DEC 2 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define READING_EXP 3 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define READING_DONE 4 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													int  reading  =  READING_INT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													char32_t  c  =  cchar ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													bool  exp_sign  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bool  exp_beg  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bool  is_float  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														switch  ( reading )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															case  READING_INT :  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																if  ( _is_number ( c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
																	//pass
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																}  else  if  ( c  = =  ' . ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	reading  =  READING_DEC ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	is_float  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																}  else  if  ( c  = =  ' e ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	reading  =  READING_EXP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	reading  =  READING_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															case  READING_DEC :  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																if  ( _is_number ( c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
																}  else  if  ( c  = =  ' e ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	reading  =  READING_EXP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	reading  =  READING_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															case  READING_EXP :  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																if  ( _is_number ( c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
																	exp_beg  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																}  else  if  ( ( c  = =  ' - '  | |  c  = =  ' + ' )  & &  ! exp_sign  & &  ! exp_beg )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																	if  ( c  = =  ' - ' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
																		is_float  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																	} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
																	exp_sign  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																	reading  =  READING_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( reading  = =  READING_DONE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														num  + =  String : : chr ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														c  =  GET_CHAR ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_CONSTANT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( is_float )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 14:07:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														r_token . value  =  num . to_float ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-13 05:31:51 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														r_token . value  =  num . to_int ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ( cchar  > =  ' A '  & &  cchar  < =  ' Z ' )  | |  ( cchar  > =  ' a '  & &  cchar  < =  ' z ' )  | |  cchar  = =  ' _ ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													String  id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bool  first  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													while  ( ( cchar  > =  ' A '  & &  cchar  < =  ' Z ' )  | |  ( cchar  > =  ' a '  & &  cchar  < =  ' z ' )  | |  cchar  = =  ' _ '  | |  ( ! first  & &  _is_number ( cchar ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														id  + =  String : : chr ( cchar ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														cchar  =  GET_CHAR ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														first  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs - - ;  //go back one
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( id  = =  " in " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_OP_IN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( id  = =  " null " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_CONSTANT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . value  =  Variant ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( id  = =  " true " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_CONSTANT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . value  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( id  = =  " false " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_CONSTANT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . value  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( id  = =  " PI " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_CONSTANT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . value  =  Math_PI ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( id  = =  " TAU " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_CONSTANT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . value  =  Math_TAU ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( id  = =  " INF " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_CONSTANT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . value  =  Math_INF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( id  = =  " NAN " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_CONSTANT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . value  =  Math_NAN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( id  = =  " not " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_OP_NOT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( id  = =  " or " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_OP_OR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( id  = =  " and " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_OP_AND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( id  = =  " self " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_SELF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-11 13:16:08 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( Variant : : has_utility_function ( id ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															r_token . type  =  TK_BUILTIN_FUNC ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 18:31:33 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															r_token . value  =  id ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . type  =  TK_IDENTIFIER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_token . value  =  id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( cchar  = =  ' . ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// Handled down there as we support '.[0-9]' as numbers above
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_PERIOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_set_error ( " Unexpected character. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_token . type  =  TK_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  ERR_PARSE_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-01 16:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# undef GET_CHAR 
  
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r_token . type  =  TK_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ERR_PARSE_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  char  * Expression : : token_name [ TK_MAX ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" CURLY BRACKET OPEN " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" CURLY BRACKET CLOSE " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" BRACKET OPEN " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" BRACKET CLOSE " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" PARENTHESIS OPEN " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" PARENTHESIS CLOSE " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" IDENTIFIER " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" BUILTIN FUNC " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" SELF " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" CONSTANT " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" BASIC TYPE " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" COLON " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" COMMA " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" PERIOD " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP IN " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP EQUAL " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP NOT EQUAL " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP LESS " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP LESS EQUAL " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP GREATER " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP GREATER EQUAL " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP AND " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP OR " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP NOT " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP ADD " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP SUB " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP MUL " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP DIV " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP MOD " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP SHIFT LEFT " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP SHIFT RIGHT " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP BIT AND " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP BIT OR " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP BIT XOR " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP BIT INVERT " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" OP INPUT " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" EOF " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" ERROR " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Expression : : ENode  * Expression : : _parse_expression ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Vector < ExpressionNode >  expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//keep appending stuff to expression
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ENode  * expr  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Token  tk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_get_token ( tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( error_set )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( tk . type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_CURLY_BRACKET_OPEN :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//a dictionary
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												DictionaryNode  * dn  =  alloc_node < DictionaryNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													int  cofs  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  = =  TK_CURLY_BRACKET_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs  =  cofs ;  //revert
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													//parse an expression
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ENode  * subexpr  =  _parse_expression ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! subexpr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													dn - > dict . push_back ( subexpr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  ! =  TK_COLON )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														_set_error ( " Expected ':' " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													subexpr  =  _parse_expression ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! subexpr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													dn - > dict . push_back ( subexpr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													cofs  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  = =  TK_COMMA )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														//all good
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( tk . type  = =  TK_CURLY_BRACKET_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														str_ofs  =  cofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														_set_error ( " Expected ',' or '}' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expr  =  dn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_BRACKET_OPEN :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//an array
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ArrayNode  * an  =  alloc_node < ArrayNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													int  cofs  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  = =  TK_BRACKET_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs  =  cofs ;  //revert
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													//parse an expression
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ENode  * subexpr  =  _parse_expression ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! subexpr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													an - > array . push_back ( subexpr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													cofs  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  = =  TK_COMMA )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														//all good
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( tk . type  = =  TK_BRACKET_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														str_ofs  =  cofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														_set_error ( " Expected ',' or ']' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expr  =  an ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_PARENTHESIS_OPEN :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//a suexpression
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ENode  * e  =  _parse_expression ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( error_set )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( tk . type  ! =  TK_PARENTHESIS_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_set_error ( " Expected ')' " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expr  =  e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_IDENTIFIER :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												String  identifier  =  tk . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												int  cofs  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( tk . type  = =  TK_PARENTHESIS_OPEN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													//function call
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													CallNode  * func_call  =  alloc_node < CallNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													func_call - > method  =  identifier ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													SelfNode  * self_node  =  alloc_node < SelfNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													func_call - > base  =  self_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													while  ( true )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														int  cofs2  =  str_ofs ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( tk . type  = =  TK_PARENTHESIS_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														str_ofs  =  cofs2 ;  //revert
 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														//parse an expression
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ENode  * subexpr  =  _parse_expression ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( ! subexpr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														func_call - > arguments . push_back ( subexpr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														cofs2  =  str_ofs ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( tk . type  = =  TK_COMMA )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															//all good
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														}  else  if  ( tk . type  = =  TK_PARENTHESIS_CLOSE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															str_ofs  =  cofs2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															_set_error ( " Expected ',' or ')' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													expr  =  func_call ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													//named indexing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs  =  cofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:47:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													int  input_index  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													for  ( int  i  =  0 ;  i  <  input_names . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( input_names [ i ]  = =  identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															input_index  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( input_index  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														InputNode  * input  =  alloc_node < InputNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														input - > index  =  input_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														expr  =  input ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														NamedIndexNode  * index  =  alloc_node < NamedIndexNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														SelfNode  * self_node  =  alloc_node < SelfNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														index - > base  =  self_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														index - > name  =  identifier ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														expr  =  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_INPUT :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												InputNode  * input  =  alloc_node < InputNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												input - > index  =  tk . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expr  =  input ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_SELF :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												SelfNode  * self  =  alloc_node < SelfNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expr  =  self ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_CONSTANT :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ConstantNode  * constant  =  alloc_node < ConstantNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												constant - > value  =  tk . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expr  =  constant ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_BASIC_TYPE :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//constructor..
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Variant : : Type  bt  =  Variant : : Type ( int ( tk . value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( tk . type  ! =  TK_PARENTHESIS_OPEN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_set_error ( " Expected '(' " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ConstructorNode  * constructor  =  alloc_node < ConstructorNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												constructor - > data_type  =  bt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													int  cofs  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  = =  TK_PARENTHESIS_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs  =  cofs ;  //revert
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													//parse an expression
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ENode  * subexpr  =  _parse_expression ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! subexpr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													constructor - > arguments . push_back ( subexpr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													cofs  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  = =  TK_COMMA )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														//all good
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( tk . type  = =  TK_PARENTHESIS_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														str_ofs  =  cofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														_set_error ( " Expected ',' or ')' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expr  =  constructor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_BUILTIN_FUNC :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//builtin function
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 18:31:33 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												StringName  func  =  tk . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( tk . type  ! =  TK_PARENTHESIS_OPEN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_set_error ( " Expected '(' " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BuiltinFuncNode  * bifunc  =  alloc_node < BuiltinFuncNode > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 18:31:33 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bifunc - > func  =  func ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													int  cofs  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  = =  TK_PARENTHESIS_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs  =  cofs ;  //revert
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													//parse an expression
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ENode  * subexpr  =  _parse_expression ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! subexpr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													bifunc - > arguments . push_back ( subexpr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													cofs  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  = =  TK_COMMA )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														//all good
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( tk . type  = =  TK_PARENTHESIS_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														str_ofs  =  cofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														_set_error ( " Expected ',' or ')' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-11 13:16:08 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! Variant : : is_utility_function_vararg ( bifunc - > func ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													int  expected_args  =  Variant : : get_utility_function_argument_count ( bifunc - > func ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 18:31:33 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( expected_args  ! =  bifunc - > arguments . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														_set_error ( " Builtin func ' "  +  String ( bifunc - > func )  +  " ' expects  "  +  itos ( expected_args )  +  "  arguments. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expr  =  bifunc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_SUB :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ExpressionNode  e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												e . is_op  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												e . op  =  Variant : : OP_NEGATE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expression . push_back ( e ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_NOT :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ExpressionNode  e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												e . is_op  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												e . op  =  Variant : : OP_NOT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expression . push_back ( e ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_set_error ( " Expected expression. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//before going to operators, must check indexing!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  cofs2  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_get_token ( tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( error_set )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bool  done  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  ( tk . type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  TK_BRACKET_OPEN :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													//value indexing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													IndexNode  * index  =  alloc_node < IndexNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													index - > base  =  expr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ENode  * what  =  _parse_expression ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! what )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													index - > index  =  what ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  ! =  TK_BRACKET_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														_set_error ( " Expected ']' at end of index. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													expr  =  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  TK_PERIOD :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													//named indexing or function call
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  ! =  TK_IDENTIFIER )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														_set_error ( " Expected identifier after '.' " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													StringName  identifier  =  tk . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													int  cofs  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( tk . type  = =  TK_PARENTHESIS_OPEN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														//function call
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														CallNode  * func_call  =  alloc_node < CallNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														func_call - > method  =  identifier ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														func_call - > base  =  expr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														while  ( true )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															int  cofs3  =  str_ofs ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															if  ( tk . type  = =  TK_PARENTHESIS_CLOSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															str_ofs  =  cofs3 ;  //revert
 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															//parse an expression
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															ENode  * subexpr  =  _parse_expression ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															if  ( ! subexpr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															func_call - > arguments . push_back ( subexpr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															cofs3  =  str_ofs ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															_get_token ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															if  ( tk . type  = =  TK_COMMA )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																//all good
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															}  else  if  ( tk . type  = =  TK_PARENTHESIS_CLOSE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																str_ofs  =  cofs3 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																_set_error ( " Expected ',' or ')' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														expr  =  func_call ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														//named indexing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														str_ofs  =  cofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														NamedIndexNode  * index  =  alloc_node < NamedIndexNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														index - > base  =  expr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														index - > name  =  identifier ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														expr  =  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												default :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													str_ofs  =  cofs2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													done  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( done )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//push expression
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ExpressionNode  e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											e . is_op  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											e . node  =  expr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expression . push_back ( e ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//ok finally look for an operator
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  cofs  =  str_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_get_token ( tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( error_set )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Variant : : Operator  op  =  Variant : : OP_MAX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( tk . type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-10 13:00:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  TK_OP_IN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_IN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_EQUAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_NOT_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_NOT_EQUAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_LESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_LESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_LESS_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_LESS_EQUAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_GREATER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_GREATER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_GREATER_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_GREATER_EQUAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_AND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_AND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_OR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_OR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_NOT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_NOT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_ADD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_ADD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_SUB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_SUBTRACT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_MUL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_MULTIPLY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_DIV : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_DIVIDE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_MOD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_MODULE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_SHIFT_LEFT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_SHIFT_LEFT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_SHIFT_RIGHT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_SHIFT_RIGHT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_BIT_AND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_BIT_AND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_BIT_OR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_BIT_OR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_BIT_XOR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_BIT_XOR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  TK_OP_BIT_INVERT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op  =  Variant : : OP_BIT_NEGATE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 17:08:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											default :  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 15:46:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( op  = =  Variant : : OP_MAX )  {  //stop appending stuff
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											str_ofs  =  cofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//push operator and go on
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ExpressionNode  e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											e . is_op  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											e . op  =  op ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expression . push_back ( e ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 19:05:16 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Reduce the set of expressions and place them in an operator tree, respecting precedence */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( expression . size ( )  >  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  next_op  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  min_priority  =  0xFFFFF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bool  is_unary  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( int  i  =  0 ;  i  <  expression . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! expression [ i ] . is_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  priority ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bool  unary  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  ( expression [ i ] . op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_BIT_NEGATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													unary  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_NEGATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													unary  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-10 13:00:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												case  Variant : : OP_MULTIPLY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_DIVIDE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_MODULE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_ADD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_SUBTRACT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_SHIFT_LEFT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_SHIFT_RIGHT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_BIT_AND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_BIT_XOR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  6 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_BIT_OR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  7 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_LESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_LESS_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_GREATER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_GREATER_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_NOT_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_IN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  10 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_NOT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  11 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													unary  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-10 13:00:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												case  Variant : : OP_AND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  12 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  Variant : : OP_OR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													priority  =  13 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												default :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_set_error ( " Parser bug, invalid operator in expression:  "  +  itos ( expression [ i ] . op ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( priority  <  min_priority )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// < is used for left to right (default)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// <= is used for right to left
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												next_op  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												min_priority  =  priority ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												is_unary  =  unary ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( next_op  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_set_error ( " Yet another parser bug.... " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_V ( nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// OK! create operator..
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( is_unary )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  expr_pos  =  next_op ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											while  ( expression [ expr_pos ] . is_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expr_pos + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( expr_pos  = =  expression . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													//can happen..
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													_set_error ( " Unexpected end of expression... " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 13:59:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											//consecutively do unary operators
 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  expr_pos  -  1 ;  i  > =  next_op ;  i - - )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												OperatorNode  * op  =  alloc_node < OperatorNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op - > op  =  expression [ i ] . op ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												op - > nodes [ 0 ]  =  expression [ i  +  1 ] . node ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												op - > nodes [ 1 ]  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												expression . write [ i ] . is_op  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expression . write [ i ] . node  =  op ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expression . remove ( i  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( next_op  <  1  | |  next_op  > =  ( expression . size ( )  -  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_set_error ( " Parser bug... " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ERR_FAIL_V ( nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											OperatorNode  * op  =  alloc_node < OperatorNode > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											op - > op  =  expression [ next_op ] . op ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( expression [ next_op  -  1 ] . is_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_set_error ( " Parser bug... " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ERR_FAIL_V ( nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( expression [ next_op  +  1 ] . is_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// this is not invalid and can really appear
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// but it becomes invalid anyway because no binary op
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// can be followed by a unary op in a valid combination,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// due to how precedence works, unaries will always disappear first
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_set_error ( " Unexpected two consecutive operators. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											op - > nodes [ 0 ]  =  expression [ next_op  -  1 ] . node ;  //expression goes as left
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											op - > nodes [ 1 ]  =  expression [ next_op  +  1 ] . node ;  //next expression goes as right
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											//replace all 3 nodes by this operator and make it an expression
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expression . write [ next_op  -  1 ] . node  =  op ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expression . remove ( next_op ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expression . remove ( next_op ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  expression [ 0 ] . node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  Expression : : _compile_expression ( )  {  
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! expression_dirty )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  error_set ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nodes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memdelete ( nodes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										nodes  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										root  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									error_str  =  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									error_set  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									str_ofs  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									root  =  _parse_expression ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( error_set )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										root  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( nodes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memdelete ( nodes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										nodes  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									expression_dirty  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  Expression : : _execute ( const  Array  & p_inputs ,  Object  * p_instance ,  Expression : : ENode  * p_node ,  Variant  & r_ret ,  String  & r_error_str )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( p_node - > type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Expression : : ENode : : TYPE_INPUT :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  Expression : : InputNode  * in  =  static_cast < const  Expression : : InputNode  * > ( p_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( in - > index  <  0  | |  in - > index  > =  p_inputs . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_error_str  =  vformat ( RTR ( " Invalid input %i (not passed) in expression " ) ,  in - > index ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_ret  =  p_inputs [ in - > index ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Expression : : ENode : : TYPE_CONSTANT :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  Expression : : ConstantNode  * c  =  static_cast < const  Expression : : ConstantNode  * > ( p_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_ret  =  c - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Expression : : ENode : : TYPE_SELF :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! p_instance )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_error_str  =  RTR ( " self can't be used because instance is null (not passed) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_ret  =  p_instance ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Expression : : ENode : : TYPE_OPERATOR :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  Expression : : OperatorNode  * op  =  static_cast < const  Expression : : OperatorNode  * > ( p_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Variant  a ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bool  ret  =  _execute ( p_inputs ,  p_instance ,  op - > nodes [ 0 ] ,  a ,  r_error_str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Variant  b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( op - > nodes [ 1 ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ret  =  _execute ( p_inputs ,  p_instance ,  op - > nodes [ 1 ] ,  b ,  r_error_str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bool  valid  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Variant : : evaluate ( op - > op ,  a ,  b ,  r_ret ,  valid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! valid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												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 ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Expression : : ENode : : TYPE_INDEX :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  Expression : : IndexNode  * index  =  static_cast < const  Expression : : IndexNode  * > ( p_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Variant  base ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bool  ret  =  _execute ( p_inputs ,  p_instance ,  index - > base ,  base ,  r_error_str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Variant  idx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ret  =  _execute ( p_inputs ,  p_instance ,  index - > index ,  idx ,  r_error_str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bool  valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_ret  =  base . get ( idx ,  & valid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! valid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												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 ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Expression : : ENode : : TYPE_NAMED_INDEX :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  Expression : : NamedIndexNode  * index  =  static_cast < const  Expression : : NamedIndexNode  * > ( p_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Variant  base ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bool  ret  =  _execute ( p_inputs ,  p_instance ,  index - > base ,  base ,  r_error_str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bool  valid ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-06 22:29:22 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_ret  =  base . get_named ( index - > name ,  valid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( ! valid )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-22 04:58:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_error_str  =  vformat ( RTR ( " Invalid named index '%s' for base type %s " ) ,  String ( index - > name ) ,  Variant : : get_type_name ( base . get_type ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Expression : : ENode : : TYPE_ARRAY :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  Expression : : ArrayNode  * array  =  static_cast < const  Expression : : ArrayNode  * > ( p_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Array  arr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arr . resize ( array - > array . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  array - > array . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Variant  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bool  ret  =  _execute ( p_inputs ,  p_instance ,  array - > array [ i ] ,  value ,  r_error_str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												arr [ i ]  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_ret  =  arr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Expression : : ENode : : TYPE_DICTIONARY :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  Expression : : DictionaryNode  * dictionary  =  static_cast < const  Expression : : DictionaryNode  * > ( p_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Dictionary  d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  dictionary - > dict . size ( ) ;  i  + =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Variant  key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bool  ret  =  _execute ( p_inputs ,  p_instance ,  dictionary - > dict [ i  +  0 ] ,  key ,  r_error_str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Variant  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  =  _execute ( p_inputs ,  p_instance ,  dictionary - > dict [ i  +  1 ] ,  value ,  r_error_str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												d [ key ]  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_ret  =  d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Expression : : ENode : : TYPE_CONSTRUCTOR :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  Expression : : ConstructorNode  * constructor  =  static_cast < const  Expression : : ConstructorNode  * > ( p_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector < Variant >  arr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector < const  Variant  * >  argp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arr . resize ( constructor - > arguments . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											argp . resize ( constructor - > arguments . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  constructor - > arguments . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Variant  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bool  ret  =  _execute ( p_inputs ,  p_instance ,  constructor - > arguments [ i ] ,  value ,  r_error_str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												arr . write [ i ]  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												argp . write [ i ]  =  & arr [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-19 16:27:19 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Callable : : CallError  ce ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-09 00:19:09 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Variant : : construct ( constructor - > data_type ,  r_ret ,  ( const  Variant  * * ) argp . ptr ( ) ,  argp . size ( ) ,  ce ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-19 16:27:19 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ce . error  ! =  Callable : : CallError : : CALL_OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												r_error_str  =  vformat ( RTR ( " Invalid arguments to construct '%s' " ) ,  Variant : : get_type_name ( constructor - > data_type ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Expression : : ENode : : TYPE_BUILTIN_FUNC :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  Expression : : BuiltinFuncNode  * bifunc  =  static_cast < const  Expression : : BuiltinFuncNode  * > ( p_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector < Variant >  arr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector < const  Variant  * >  argp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arr . resize ( bifunc - > arguments . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											argp . resize ( bifunc - > arguments . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  bifunc - > arguments . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Variant  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bool  ret  =  _execute ( p_inputs ,  p_instance ,  bifunc - > arguments [ i ] ,  value ,  r_error_str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												arr . write [ i ]  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												argp . write [ i ]  =  & arr [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 18:31:33 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_ret  =  Variant ( ) ;  //may not return anything
 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-19 16:27:19 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Callable : : CallError  ce ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-11 13:16:08 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Variant : : call_utility_function ( bifunc - > func ,  & r_ret ,  ( const  Variant  * * ) argp . ptr ( ) ,  argp . size ( ) ,  ce ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-19 16:27:19 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ce . error  ! =  Callable : : CallError : : CALL_OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 18:31:33 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_error_str  =  " Builtin Call Failed.  "  +  Variant : : get_call_error_text ( bifunc - > func ,  ( const  Variant  * * ) argp . ptr ( ) ,  argp . size ( ) ,  ce ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Expression : : ENode : : TYPE_CALL :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  Expression : : CallNode  * call  =  static_cast < const  Expression : : CallNode  * > ( p_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Variant  base ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bool  ret  =  _execute ( p_inputs ,  p_instance ,  call - > base ,  base ,  r_error_str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector < Variant >  arr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector < const  Variant  * >  argp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arr . resize ( call - > arguments . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											argp . resize ( call - > arguments . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  call - > arguments . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Variant  value ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ret  =  _execute ( p_inputs ,  p_instance ,  call - > arguments [ i ] ,  value ,  r_error_str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-14 16:41:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												arr . write [ i ]  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												argp . write [ i ]  =  & arr [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-19 16:27:19 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Callable : : CallError  ce ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-11 13:16:08 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											base . call ( call - > method ,  ( const  Variant  * * ) argp . ptr ( ) ,  argp . size ( ) ,  r_ret ,  ce ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-19 16:27:19 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ce . error  ! =  Callable : : CallError : : CALL_OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												r_error_str  =  vformat ( RTR ( " On call to '%s': " ) ,  String ( call - > method ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:47:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  Expression : : parse ( const  String  & p_expression ,  const  Vector < String >  & p_input_names )  {  
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( nodes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memdelete ( nodes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										nodes  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										root  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									error_str  =  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									error_set  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									str_ofs  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:47:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									input_names  =  p_input_names ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									expression  =  p_expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									root  =  _parse_expression ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( error_set )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										root  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( nodes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memdelete ( nodes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										nodes  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  ERR_INVALID_PARAMETER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Variant  Expression : : execute ( Array  p_inputs ,  Object  * p_base ,  bool  p_show_error )  {  
						 
					
						
							
								
									
										
										
										
											2019-08-14 20:57:49 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( error_set ,  Variant ( ) ,  " There was previously a parse error:  "  +  error_str  +  " . " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									execution_error  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Variant  output ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  error_txt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  err  =  _execute ( p_inputs ,  p_base ,  root ,  output ,  error_txt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										execution_error  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										error_str  =  error_txt ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-14 20:57:49 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( p_show_error ,  Variant ( ) ,  error_str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  output ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  Expression : : has_execute_failed ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  execution_error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  Expression : : get_error_text ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  error_str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Expression : : _bind_methods ( )  {  
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:47:51 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ClassDB : : bind_method ( D_METHOD ( " parse " ,  " expression " ,  " input_names " ) ,  & Expression : : parse ,  DEFVAL ( Vector < String > ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-09 08:50:06 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ClassDB : : bind_method ( D_METHOD ( " execute " ,  " inputs " ,  " base_instance " ,  " show_error " ) ,  & Expression : : execute ,  DEFVAL ( Array ( ) ) ,  DEFVAL ( Variant ( ) ) ,  DEFVAL ( true ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-08 17:34:24 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ClassDB : : bind_method ( D_METHOD ( " has_execute_failed " ) ,  & Expression : : has_execute_failed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ClassDB : : bind_method ( D_METHOD ( " get_error_text " ) ,  & Expression : : get_error_text ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Expression : : ~ Expression ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nodes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memdelete ( nodes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}