mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 13:41:03 +00:00 
			
		
		
		
	
		
			
	
	
		
			324 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			324 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|   | #ifndef EXPRESSION_H
 | ||
|  | #define EXPRESSION_H
 | ||
|  | 
 | ||
|  | #include "core/reference.h"
 | ||
|  | 
 | ||
|  | class Expression : public Reference { | ||
|  | 	GDCLASS(Expression, Reference) | ||
|  | public: | ||
|  | 	enum BuiltinFunc { | ||
|  | 		MATH_SIN, | ||
|  | 		MATH_COS, | ||
|  | 		MATH_TAN, | ||
|  | 		MATH_SINH, | ||
|  | 		MATH_COSH, | ||
|  | 		MATH_TANH, | ||
|  | 		MATH_ASIN, | ||
|  | 		MATH_ACOS, | ||
|  | 		MATH_ATAN, | ||
|  | 		MATH_ATAN2, | ||
|  | 		MATH_SQRT, | ||
|  | 		MATH_FMOD, | ||
|  | 		MATH_FPOSMOD, | ||
|  | 		MATH_FLOOR, | ||
|  | 		MATH_CEIL, | ||
|  | 		MATH_ROUND, | ||
|  | 		MATH_ABS, | ||
|  | 		MATH_SIGN, | ||
|  | 		MATH_POW, | ||
|  | 		MATH_LOG, | ||
|  | 		MATH_EXP, | ||
|  | 		MATH_ISNAN, | ||
|  | 		MATH_ISINF, | ||
|  | 		MATH_EASE, | ||
|  | 		MATH_DECIMALS, | ||
|  | 		MATH_STEPIFY, | ||
|  | 		MATH_LERP, | ||
|  | 		MATH_INVERSE_LERP, | ||
|  | 		MATH_RANGE_LERP, | ||
|  | 		MATH_DECTIME, | ||
|  | 		MATH_RANDOMIZE, | ||
|  | 		MATH_RAND, | ||
|  | 		MATH_RANDF, | ||
|  | 		MATH_RANDOM, | ||
|  | 		MATH_SEED, | ||
|  | 		MATH_RANDSEED, | ||
|  | 		MATH_DEG2RAD, | ||
|  | 		MATH_RAD2DEG, | ||
|  | 		MATH_LINEAR2DB, | ||
|  | 		MATH_DB2LINEAR, | ||
|  | 		MATH_POLAR2CARTESIAN, | ||
|  | 		MATH_CARTESIAN2POLAR, | ||
|  | 		MATH_WRAP, | ||
|  | 		MATH_WRAPF, | ||
|  | 		LOGIC_MAX, | ||
|  | 		LOGIC_MIN, | ||
|  | 		LOGIC_CLAMP, | ||
|  | 		LOGIC_NEAREST_PO2, | ||
|  | 		OBJ_WEAKREF, | ||
|  | 		FUNC_FUNCREF, | ||
|  | 		TYPE_CONVERT, | ||
|  | 		TYPE_OF, | ||
|  | 		TYPE_EXISTS, | ||
|  | 		TEXT_CHAR, | ||
|  | 		TEXT_STR, | ||
|  | 		TEXT_PRINT, | ||
|  | 		TEXT_PRINTERR, | ||
|  | 		TEXT_PRINTRAW, | ||
|  | 		VAR_TO_STR, | ||
|  | 		STR_TO_VAR, | ||
|  | 		VAR_TO_BYTES, | ||
|  | 		BYTES_TO_VAR, | ||
|  | 		COLORN, | ||
|  | 		FUNC_MAX | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	static int get_func_argument_count(BuiltinFunc p_func); | ||
|  | 	static String get_func_name(BuiltinFunc p_func); | ||
|  | 	static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Variant::CallError &r_error, String &r_error_str); | ||
|  | 	static BuiltinFunc find_function(const String &p_string); | ||
|  | 
 | ||
|  | private: | ||
|  | 	static const char *func_name[FUNC_MAX]; | ||
|  | 
 | ||
|  | 	struct Input { | ||
|  | 
 | ||
|  | 		Variant::Type type; | ||
|  | 		String name; | ||
|  | 
 | ||
|  | 		Input() { type = Variant::NIL; } | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	Vector<Input> inputs; | ||
|  | 	Variant::Type output_type; | ||
|  | 
 | ||
|  | 	String expression; | ||
|  | 
 | ||
|  | 	bool sequenced; | ||
|  | 	int str_ofs; | ||
|  | 	bool expression_dirty; | ||
|  | 
 | ||
|  | 	bool _compile_expression(); | ||
|  | 
 | ||
|  | 	enum TokenType { | ||
|  | 		TK_CURLY_BRACKET_OPEN, | ||
|  | 		TK_CURLY_BRACKET_CLOSE, | ||
|  | 		TK_BRACKET_OPEN, | ||
|  | 		TK_BRACKET_CLOSE, | ||
|  | 		TK_PARENTHESIS_OPEN, | ||
|  | 		TK_PARENTHESIS_CLOSE, | ||
|  | 		TK_IDENTIFIER, | ||
|  | 		TK_BUILTIN_FUNC, | ||
|  | 		TK_SELF, | ||
|  | 		TK_CONSTANT, | ||
|  | 		TK_BASIC_TYPE, | ||
|  | 		TK_COLON, | ||
|  | 		TK_COMMA, | ||
|  | 		TK_PERIOD, | ||
|  | 		TK_OP_IN, | ||
|  | 		TK_OP_EQUAL, | ||
|  | 		TK_OP_NOT_EQUAL, | ||
|  | 		TK_OP_LESS, | ||
|  | 		TK_OP_LESS_EQUAL, | ||
|  | 		TK_OP_GREATER, | ||
|  | 		TK_OP_GREATER_EQUAL, | ||
|  | 		TK_OP_AND, | ||
|  | 		TK_OP_OR, | ||
|  | 		TK_OP_NOT, | ||
|  | 		TK_OP_ADD, | ||
|  | 		TK_OP_SUB, | ||
|  | 		TK_OP_MUL, | ||
|  | 		TK_OP_DIV, | ||
|  | 		TK_OP_MOD, | ||
|  | 		TK_OP_SHIFT_LEFT, | ||
|  | 		TK_OP_SHIFT_RIGHT, | ||
|  | 		TK_OP_BIT_AND, | ||
|  | 		TK_OP_BIT_OR, | ||
|  | 		TK_OP_BIT_XOR, | ||
|  | 		TK_OP_BIT_INVERT, | ||
|  | 		TK_INPUT, | ||
|  | 		TK_EOF, | ||
|  | 		TK_ERROR, | ||
|  | 		TK_MAX | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	static const char *token_name[TK_MAX]; | ||
|  | 	struct Token { | ||
|  | 
 | ||
|  | 		TokenType type; | ||
|  | 		Variant value; | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	void _set_error(const String &p_err) { | ||
|  | 		if (error_set) | ||
|  | 			return; | ||
|  | 		error_str = p_err; | ||
|  | 		error_set = true; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	Error _get_token(Token &r_token); | ||
|  | 
 | ||
|  | 	String error_str; | ||
|  | 	bool error_set; | ||
|  | 
 | ||
|  | 	struct ENode { | ||
|  | 
 | ||
|  | 		enum Type { | ||
|  | 			TYPE_INPUT, | ||
|  | 			TYPE_CONSTANT, | ||
|  | 			TYPE_SELF, | ||
|  | 			TYPE_OPERATOR, | ||
|  | 			TYPE_INDEX, | ||
|  | 			TYPE_NAMED_INDEX, | ||
|  | 			TYPE_ARRAY, | ||
|  | 			TYPE_DICTIONARY, | ||
|  | 			TYPE_CONSTRUCTOR, | ||
|  | 			TYPE_BUILTIN_FUNC, | ||
|  | 			TYPE_CALL | ||
|  | 		}; | ||
|  | 
 | ||
|  | 		ENode *next; | ||
|  | 
 | ||
|  | 		Type type; | ||
|  | 
 | ||
|  | 		ENode() { next = NULL; } | ||
|  | 		virtual ~ENode() { | ||
|  | 			if (next) { | ||
|  | 				memdelete(next); | ||
|  | 			} | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	struct ExpressionNode { | ||
|  | 
 | ||
|  | 		bool is_op; | ||
|  | 		union { | ||
|  | 			Variant::Operator op; | ||
|  | 			ENode *node; | ||
|  | 		}; | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	ENode *_parse_expression(); | ||
|  | 
 | ||
|  | 	struct InputNode : public ENode { | ||
|  | 
 | ||
|  | 		int index; | ||
|  | 		InputNode() { | ||
|  | 			type = TYPE_INPUT; | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	struct ConstantNode : public ENode { | ||
|  | 
 | ||
|  | 		Variant value; | ||
|  | 		ConstantNode() { | ||
|  | 			type = TYPE_CONSTANT; | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	struct OperatorNode : public ENode { | ||
|  | 
 | ||
|  | 		Variant::Operator op; | ||
|  | 
 | ||
|  | 		ENode *nodes[2]; | ||
|  | 
 | ||
|  | 		OperatorNode() { | ||
|  | 			type = TYPE_OPERATOR; | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	struct SelfNode : public ENode { | ||
|  | 
 | ||
|  | 		SelfNode() { | ||
|  | 			type = TYPE_SELF; | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	struct IndexNode : public ENode { | ||
|  | 		ENode *base; | ||
|  | 		ENode *index; | ||
|  | 
 | ||
|  | 		IndexNode() { | ||
|  | 			type = TYPE_INDEX; | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	struct NamedIndexNode : public ENode { | ||
|  | 		ENode *base; | ||
|  | 		StringName name; | ||
|  | 
 | ||
|  | 		NamedIndexNode() { | ||
|  | 			type = TYPE_NAMED_INDEX; | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	struct ConstructorNode : public ENode { | ||
|  | 		Variant::Type data_type; | ||
|  | 		Vector<ENode *> arguments; | ||
|  | 
 | ||
|  | 		ConstructorNode() { | ||
|  | 			type = TYPE_CONSTRUCTOR; | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	struct CallNode : public ENode { | ||
|  | 		ENode *base; | ||
|  | 		StringName method; | ||
|  | 		Vector<ENode *> arguments; | ||
|  | 
 | ||
|  | 		CallNode() { | ||
|  | 			type = TYPE_CALL; | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	struct ArrayNode : public ENode { | ||
|  | 		Vector<ENode *> array; | ||
|  | 		ArrayNode() { | ||
|  | 			type = TYPE_ARRAY; | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	struct DictionaryNode : public ENode { | ||
|  | 		Vector<ENode *> dict; | ||
|  | 		DictionaryNode() { | ||
|  | 			type = TYPE_DICTIONARY; | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	struct BuiltinFuncNode : public ENode { | ||
|  | 		BuiltinFunc func; | ||
|  | 		Vector<ENode *> arguments; | ||
|  | 		BuiltinFuncNode() { | ||
|  | 			type = TYPE_BUILTIN_FUNC; | ||
|  | 		} | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	template <class T> | ||
|  | 	T *alloc_node() { | ||
|  | 		T *node = memnew(T); | ||
|  | 		node->next = nodes; | ||
|  | 		nodes = node; | ||
|  | 		return node; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	ENode *root; | ||
|  | 	ENode *nodes; | ||
|  | 
 | ||
|  | 	bool execution_error; | ||
|  | 	bool _execute(const Array &p_inputs, Object *p_instance, Expression::ENode *p_node, Variant &r_ret, String &r_error_str); | ||
|  | 
 | ||
|  | protected: | ||
|  | 	static void _bind_methods(); | ||
|  | 
 | ||
|  | public: | ||
|  | 	Error parse(const String &p_expression); | ||
|  | 	Variant execute(Array p_inputs, Object *p_base = NULL, bool p_show_error = true); | ||
|  | 	bool has_execute_failed() const; | ||
|  | 	String get_error_text() const; | ||
|  | 
 | ||
|  | 	Expression(); | ||
|  | 	~Expression(); | ||
|  | }; | ||
|  | 
 | ||
|  | #endif // EXPRESSION_H
 |