diff options
Diffstat (limited to 'servers/rendering/shader_language.cpp')
-rw-r--r-- | servers/rendering/shader_language.cpp | 87 |
1 files changed, 64 insertions, 23 deletions
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index d6acad83f7..e9b1cb366d 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++; } @@ -2353,10 +2353,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 +2383,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 +2397,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 +2471,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; } @@ -3869,7 +3905,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 +3969,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 +4036,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': @@ -6979,6 +7015,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 +7075,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 +7336,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 +7356,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 +7419,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 +7429,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; |