summaryrefslogtreecommitdiff
path: root/servers/rendering/shader_language.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/shader_language.cpp')
-rw-r--r--servers/rendering/shader_language.cpp267
1 files changed, 173 insertions, 94 deletions
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index d6acad83f7..28c41fb2dc 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -33,15 +33,15 @@
#include "core/print_string.h"
#include "servers/rendering_server.h"
-static bool _is_text_char(CharType c) {
+static bool _is_text_char(char32_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
-static bool _is_number(CharType c) {
+static bool _is_number(char32_t c) {
return (c >= '0' && c <= '9');
}
-static bool _is_hex(CharType c) {
+static bool _is_hex(char32_t c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
@@ -334,7 +334,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
};
ShaderLanguage::Token ShaderLanguage::_get_token() {
-#define GETCHAR(m_idx) (((char_idx + m_idx) < code.length()) ? code[char_idx + m_idx] : CharType(0))
+#define GETCHAR(m_idx) (((char_idx + m_idx) < code.length()) ? code[char_idx + m_idx] : char32_t(0))
while (true) {
char_idx++;
@@ -582,11 +582,11 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
break;
}
- str += CharType(GETCHAR(i));
+ str += char32_t(GETCHAR(i));
i++;
}
- CharType last_char = str[str.length() - 1];
+ char32_t last_char = str[str.length() - 1];
if (hexa_found) {
//integer(hex)
@@ -663,7 +663,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
String str;
while (_is_text_char(GETCHAR(0))) {
- str += CharType(GETCHAR(0));
+ str += char32_t(GETCHAR(0));
char_idx++;
}
@@ -920,13 +920,13 @@ void ShaderLanguage::clear() {
}
}
-bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name) {
- if (p_builtin_types.has(p_identifier)) {
+bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name) {
+ if (p_function_info.built_ins.has(p_identifier)) {
if (r_data_type) {
- *r_data_type = p_builtin_types[p_identifier].type;
+ *r_data_type = p_function_info.built_ins[p_identifier].type;
}
if (r_is_const) {
- *r_is_const = p_builtin_types[p_identifier].constant;
+ *r_is_const = p_function_info.built_ins[p_identifier].constant;
}
if (r_type) {
*r_type = IDENTIFIER_BUILTIN_VAR;
@@ -935,6 +935,20 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
return true;
}
+ if (p_function_info.stage_functions.has(p_identifier)) {
+ if (r_data_type) {
+ *r_data_type = p_function_info.stage_functions[p_identifier].return_type;
+ }
+ if (r_is_const) {
+ *r_is_const = true;
+ }
+ if (r_type) {
+ *r_type = IDENTIFIER_FUNCTION;
+ }
+
+ return true;
+ }
+
FunctionNode *function = nullptr;
while (p_block) {
@@ -2152,7 +2166,7 @@ const ShaderLanguage::BuiltinFuncOutArgs ShaderLanguage::builtin_func_out_args[]
{ nullptr, 0 }
};
-bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str) {
+bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str) {
ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, false);
Vector<DataType> args;
@@ -2169,6 +2183,30 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
int argcount = args.size();
+ if (p_function_info.stage_functions.has(name)) {
+ //stage based function
+ const StageFunctionInfo &sf = p_function_info.stage_functions[name];
+ if (argcount != sf.arguments.size()) {
+ _set_error(vformat("Invalid number of arguments when calling stage function '%s', which expects %d arguments.", String(name), sf.arguments.size()));
+ return false;
+ }
+ //validate arguments
+ for (int i = 0; i < argcount; i++) {
+ if (args[i] != sf.arguments[i].type) {
+ _set_error(vformat("Invalid argument type when calling stage function '%s', type expected is '%s'.", String(name), String(get_datatype_name(sf.arguments[i].type))));
+ return false;
+ }
+ }
+
+ if (r_ret_type) {
+ *r_ret_type = sf.return_type;
+ }
+ if (r_ret_type_str) {
+ *r_ret_type_str = "";
+ }
+ return true;
+ }
+
bool failed_builtin = false;
bool unsupported_builtin = false;
int builtin_idx = 0;
@@ -2241,8 +2279,8 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
if (shader->uniforms.has(varname)) {
fail = true;
} else {
- if (p_builtin_types.has(varname)) {
- BuiltInInfo info = p_builtin_types[varname];
+ if (p_function_info.built_ins.has(varname)) {
+ BuiltInInfo info = p_function_info.built_ins[varname];
if (info.constant) {
fail = true;
}
@@ -2278,7 +2316,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
const BlockNode *b = p_block;
bool valid = false;
while (b) {
- if (b->variables.has(var_name) || p_builtin_types.has(var_name)) {
+ if (b->variables.has(var_name) || p_function_info.built_ins.has(var_name)) {
valid = true;
break;
}
@@ -2353,10 +2391,13 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
err += ",";
}
- if (p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && p_func->arguments[i + 1]->get_datatype() == TYPE_INT && static_cast<ConstantNode *>(p_func->arguments[i + 1])->values[0].sint < 0) {
- err += "-";
+ String arg_name;
+ if (args[i] == TYPE_STRUCT) {
+ arg_name = args2[i];
+ } else {
+ arg_name = get_datatype_name(args[i]);
}
- err += get_datatype_name(args[i]);
+ err += arg_name;
}
err += ")";
_set_error(err);
@@ -2380,6 +2421,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
return false;
}
+ int last_arg_count = 0;
+ String arg_list = "";
+
for (int i = 0; i < shader->functions.size(); i++) {
if (name != shader->functions[i].name) {
continue;
@@ -2391,21 +2435,45 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
}
FunctionNode *pfunc = shader->functions[i].function;
+ if (arg_list == "") {
+ for (int j = 0; j < pfunc->arguments.size(); j++) {
+ if (j > 0) {
+ arg_list += ", ";
+ }
+ String func_arg_name;
+ if (pfunc->arguments[j].type == TYPE_STRUCT) {
+ func_arg_name = pfunc->arguments[j].type_str;
+ } else {
+ func_arg_name = get_datatype_name(pfunc->arguments[j].type);
+ }
+ arg_list += func_arg_name;
+ }
+ }
if (pfunc->arguments.size() != args.size()) {
+ last_arg_count = pfunc->arguments.size();
continue;
}
bool fail = false;
for (int j = 0; j < args.size(); j++) {
- if (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].type_str) {
- fail = true;
- break;
- }
if (get_scalar_type(args[j]) == args[j] && p_func->arguments[j + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[j + 1]), pfunc->arguments[j].type)) {
//all good, but it needs implicit conversion later
- } else if (args[j] != pfunc->arguments[j].type) {
+ } else if (args[j] != pfunc->arguments[j].type || (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].type_str)) {
+ String func_arg_name;
+ if (pfunc->arguments[j].type == TYPE_STRUCT) {
+ func_arg_name = pfunc->arguments[j].type_str;
+ } else {
+ func_arg_name = get_datatype_name(pfunc->arguments[j].type);
+ }
+ String arg_name;
+ if (args[j] == TYPE_STRUCT) {
+ arg_name = args2[j];
+ } else {
+ arg_name = get_datatype_name(args[j]);
+ }
+ _set_error(vformat("Invalid argument for \"%s(%s)\" function: argument %s should be %s but is %s.", String(name), arg_list, j + 1, func_arg_name, arg_name));
fail = true;
break;
}
@@ -2441,6 +2509,12 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
}
}
+ if (last_arg_count > args.size()) {
+ _set_error(vformat("Too few arguments for \"%s(%s)\" call. Expected at least %s but received %s.", String(name), arg_list, last_arg_count, args.size()));
+ } else if (last_arg_count < args.size()) {
+ _set_error(vformat("Too many arguments for \"%s(%s)\" call. Expected at most %s but received %s.", String(name), arg_list, last_arg_count, args.size()));
+ }
+
return false;
}
@@ -2456,7 +2530,7 @@ bool ShaderLanguage::_compare_datatypes_in_nodes(Node *a, Node *b) const {
return true;
}
-bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg) {
+bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg) {
TkPos pos = _get_tkpos();
Token tk = _get_token();
@@ -2478,7 +2552,7 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str
}
}
- Node *arg = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *arg = _parse_and_reduce_expression(p_block, p_function_info);
if (!arg) {
return false;
@@ -3017,16 +3091,16 @@ bool ShaderLanguage::_is_operator_assign(Operator p_op) const {
return false;
}
-bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message) {
+bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message) {
if (p_node->type == Node::TYPE_OPERATOR) {
OperatorNode *op = static_cast<OperatorNode *>(p_node);
if (op->op == OP_INDEX) {
- return _validate_assign(op->arguments[0], p_builtin_types, r_message);
+ return _validate_assign(op->arguments[0], p_function_info, r_message);
} else if (_is_operator_assign(op->op)) {
//chained assignment
- return _validate_assign(op->arguments[1], p_builtin_types, r_message);
+ return _validate_assign(op->arguments[1], p_function_info, r_message);
} else if (op->op == OP_CALL) {
if (r_message) {
@@ -3045,7 +3119,7 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
return false;
}
- return _validate_assign(member->owner, p_builtin_types, r_message);
+ return _validate_assign(member->owner, p_function_info, r_message);
} else if (p_node->type == Node::TYPE_VARIABLE) {
VariableNode *var = static_cast<VariableNode *>(p_node);
@@ -3071,7 +3145,7 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
return false;
}
- if (!(p_builtin_types.has(var->name) && p_builtin_types[var->name].constant)) {
+ if (!(p_function_info.built_ins.has(var->name) && p_function_info.built_ins[var->name].constant)) {
return true;
}
} else if (p_node->type == Node::TYPE_ARRAY) {
@@ -3168,7 +3242,7 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa
ERR_FAIL_V(false); //bug? function not found
}
-ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) {
+ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info) {
Vector<Expression> expression;
//Vector<TokenType> operators;
@@ -3184,7 +3258,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_PARENTHESIS_OPEN) {
//handle subexpression
- expr = _parse_and_reduce_expression(p_block, p_builtin_types);
+ expr = _parse_and_reduce_expression(p_block, p_function_info);
if (!expr) {
return nullptr;
}
@@ -3257,7 +3331,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
int carg = -1;
- bool ok = _parse_function_arguments(p_block, p_builtin_types, func, &carg);
+ bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg);
if (carg >= 0) {
completion_type = COMPLETION_CALL_ARGUMENTS;
@@ -3271,7 +3345,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr;
}
- if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) {
+ if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) {
_set_error("No matching constructor found for: '" + String(funcname->name) + "'");
return nullptr;
}
@@ -3347,7 +3421,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else {
_set_tkpos(pos2);
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
_set_error("Expected single integer constant > 0");
return nullptr;
@@ -3408,7 +3482,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
while (true) {
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return nullptr;
}
@@ -3448,7 +3522,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
nexpr = an;
} else {
- nexpr = _parse_and_reduce_expression(p_block, p_builtin_types);
+ nexpr = _parse_and_reduce_expression(p_block, p_function_info);
if (!nexpr) {
return nullptr;
}
@@ -3490,7 +3564,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
int carg = -1;
- bool ok = _parse_function_arguments(p_block, p_builtin_types, func, &carg);
+ bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg);
// Check if block has a variable with the same name as function to prevent shader crash.
ShaderLanguage::BlockNode *bnode = p_block;
@@ -3532,7 +3606,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr;
}
- if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) {
+ if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) {
_set_error("No matching function found for: '" + String(funcname->name) + "'");
return nullptr;
}
@@ -3584,8 +3658,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else if (shader->uniforms.has(varname)) {
error = true;
} else {
- if (p_builtin_types.has(varname)) {
- BuiltInInfo info = p_builtin_types[varname];
+ if (p_function_info.built_ins.has(varname)) {
+ BuiltInInfo info = p_function_info.built_ins[varname];
if (info.constant) {
error = true;
}
@@ -3617,7 +3691,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (!_propagate_function_call_sampler_uniform_settings(name, i, u->filter, u->repeat)) {
return nullptr;
}
- } else if (p_builtin_types.has(varname)) {
+ } else if (p_function_info.built_ins.has(varname)) {
//a built-in
if (!_propagate_function_call_sampler_builtin_reference(name, i, varname)) {
return nullptr;
@@ -3672,7 +3746,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr;
}
} else {
- if (!_find_identifier(p_block, false, p_builtin_types, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) {
+ if (!_find_identifier(p_block, false, p_function_info, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) {
_set_error("Unknown identifier in expression: " + String(identifier));
return nullptr;
}
@@ -3697,7 +3771,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_PERIOD) {
completion_class = TAG_ARRAY;
p_block->block_tag = SubClassTag::TAG_ARRAY;
- call_expression = _parse_and_reduce_expression(p_block, p_builtin_types);
+ call_expression = _parse_and_reduce_expression(p_block, p_function_info);
p_block->block_tag = SubClassTag::TAG_GLOBAL;
if (!call_expression) {
return nullptr;
@@ -3705,7 +3779,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
data_type = call_expression->get_datatype();
} else { // indexing
- index_expression = _parse_and_reduce_expression(p_block, p_builtin_types);
+ index_expression = _parse_and_reduce_expression(p_block, p_function_info);
if (!index_expression) {
return nullptr;
}
@@ -3869,7 +3943,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
break;
}
- const CharType *c = ident.ptr();
+ const char32_t *c = ident.ptr();
for (int i = 0; i < l; i++) {
switch (c[i]) {
case 'r':
@@ -3933,7 +4007,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
break;
}
- const CharType *c = ident.ptr();
+ const char32_t *c = ident.ptr();
for (int i = 0; i < l; i++) {
switch (c[i]) {
case 'r':
@@ -4000,7 +4074,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
break;
}
- const CharType *c = ident.ptr();
+ const char32_t *c = ident.ptr();
for (int i = 0; i < l; i++) {
switch (c[i]) {
case 'r':
@@ -4085,7 +4159,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
_set_error("Nested array length() is not yet implemented");
return nullptr;
} else if (tk.type == TK_BRACKET_OPEN) {
- Node *index_expression = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *index_expression = _parse_and_reduce_expression(p_block, p_function_info);
if (!index_expression) {
return nullptr;
}
@@ -4134,7 +4208,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
*/
} else if (tk.type == TK_BRACKET_OPEN) {
- Node *index = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *index = _parse_and_reduce_expression(p_block, p_function_info);
if (!index) {
return nullptr;
}
@@ -4276,7 +4350,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr;
}
- if (!_validate_assign(expr, p_builtin_types)) {
+ if (!_validate_assign(expr, p_function_info)) {
_set_error("Invalid use of increment/decrement operator in constant expression.");
return nullptr;
}
@@ -4574,7 +4648,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
for (int i = expr_pos - 1; i >= next_op; i--) {
OperatorNode *op = alloc_node<OperatorNode>();
op->op = expression[i].op;
- if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_builtin_types)) {
+ if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_function_info)) {
_set_error("Can't use increment/decrement operator in constant expression.");
return nullptr;
}
@@ -4648,7 +4722,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (_is_operator_assign(op->op)) {
String assign_message;
- if (!_validate_assign(expression[next_op - 1].node, p_builtin_types, &assign_message)) {
+ if (!_validate_assign(expression[next_op - 1].node, p_function_info, &assign_message)) {
_set_error(assign_message);
return nullptr;
}
@@ -4802,8 +4876,8 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
return p_node;
}
-ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) {
- ShaderLanguage::Node *expr = _parse_expression(p_block, p_builtin_types);
+ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const FunctionInfo &p_function_info) {
+ ShaderLanguage::Node *expr = _parse_expression(p_block, p_function_info);
if (!expr) { //errored
return nullptr;
}
@@ -4813,7 +4887,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_
return expr;
}
-Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one, bool p_can_break, bool p_can_continue) {
+Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_just_one, bool p_can_break, bool p_can_continue) {
while (true) {
TkPos pos = _get_tkpos();
@@ -4897,7 +4971,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
StringName name = tk.text;
ShaderLanguage::IdentifierType itype;
- if (_find_identifier(p_block, true, p_builtin_types, name, (ShaderLanguage::DataType *)nullptr, &itype)) {
+ if (_find_identifier(p_block, true, p_function_info, name, (ShaderLanguage::DataType *)nullptr, &itype)) {
if (itype != IDENTIFIER_FUNCTION) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
@@ -5016,7 +5090,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
} else {
_set_tkpos(pos2);
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
_set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR;
@@ -5097,7 +5171,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
while (true) {
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5169,7 +5243,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
decl.initializer = nullptr;
//variable created with assignment! must parse an expression
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5229,7 +5303,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
//a sub block, just because..
BlockNode *block = alloc_node<BlockNode>();
block->parent_block = p_block;
- if (_parse_block(block, p_builtin_types, false, p_can_break, p_can_continue) != OK) {
+ if (_parse_block(block, p_function_info, false, p_can_break, p_can_continue) != OK) {
return ERR_PARSE_ERROR;
}
p_block->statements.push_back(block);
@@ -5243,7 +5317,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
cf->flow_op = FLOW_OP_IF;
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5265,7 +5339,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->blocks.push_back(block);
p_block->statements.push_back(cf);
- Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
+ Error err = _parse_block(block, p_function_info, true, p_can_break, p_can_continue);
if (err) {
return err;
}
@@ -5276,7 +5350,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
block = alloc_node<BlockNode>();
block->parent_block = p_block;
cf->blocks.push_back(block);
- err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
+ err = _parse_block(block, p_function_info, true, p_can_break, p_can_continue);
} else {
_set_tkpos(pos); //rollback
@@ -5295,7 +5369,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
cf->flow_op = FLOW_OP_SWITCH;
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5323,7 +5397,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
int prev_type = TK_CF_CASE;
while (true) { // Go-through multiple cases.
- if (_parse_block(switch_block, p_builtin_types, true, true, false) != OK) {
+ if (_parse_block(switch_block, p_function_info, true, true, false) != OK) {
return ERR_PARSE_ERROR;
}
pos = _get_tkpos();
@@ -5424,7 +5498,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->blocks.push_back(case_block);
p_block->statements.push_back(cf);
- Error err = _parse_block(case_block, p_builtin_types, false, true, false);
+ Error err = _parse_block(case_block, p_function_info, false, true, false);
if (err) {
return err;
}
@@ -5458,7 +5532,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->blocks.push_back(default_block);
p_block->statements.push_back(cf);
- Error err = _parse_block(default_block, p_builtin_types, false, true, false);
+ Error err = _parse_block(default_block, p_function_info, false, true, false);
if (err) {
return err;
}
@@ -5475,7 +5549,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
do_block = alloc_node<BlockNode>();
do_block->parent_block = p_block;
- Error err = _parse_block(do_block, p_builtin_types, true, true, true);
+ Error err = _parse_block(do_block, p_function_info, true, true, true);
if (err) {
return err;
}
@@ -5499,7 +5573,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
} else {
cf->flow_op = FLOW_OP_WHILE;
}
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5516,7 +5590,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->blocks.push_back(block);
p_block->statements.push_back(cf);
- Error err = _parse_block(block, p_builtin_types, true, true, true);
+ Error err = _parse_block(block, p_function_info, true, true, true);
if (err) {
return err;
}
@@ -5547,11 +5621,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
init_block->parent_block = p_block;
init_block->single_statement = true;
cf->blocks.push_back(init_block);
- if (_parse_block(init_block, p_builtin_types, true, false, false) != OK) {
+ if (_parse_block(init_block, p_function_info, true, false, false) != OK) {
return ERR_PARSE_ERROR;
}
- Node *n = _parse_and_reduce_expression(init_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(init_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5569,7 +5643,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->expressions.push_back(n);
- n = _parse_and_reduce_expression(init_block, p_builtin_types);
+ n = _parse_and_reduce_expression(init_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5587,7 +5661,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->blocks.push_back(block);
p_block->statements.push_back(cf);
- Error err = _parse_block(block, p_builtin_types, true, true, true);
+ Error err = _parse_block(block, p_function_info, true, true, true);
if (err) {
return err;
}
@@ -5623,7 +5697,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
} else {
_set_tkpos(pos); //rollback, wants expression
- Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *expr = _parse_and_reduce_expression(p_block, p_function_info);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -5725,7 +5799,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
} else {
//nothing else, so expression
_set_tkpos(pos); //rollback
- Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *expr = _parse_and_reduce_expression(p_block, p_function_info);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -6066,7 +6140,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
name = tk.text;
- if (_find_identifier(nullptr, false, Map<StringName, BuiltInInfo>(), name)) {
+ if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -6315,7 +6389,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
//reset scope for next uniform
if (tk.type == TK_OP_ASSIGN) {
- Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>());
+ Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -6440,7 +6514,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
- if (_find_identifier(nullptr, false, Map<StringName, BuiltInInfo>(), name)) {
+ if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -6553,7 +6627,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
_set_tkpos(pos2);
- Node *n = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>());
+ Node *n = _parse_and_reduce_expression(NULL, FunctionInfo());
if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
_set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR;
@@ -6634,7 +6708,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
while (true) {
- Node *n = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>());
+ Node *n = _parse_and_reduce_expression(NULL, FunctionInfo());
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -6689,7 +6763,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.initializer = static_cast<ConstantNode *>(expr);
} else {
//variable created with assignment! must parse an expression
- Node *expr = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>());
+ Node *expr = _parse_and_reduce_expression(NULL, FunctionInfo());
if (!expr)
return ERR_PARSE_ERROR;
if (expr->type == Node::TYPE_OPERATOR && ((OperatorNode *)expr)->op == OP_CALL) {
@@ -6726,7 +6800,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
name = tk.text;
- if (_find_identifier(nullptr, false, Map<StringName, BuiltInInfo>(), name)) {
+ if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -6749,14 +6823,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
break;
}
- Map<StringName, BuiltInInfo> builtin_types;
+ FunctionInfo builtins;
if (p_functions.has(name)) {
- builtin_types = p_functions[name].built_ins;
+ builtins = p_functions[name];
}
if (p_functions.has("global")) { // Adds global variables: 'TIME'
for (Map<StringName, BuiltInInfo>::Element *E = p_functions["global"].built_ins.front(); E; E = E->next()) {
- builtin_types.insert(E->key(), E->value());
+ builtins.built_ins.insert(E->key(), E->value());
}
}
@@ -6879,7 +6953,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
pname = tk.text;
ShaderLanguage::IdentifierType itype;
- if (_find_identifier(func_node->body, false, builtin_types, pname, (ShaderLanguage::DataType *)nullptr, &itype)) {
+ if (_find_identifier(func_node->body, false, builtins, pname, (ShaderLanguage::DataType *)nullptr, &itype)) {
if (itype != IDENTIFIER_FUNCTION) {
_set_error("Redefinition of '" + String(pname) + "'");
return ERR_PARSE_ERROR;
@@ -6941,7 +7015,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
current_function = name;
- Error err = _parse_block(func_node->body, builtin_types);
+ Error err = _parse_block(func_node->body, builtins);
if (err) {
return err;
}
@@ -6979,6 +7053,11 @@ bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionI
return true;
}
}
+ if (p_functions.has("compute")) {
+ if (p_functions["compute"].built_ins.has(p_name)) {
+ return true;
+ }
+ }
return false;
}
@@ -7034,7 +7113,7 @@ Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperat
static int _get_first_ident_pos(const String &p_code) {
int idx = 0;
-#define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : CharType(0))
+#define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : char32_t(0))
while (true) {
if (GETCHAR(0) == '/' && GETCHAR(1) == '/') {
@@ -7295,7 +7374,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
if (j == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
if (shader->functions[i].function->arguments[j].is_const) {
@@ -7315,7 +7394,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
calltip += shader->functions[i].function->arguments[j].name;
if (j == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
}
@@ -7378,7 +7457,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
if (i == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
if (out_arg >= 0 && i == out_arg) {
@@ -7388,7 +7467,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
calltip += get_datatype_name(builtin_func_defs[idx].args[i]);
if (i == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
found_arg = true;