diff --git a/core/math/expression.cpp b/core/math/expression.cpp index b7fd26ae367..6d47fed1215 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -350,9 +350,9 @@ Error Expression::_get_token(Token &r_token) { case READING_INT: { if (is_digit(c)) { if (is_first_char && c == '0') { - if (next_char == 'b') { + if (next_char == 'b' || next_char == 'B') { reading = READING_BIN; - } else if (next_char == 'x') { + } else if (next_char == 'x' || next_char == 'X') { reading = READING_HEX; } } @@ -370,7 +370,7 @@ Error Expression::_get_token(Token &r_token) { case READING_BIN: { if (bin_beg && !is_binary_digit(c)) { reading = READING_DONE; - } else if (c == 'b') { + } else if (c == 'b' || c == 'B') { bin_beg = true; } @@ -378,7 +378,7 @@ Error Expression::_get_token(Token &r_token) { case READING_HEX: { if (hex_beg && !is_hex_digit(c)) { reading = READING_DONE; - } else if (c == 'x') { + } else if (c == 'x' || c == 'X') { hex_beg = true; } diff --git a/editor/import/resource_importer_imagefont.cpp b/editor/import/resource_importer_imagefont.cpp index e0a8cd924b7..741287ece31 100644 --- a/editor/import/resource_importer_imagefont.cpp +++ b/editor/import/resource_importer_imagefont.cpp @@ -159,7 +159,7 @@ Error ResourceImporterImageFont::import(ResourceUID::ID p_source_id, const Strin c++; // Skip "+". continue; } - } else if (range[c] == '0' && (c <= range.length() - 2) && range[c + 1] == 'x') { + } else if (range[c] == '0' && (c <= range.length() - 2) && (range[c + 1] == 'x' || range[c + 1] == 'X')) { // Read hexadecimal value, start. token = String(); if (step == STEP_START_BEGIN) { diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 25e09504ce9..9d90c35736b 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -351,12 +351,12 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l // Special cases for numbers. if (in_number && !is_a_digit) { - if (str[j] == 'b' && str[j - 1] == '0') { + if ((str[j] == 'b' || str[j] == 'B') && str[j - 1] == '0') { is_bin_notation = true; - } else if (str[j] == 'x' && str[j - 1] == '0') { + } else if ((str[j] == 'x' || str[j] == 'X') && str[j - 1] == '0') { is_hex_notation = true; } else if (!((str[j] == '-' || str[j] == '+') && str[j - 1] == 'e' && !prev_is_digit) && - !(str[j] == '_' && (prev_is_digit || str[j - 1] == 'b' || str[j - 1] == 'x' || str[j - 1] == '.')) && + !(str[j] == '_' && (prev_is_digit || str[j - 1] == 'b' || str[j - 1] == 'B' || str[j - 1] == 'x' || str[j - 1] == 'X' || str[j - 1] == '.')) && !(str[j] == 'e' && (prev_is_digit || str[j - 1] == '_')) && !(str[j] == '.' && (prev_is_digit || (!prev_is_binary_op && (j > 0 && (str[j - 1] == '_' || str[j - 1] == '-' || str[j - 1] == '+' || str[j - 1] == '~'))))) && !((str[j] == '-' || str[j] == '+' || str[j] == '~') && !is_binary_op && !prev_is_binary_op && str[j - 1] != 'e')) { diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index dd936cbe7ed..2bc4b703e20 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -696,13 +696,13 @@ GDScriptTokenizer::Token GDScriptTokenizerText::number() { if (_peek(-1) == '.') { has_decimal = true; } else if (_peek(-1) == '0') { - if (_peek() == 'x') { + if (_peek() == 'x' || _peek() == 'X') { // Hexadecimal. base = 16; digit_check_func = is_hex_digit; need_digits = true; _advance(); - } else if (_peek() == 'b') { + } else if (_peek() == 'b' || _peek() == 'B') { // Binary. base = 2; digit_check_func = is_binary_digit; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index c79c45fa08c..0ca2307e3db 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -979,7 +979,7 @@ namespace Godot { if (instance.Length < 3) return false; - if (instance[from] != '0' || instance[from + 1] != 'x') + if (instance[from] != '0' || instance[from + 1] != 'x' || instance[from + 1] != 'X') return false; from += 2; } diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp index a2113a89e22..7905acfd0e4 100644 --- a/scene/resources/syntax_highlighter.cpp +++ b/scene/resources/syntax_highlighter.cpp @@ -302,12 +302,12 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) { } // Check for dot or underscore or 'x' for hex notation in floating point number or 'e' for scientific notation. - if ((str[j] == '.' || str[j] == 'x' || str[j] == '_' || str[j] == 'f' || str[j] == 'e' || (uint_suffix_enabled && str[j] == 'u')) && !in_word && prev_is_number && !is_number) { + if ((str[j] == '.' || str[j] == 'x' || str[j] == 'X' || str[j] == '_' || str[j] == 'f' || str[j] == 'e' || (uint_suffix_enabled && str[j] == 'u')) && !in_word && prev_is_number && !is_number) { is_number = true; is_a_symbol = false; is_char = false; - if (str[j] == 'x' && str[j - 1] == '0') { + if ((str[j] == 'x' || str[j] == 'X') && str[j - 1] == '0') { is_hex_notation = true; } } diff --git a/tests/core/math/test_expression.h b/tests/core/math/test_expression.h index c3e42804919..8dbc5cae21a 100644 --- a/tests/core/math/test_expression.h +++ b/tests/core/math/test_expression.h @@ -213,6 +213,15 @@ TEST_CASE("[Expression] Underscored numeric literals") { CHECK_MESSAGE( expression.parse("0xff_99_00") == OK, "The expression should parse successfully."); + CHECK_MESSAGE( + expression.parse("0Xff_99_00") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + expression.parse("0b10_11_00") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + expression.parse("0B10_11_00") == OK, + "The expression should parse successfully."); } TEST_CASE("[Expression] Built-in functions") { diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index ea60230947d..479f448f24d 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -545,7 +545,10 @@ TEST_CASE("[String] String to integer") { CHECK(String(nums[i]).to_int() == num[i]); } CHECK(String("0b1011").to_int() == 1011); // Looks like a binary number, but to_int() handles this as a base-10 number, "b" is just ignored. + CHECK(String("0B1011").to_int() == 1011); + CHECK(String("0x1012").to_int() == 1012); // Looks like a hexadecimal number, but to_int() handles this as a base-10 number, "x" is just ignored. + CHECK(String("0X1012").to_int() == 1012); ERR_PRINT_OFF CHECK(String("999999999999999999999999999999999999999999999999999999999").to_int() == INT64_MAX); // Too large, largest possible is returned. @@ -554,10 +557,10 @@ TEST_CASE("[String] String to integer") { } TEST_CASE("[String] Hex to integer") { - static const char *nums[12] = { "0xFFAE", "22", "0", "AADDAD", "0x7FFFFFFFFFFFFFFF", "-0xf", "", "000", "000f", "0xaA", "-ff", "-" }; - static const int64_t num[12] = { 0xFFAE, 0x22, 0, 0xAADDAD, 0x7FFFFFFFFFFFFFFF, -0xf, 0, 0, 0xf, 0xaa, -0xff, 0x0 }; + static const char *nums[13] = { "0xFFAE", "22", "0", "AADDAD", "0x7FFFFFFFFFFFFFFF", "-0xf", "", "000", "000f", "0xaA", "-ff", "-", "0XFFAE" }; + static const int64_t num[13] = { 0xFFAE, 0x22, 0, 0xAADDAD, 0x7FFFFFFFFFFFFFFF, -0xf, 0, 0, 0xf, 0xaa, -0xff, 0x0, 0xFFAE }; - for (int i = 0; i < 12; i++) { + for (int i = 0; i < 13; i++) { CHECK(String(nums[i]).hex_to_int() == num[i]); } @@ -575,10 +578,10 @@ TEST_CASE("[String] Hex to integer") { } TEST_CASE("[String] Bin to integer") { - static const char *nums[10] = { "", "0", "0b0", "0b1", "0b", "1", "0b1010", "-0b11", "-1010", "0b0111111111111111111111111111111111111111111111111111111111111111" }; - static const int64_t num[10] = { 0, 0, 0, 1, 0, 1, 10, -3, -10, 0x7FFFFFFFFFFFFFFF }; + static const char *nums[11] = { "", "0", "0b0", "0b1", "0b", "1", "0b1010", "-0b11", "-1010", "0b0111111111111111111111111111111111111111111111111111111111111111", "0B1010" }; + static const int64_t num[11] = { 0, 0, 0, 1, 0, 1, 10, -3, -10, 0x7FFFFFFFFFFFFFFF, 10 }; - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 11; i++) { CHECK(String(nums[i]).bin_to_int() == num[i]); }