diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 6d47fed1215..26b773a2242 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -359,7 +359,7 @@ Error Expression::_get_token(Token &r_token) { } else if (c == '.') { reading = READING_DEC; is_float = true; - } else if (c == 'e') { + } else if (c == 'e' || c == 'E') { reading = READING_EXP; is_float = true; } else { @@ -385,7 +385,7 @@ Error Expression::_get_token(Token &r_token) { } break; case READING_DEC: { if (is_digit(c)) { - } else if (c == 'e') { + } else if (c == 'e' || c == 'E') { reading = READING_EXP; } else { reading = READING_DONE; diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index c879cf99008..637394324e9 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -4964,17 +4964,18 @@ bool String::is_valid_float() const { bool numbers_found = false; for (int i = from; i < len; i++) { - if (is_digit(operator[](i))) { + const char32_t c = operator[](i); + if (is_digit(c)) { if (exponent_found) { exponent_values_found = true; } else { numbers_found = true; } - } else if (numbers_found && !exponent_found && operator[](i) == 'e') { + } else if (numbers_found && !exponent_found && (c == 'e' || c == 'E')) { exponent_found = true; - } else if (!period_found && !exponent_found && operator[](i) == '.') { + } else if (!period_found && !exponent_found && c == '.') { period_found = true; - } else if ((operator[](i) == '-' || operator[](i) == '+') && exponent_found && !exponent_values_found && !sign_found) { + } else if ((c == '-' || c == '+') && exponent_found && !exponent_values_found && !sign_found) { sign_found = true; } else { return false; // no start with number plz diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 3ce242d49c9..00d2c2c8b35 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -441,7 +441,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri } else if (c == '.') { reading = READING_DEC; is_float = true; - } else if (c == 'e') { + } else if (c == 'e' || c == 'E') { reading = READING_EXP; is_float = true; } else { @@ -451,7 +451,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri } break; case READING_DEC: { if (is_digit(c)) { - } else if (c == 'e') { + } else if (c == 'e' || c == 'E') { reading = READING_EXP; } else { reading = READING_DONE; @@ -1962,7 +1962,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str case Variant::FLOAT: { String s = rtos_fix(p_variant.operator double()); if (s != "inf" && s != "inf_neg" && s != "nan") { - if (!s.contains_char('.') && !s.contains_char('e')) { + if (!s.contains_char('.') && !s.contains_char('e') && !s.contains_char('E')) { s += ".0"; } } diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 9d90c35736b..acb74c1a6dc 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -355,11 +355,11 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l is_bin_notation = true; } 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) && + } else if (!((str[j] == '-' || str[j] == '+') && (str[j - 1] == 'e' || str[j - 1] == 'E') && !prev_is_digit) && !(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] == 'e' || 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')) { + !((str[j] == '-' || str[j] == '+' || str[j] == '~') && !is_binary_op && !prev_is_binary_op && str[j - 1] != 'e' && str[j - 1] != 'E')) { /* This condition continues number highlighting in special cases. 1st row: '+' or '-' after scientific notation (like 3e-4); 2nd row: '_' as a numeric separator; diff --git a/modules/gdscript/tests/scripts/parser/features/constants.gd b/modules/gdscript/tests/scripts/parser/features/constants.gd index 013c9c074f1..62600eea441 100644 --- a/modules/gdscript/tests/scripts/parser/features/constants.gd +++ b/modules/gdscript/tests/scripts/parser/features/constants.gd @@ -4,6 +4,8 @@ func test(): const _VECTOR = Vector2(5, 6) const _ARRAY = [] const _DICTIONARY = {"this": "dictionary"} + const _FLOAT1 = 1e2 + const _FLOAT2 = 1E2 # Create user constants from built-in constants. const _HELLO = PI + TAU diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index b6678986b07..527d2dce41f 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -6881,7 +6881,8 @@ void TextServerAdvanced::_insert_num_systems_lang() { ar.lang.insert(StringName("sd_Arab_PK")); ar.digits = U"٠١٢٣٤٥٦٧٨٩٫"; ar.percent_sign = U"٪"; - ar.exp = U"اس"; + ar.exp_l = U"اس"; + ar.exp_u = U"اس"; num_systems.push_back(ar); } @@ -6912,7 +6913,8 @@ void TextServerAdvanced::_insert_num_systems_lang() { pr.lang.insert(StringName("uz_Arab_AF")); pr.digits = U"۰۱۲۳۴۵۶۷۸۹٫"; pr.percent_sign = U"٪"; - pr.exp = U"اس"; + pr.exp_l = U"اس"; + pr.exp_u = U"اس"; num_systems.push_back(pr); } @@ -6930,7 +6932,8 @@ void TextServerAdvanced::_insert_num_systems_lang() { bn.lang.insert(StringName("mni_Beng_IN")); bn.digits = U"০১২৩৪৫৬৭৮৯."; bn.percent_sign = U"%"; - bn.exp = U"e"; + bn.exp_l = U"e"; + bn.exp_u = U"E"; num_systems.push_back(bn); } @@ -6946,7 +6949,8 @@ void TextServerAdvanced::_insert_num_systems_lang() { mr.lang.insert(StringName("sa_IN")); mr.digits = U"०१२३४५६७८९."; mr.percent_sign = U"%"; - mr.exp = U"e"; + mr.exp_l = U"e"; + mr.exp_u = U"E"; num_systems.push_back(mr); } @@ -6957,7 +6961,8 @@ void TextServerAdvanced::_insert_num_systems_lang() { dz.lang.insert(StringName("dz_BT")); dz.digits = U"༠༡༢༣༤༥༦༧༨༩."; dz.percent_sign = U"%"; - dz.exp = U"e"; + dz.exp_l = U"e"; + dz.exp_u = U"E"; num_systems.push_back(dz); } @@ -6970,7 +6975,8 @@ void TextServerAdvanced::_insert_num_systems_lang() { sat.lang.insert(StringName("sat_Olck_IN")); sat.digits = U"᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙."; sat.percent_sign = U"%"; - sat.exp = U"e"; + sat.exp_l = U"e"; + sat.exp_u = U"E"; num_systems.push_back(sat); } @@ -6981,7 +6987,8 @@ void TextServerAdvanced::_insert_num_systems_lang() { my.lang.insert(StringName("my_MM")); my.digits = U"၀၁၂၃၄၅၆၇၈၉."; my.percent_sign = U"%"; - my.exp = U"e"; + my.exp_l = U"e"; + my.exp_u = U"E"; num_systems.push_back(my); } @@ -6993,7 +7000,8 @@ void TextServerAdvanced::_insert_num_systems_lang() { ccp.lang.insert(StringName("ccp_IN")); ccp.digits = U"𑄶𑄷𑄸𑄹𑄺𑄻𑄼𑄽𑄾𑄿."; ccp.percent_sign = U"%"; - ccp.exp = U"e"; + ccp.exp_l = U"e"; + ccp.exp_u = U"E"; num_systems.push_back(ccp); } @@ -7015,7 +7023,8 @@ void TextServerAdvanced::_insert_num_systems_lang() { ff.lang.insert(StringName("ff_Adlm_SN")); ff.digits = U"𞥐𞥑𞥒𞥓𞥔𞥕𞥖𞥗𞥘𞥙."; ff.percent_sign = U"%"; - ff.exp = U"e"; + ff.exp_l = U"𞤉"; + ff.exp_u = U"𞤉"; num_systems.push_back(ff); } } @@ -7029,8 +7038,8 @@ String TextServerAdvanced::_format_number(const String &p_string, const String & if (num_systems[i].digits.is_empty()) { return p_string; } - res.replace("e", num_systems[i].exp); - res.replace("E", num_systems[i].exp); + res = res.replace("e", num_systems[i].exp_l); + res = res.replace("E", num_systems[i].exp_u); char32_t *data = res.ptrw(); for (int j = 0; j < res.length(); j++) { if (data[j] >= 0x30 && data[j] <= 0x39) { @@ -7054,7 +7063,8 @@ String TextServerAdvanced::_parse_number(const String &p_string, const String &p if (num_systems[i].digits.is_empty()) { return p_string; } - res.replace(num_systems[i].exp, "e"); + res = res.replace(num_systems[i].exp_l, "e"); + res = res.replace(num_systems[i].exp_u, "E"); char32_t *data = res.ptrw(); for (int j = 0; j < res.length(); j++) { if (data[j] == num_systems[i].digits[10]) { diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index ab37abc6f7e..6561667e80e 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -147,7 +147,8 @@ class TextServerAdvanced : public TextServerExtension { HashSet lang; String digits; String percent_sign; - String exp; + String exp_l; + String exp_u; }; Vector num_systems; diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp index 7905acfd0e4..662bb3d60c9 100644 --- a/scene/resources/syntax_highlighter.cpp +++ b/scene/resources/syntax_highlighter.cpp @@ -302,7 +302,7 @@ 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] == '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' || 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; diff --git a/tests/core/math/test_expression.h b/tests/core/math/test_expression.h index 8dbc5cae21a..7f660697db0 100644 --- a/tests/core/math/test_expression.h +++ b/tests/core/math/test_expression.h @@ -181,6 +181,9 @@ TEST_CASE("[Expression] Scientific notation") { CHECK_MESSAGE( expression.parse("2.e5") == OK, "The expression should parse successfully."); + CHECK_MESSAGE( + expression.parse("2.E5") == OK, + "The expression should parse successfully."); CHECK_MESSAGE( double(expression.execute()) == doctest::Approx(200'000), "The expression should return the expected result."); diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 479f448f24d..d0b1bf8448e 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -1888,15 +1888,15 @@ TEST_CASE("[String] Join") { } TEST_CASE("[String] Is_*") { - static const char *data[13] = { "-30", "100", "10.1", "10,1", "1e2", "1e-2", "1e2e3", "0xAB", "AB", "Test1", "1Test", "Test*1", "文字" }; - static bool isnum[13] = { true, true, true, false, false, false, false, false, false, false, false, false, false }; - static bool isint[13] = { true, true, false, false, false, false, false, false, false, false, false, false, false }; - static bool ishex[13] = { true, true, false, false, true, false, true, false, true, false, false, false, false }; - static bool ishex_p[13] = { false, false, false, false, false, false, false, true, false, false, false, false, false }; - static bool isflt[13] = { true, true, true, false, true, true, false, false, false, false, false, false, false }; - static bool isaid[13] = { false, false, false, false, false, false, false, false, true, true, false, false, false }; - static bool isuid[13] = { false, false, false, false, false, false, false, false, true, true, false, false, true }; - for (int i = 0; i < 12; i++) { + static const char *data[] = { "-30", "100", "10.1", "10,1", "1e2", "1e-2", "1e2e3", "0xAB", "AB", "Test1", "1Test", "Test*1", "文字", "1E2", "1E-2" }; + static bool isnum[] = { true, true, true, false, false, false, false, false, false, false, false, false, false, false, false }; + static bool isint[] = { true, true, false, false, false, false, false, false, false, false, false, false, false, false, false }; + static bool ishex[] = { true, true, false, false, true, false, true, false, true, false, false, false, false, true, false }; + static bool ishex_p[] = { false, false, false, false, false, false, false, true, false, false, false, false, false, false, false }; + static bool isflt[] = { true, true, true, false, true, true, false, false, false, false, false, false, false, true, true }; + static bool isaid[] = { false, false, false, false, false, false, false, false, true, true, false, false, false, false, false }; + static bool isuid[] = { false, false, false, false, false, false, false, false, true, true, false, false, true, false, false }; + for (unsigned int i = 0; i < sizeof(data) / sizeof(data[0]); i++) { String s = String::utf8(data[i]); CHECK(s.is_numeric() == isnum[i]); CHECK(s.is_valid_int() == isint[i]);