@@ -1399,6 +1399,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
13991399 if (r_is_const) {
14001400 *r_is_const = p_function_info.built_ins [p_identifier].constant ;
14011401 }
1402+ if (r_constant_values) {
1403+ *r_constant_values = p_function_info.built_ins [p_identifier].values ;
1404+ }
14021405 if (r_type) {
14031406 *r_type = IDENTIFIER_BUILTIN_VAR;
14041407 }
@@ -1551,7 +1554,7 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
15511554 return false ;
15521555}
15531556
1554- bool ShaderLanguage::_validate_operator (const BlockNode *p_block, OperatorNode *p_op, DataType *r_ret_type, int *r_ret_size) {
1557+ bool ShaderLanguage::_validate_operator (const BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_op, DataType *r_ret_type, int *r_ret_size) {
15551558 bool valid = false ;
15561559 DataType ret_type = TYPE_VOID;
15571560 int ret_size = 0 ;
@@ -2017,18 +2020,18 @@ bool ShaderLanguage::_validate_operator(const BlockNode *p_block, OperatorNode *
20172020
20182021 if (valid && (!p_block || p_block->use_op_eval )) {
20192022 // Need to be placed here and not in the `_reduce_expression` because otherwise expressions like `1 + 2 / 2` will not work correctly.
2020- valid = _eval_operator (p_block, p_op);
2023+ valid = _eval_operator (p_block, p_function_info, p_op);
20212024 }
20222025
20232026 return valid;
20242027}
20252028
2026- Vector<ShaderLanguage::Scalar> ShaderLanguage::_get_node_values (const BlockNode *p_block, Node *p_node) {
2029+ Vector<ShaderLanguage::Scalar> ShaderLanguage::_get_node_values (const BlockNode *p_block, const FunctionInfo &p_function_info, Node *p_node) {
20272030 Vector<Scalar> result;
20282031
20292032 switch (p_node->type ) {
20302033 case Node::NODE_TYPE_VARIABLE: {
2031- _find_identifier (p_block, false , FunctionInfo () , static_cast <VariableNode *>(p_node)->name , nullptr , nullptr , nullptr , nullptr , nullptr , &result);
2034+ _find_identifier (p_block, false , p_function_info , static_cast <VariableNode *>(p_node)->name , nullptr , nullptr , nullptr , nullptr , nullptr , &result);
20322035 } break ;
20332036 default : {
20342037 result = p_node->get_values ();
@@ -2038,7 +2041,7 @@ Vector<ShaderLanguage::Scalar> ShaderLanguage::_get_node_values(const BlockNode
20382041 return result;
20392042}
20402043
2041- bool ShaderLanguage::_eval_operator (const BlockNode *p_block, OperatorNode *p_op) {
2044+ bool ShaderLanguage::_eval_operator (const BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_op) {
20422045 bool is_valid = true ;
20432046
20442047 switch (p_op->op ) {
@@ -2080,8 +2083,8 @@ bool ShaderLanguage::_eval_operator(const BlockNode *p_block, OperatorNode *p_op
20802083 }
20812084 }
20822085
2083- Vector<Scalar> va = _get_node_values (p_block, p_op->arguments [0 ]);
2084- Vector<Scalar> vb = _get_node_values (p_block, p_op->arguments [1 ]);
2086+ Vector<Scalar> va = _get_node_values (p_block, p_function_info, p_op->arguments [0 ]);
2087+ Vector<Scalar> vb = _get_node_values (p_block, p_function_info, p_op->arguments [1 ]);
20852088
20862089 if (is_op_vec_transform) {
20872090 p_op->values = _eval_vector_transform (va, vb, a, b, p_op->get_datatype ());
@@ -2092,7 +2095,7 @@ bool ShaderLanguage::_eval_operator(const BlockNode *p_block, OperatorNode *p_op
20922095 case OP_NOT:
20932096 case OP_NEGATE:
20942097 case OP_BIT_INVERT: {
2095- p_op->values = _eval_unary_vector (_get_node_values (p_block, p_op->arguments [0 ]), p_op->get_datatype (), p_op->op );
2098+ p_op->values = _eval_unary_vector (_get_node_values (p_block, p_function_info, p_op->arguments [0 ]), p_op->get_datatype (), p_op->op );
20962099 } break ;
20972100 default : {
20982101 } break ;
@@ -3661,7 +3664,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
36613664 int max = builtin_func_const_args[constarg_idx].max ;
36623665
36633666 bool error = false ;
3664- Vector<Scalar> values = _get_node_values (p_block, p_func->arguments [arg]);
3667+ Vector<Scalar> values = _get_node_values (p_block, p_function_info, p_func->arguments [arg]);
36653668 if (p_func->arguments [arg]->get_datatype () == TYPE_INT && !values.is_empty ()) {
36663669 if (values[0 ].sint < min || values[0 ].sint > max) {
36673670 error = true ;
@@ -5662,7 +5665,7 @@ Error ShaderLanguage::_parse_array_size(BlockNode *p_block, const FunctionInfo &
56625665 Node *expr = _parse_and_reduce_expression (p_block, p_function_info);
56635666
56645667 if (expr) {
5665- Vector<Scalar> values = _get_node_values (p_block, expr);
5668+ Vector<Scalar> values = _get_node_values (p_block, p_function_info, expr);
56665669
56675670 if (!values.is_empty ()) {
56685671 switch (expr->get_datatype ()) {
@@ -7279,7 +7282,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
72797282 op->op = tk.type == TK_OP_DECREMENT ? OP_POST_DECREMENT : OP_POST_INCREMENT;
72807283 op->arguments .push_back (expr);
72817284
7282- if (!_validate_operator (p_block, op, &op->return_cache , &op->return_array_size )) {
7285+ if (!_validate_operator (p_block, p_function_info, op, &op->return_cache , &op->return_array_size )) {
72837286 _set_error (RTR (" Invalid base type for increment/decrement operator." ));
72847287 return nullptr ;
72857288 }
@@ -7631,7 +7634,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
76317634 expression.write [i].is_op = false ;
76327635 expression.write [i].node = op;
76337636
7634- if (!_validate_operator (p_block, op, &op->return_cache , &op->return_array_size )) {
7637+ if (!_validate_operator (p_block, p_function_info, op, &op->return_cache , &op->return_array_size )) {
76357638 if (error_set) {
76367639 return nullptr ;
76377640 }
@@ -7673,7 +7676,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
76737676
76747677 expression.write [next_op - 1 ].is_op = false ;
76757678 expression.write [next_op - 1 ].node = op;
7676- if (!_validate_operator (p_block, op, &op->return_cache , &op->return_array_size )) {
7679+ if (!_validate_operator (p_block, p_function_info, op, &op->return_cache , &op->return_array_size )) {
76777680 if (error_set) {
76787681 return nullptr ;
76797682 }
@@ -7740,7 +7743,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
77407743
77417744 // replace all 3 nodes by this operator and make it an expression
77427745
7743- if (!_validate_operator (p_block, op, &op->return_cache , &op->return_array_size )) {
7746+ if (!_validate_operator (p_block, p_function_info, op, &op->return_cache , &op->return_array_size )) {
77447747 if (error_set) {
77457748 return nullptr ;
77467749 }
@@ -9073,6 +9076,40 @@ Error ShaderLanguage::_validate_precision(DataType p_type, DataPrecision p_preci
90739076 return OK;
90749077}
90759078
9079+ bool ShaderLanguage::_parse_numeric_constant_expression (const FunctionInfo &p_function_info, float &r_constant) {
9080+ ShaderLanguage::Node *expr = _parse_and_reduce_expression (nullptr , p_function_info);
9081+ if (expr == nullptr ) {
9082+ return false ;
9083+ }
9084+
9085+ Vector<Scalar> values;
9086+ if (expr->type == Node::NODE_TYPE_VARIABLE) {
9087+ _find_identifier (nullptr , false , p_function_info, static_cast <VariableNode *>(expr)->name , nullptr , nullptr , nullptr , nullptr , nullptr , &values);
9088+ } else {
9089+ values = expr->get_values ();
9090+ }
9091+
9092+ if (values.is_empty ()) {
9093+ return false ; // To prevent possible crash.
9094+ }
9095+
9096+ switch (expr->get_datatype ()) {
9097+ case TYPE_FLOAT:
9098+ r_constant = values[0 ].real ;
9099+ break ;
9100+ case TYPE_INT:
9101+ r_constant = static_cast <float >(values[0 ].sint );
9102+ break ;
9103+ case TYPE_UINT:
9104+ r_constant = static_cast <float >(values[0 ].uint );
9105+ break ;
9106+ default :
9107+ return false ;
9108+ }
9109+
9110+ return true ;
9111+ }
9112+
90769113Error ShaderLanguage::_parse_shader (const HashMap<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const HashSet<String> &p_shader_types) {
90779114 Token tk;
90789115 TkPos prev_pos;
@@ -9817,58 +9854,30 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
98179854 return ERR_PARSE_ERROR;
98189855 }
98199856
9820- tk = _get_token ();
9821-
9822- float sign = 1.0 ;
9823-
9824- if (tk.type == TK_OP_SUB) {
9825- sign = -1.0 ;
9826- tk = _get_token ();
9827- }
9828-
9829- if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant ()) {
9830- _set_error (RTR (" Expected an integer constant." ));
9857+ if (!_parse_numeric_constant_expression (constants, uniform.hint_range [0 ])) {
9858+ _set_error (RTR (" Expected a valid numeric expression." ));
98319859 return ERR_PARSE_ERROR;
98329860 }
98339861
9834- uniform.hint_range [0 ] = tk.constant ;
9835- uniform.hint_range [0 ] *= sign;
9836-
98379862 tk = _get_token ();
98389863
98399864 if (tk.type != TK_COMMA) {
9840- _set_error ( RTR ( " Expected ',' after integer constant. " ) );
9865+ _set_expected_error ( " , " );
98419866 return ERR_PARSE_ERROR;
98429867 }
98439868
9844- tk = _get_token ();
9845-
9846- sign = 1.0 ;
9847-
9848- if (tk.type == TK_OP_SUB) {
9849- sign = -1.0 ;
9850- tk = _get_token ();
9851- }
9852-
9853- if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant ()) {
9854- _set_error (RTR (" Expected an integer constant after ','." ));
9869+ if (!_parse_numeric_constant_expression (constants, uniform.hint_range [1 ])) {
9870+ _set_error (RTR (" Expected a valid numeric expression after ','." ));
98559871 return ERR_PARSE_ERROR;
98569872 }
98579873
9858- uniform.hint_range [1 ] = tk.constant ;
9859- uniform.hint_range [1 ] *= sign;
9860-
98619874 tk = _get_token ();
98629875
98639876 if (tk.type == TK_COMMA) {
9864- tk = _get_token ();
9865-
9866- if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant ()) {
9867- _set_error (RTR (" Expected an integer constant after ','." ));
9877+ if (!_parse_numeric_constant_expression (constants, uniform.hint_range [2 ])) {
9878+ _set_error (RTR (" Expected a valid numeric expression after ','." ));
98689879 return ERR_PARSE_ERROR;
98699880 }
9870-
9871- uniform.hint_range [2 ] = tk.constant ;
98729881 tk = _get_token ();
98739882 } else {
98749883 if (type == TYPE_INT) {
0 commit comments