diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index a45a73a8d51..ce0f53fcfb0 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -659,12 +659,20 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() { } } - // Allow '_' to be used in a number, for readability. - bool previous_was_underscore = false; + if (base != 10 && is_underscore(_peek())) { // Disallow `0x_` and `0b_`. + Token error = make_error(vformat(R"(Unexpected underscore after "0%c".)", _peek(-1))); + error.start_column = column; + error.leftmost_column = column; + error.end_column = column + 1; + error.rightmost_column = column + 1; + push_error(error); + has_error = true; + } + bool previous_was_underscore = false; // Allow `_` to be used in a number, for readability. while (digit_check_func(_peek()) || is_underscore(_peek())) { if (is_underscore(_peek())) { if (previous_was_underscore) { - Token error = make_error(R"(Only one underscore can be used as a numeric separator.)"); + Token error = make_error(R"(Multiple underscores cannot be adjacent in a numeric literal.)"); error.start_column = column; error.leftmost_column = column; error.end_column = column + 1; @@ -711,7 +719,30 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() { _advance(); // Consume decimal digits. + if (is_underscore(_peek())) { // Disallow `10._`, but allow `10.`. + Token error = make_error(R"(Unexpected underscore after decimal point.)"); + error.start_column = column; + error.leftmost_column = column; + error.end_column = column + 1; + error.rightmost_column = column + 1; + push_error(error); + has_error = true; + } + previous_was_underscore = false; while (is_digit(_peek()) || is_underscore(_peek())) { + if (is_underscore(_peek())) { + if (previous_was_underscore) { + Token error = make_error(R"(Multiple underscores cannot be adjacent in a numeric literal.)"); + error.start_column = column; + error.leftmost_column = column; + error.end_column = column + 1; + error.rightmost_column = column + 1; + push_error(error); + } + previous_was_underscore = true; + } else { + previous_was_underscore = false; + } _advance(); } } @@ -737,7 +768,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() { while (is_digit(_peek()) || is_underscore(_peek())) { if (is_underscore(_peek())) { if (previous_was_underscore) { - Token error = make_error(R"(Only one underscore can be used as a numeric separator.)"); + Token error = make_error(R"(Multiple underscores cannot be adjacent in a numeric literal.)"); error.start_column = column; error.leftmost_column = column; error.end_column = column + 1; diff --git a/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators.gd b/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators.gd index 71a03fbc0d6..f3227837760 100644 --- a/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators.gd +++ b/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators.gd @@ -1,3 +1,3 @@ func test(): # Number separators may not be placed right next to each other. - var __ = 1__23 + var _num = 1__23 diff --git a/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators.out b/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators.out index 71a3c2fd6a4..b308994ae22 100644 --- a/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators.out +++ b/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators.out @@ -1,2 +1,2 @@ GDTEST_PARSER_ERROR -Only one underscore can be used as a numeric separator. +Multiple underscores cannot be adjacent in a numeric literal. diff --git a/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators_after_decimal.gd b/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators_after_decimal.gd new file mode 100644 index 00000000000..3140999aa93 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators_after_decimal.gd @@ -0,0 +1,3 @@ +func test(): + # Number separators may not be placed right next to each other. + var _num = 123.45__67 diff --git a/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators_after_decimal.out b/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators_after_decimal.out new file mode 100644 index 00000000000..b308994ae22 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/errors/multiple_number_separators_after_decimal.out @@ -0,0 +1,2 @@ +GDTEST_PARSER_ERROR +Multiple underscores cannot be adjacent in a numeric literal. diff --git a/modules/gdscript/tests/scripts/parser/features/number_separators.gd b/modules/gdscript/tests/scripts/parser/features/number_separators.gd index f5f5661caef..a534c4fde14 100644 --- a/modules/gdscript/tests/scripts/parser/features/number_separators.gd +++ b/modules/gdscript/tests/scripts/parser/features/number_separators.gd @@ -1,12 +1,26 @@ func test(): # `_` can be used as a separator for numbers in GDScript. # It can be placed anywhere in the number, except at the beginning. - # Currently, GDScript in the `master` branch only allows using one separator - # per number. - # Results are assigned to variables to avoid warnings. - var __ = 1_23 - __ = 123_ # Trailing number separators are OK. - __ = 12_3 - __ = 123_456 - __ = 0x1234_5678 - __ = 0b1001_0101 + print(1_23) + print(12_3) + print(1_2_3) + print(123_) # Trailing number separators are OK. + print(123_456) + print(123_45_6_) + print("---") + print(0x1234_00ff) + print(0x1234_00_f_f_) + print(0b1001_0101) + print(0b1001_01_0_1_) + print("---") + print(-1_234.456_7) + print(-1_23_4_.4_56_7_) + print(-1_234.) + print(-1_23_4_.) + print(.456_7) + print(.4_56_7_) + print("---") + print(-1_234.5e000_3) + print(-1_23_4_.5e0_00_3_) + print(-1_234.5e+000_3) + print(-1_23_4_.5e+0_00_3_) diff --git a/modules/gdscript/tests/scripts/parser/features/number_separators.out b/modules/gdscript/tests/scripts/parser/features/number_separators.out index d73c5eb7cde..b0d2fd94fe9 100644 --- a/modules/gdscript/tests/scripts/parser/features/number_separators.out +++ b/modules/gdscript/tests/scripts/parser/features/number_separators.out @@ -1 +1,24 @@ GDTEST_OK +123 +123 +123 +123 +123456 +123456 +--- +305398015 +305398015 +149 +149 +--- +-1234.4567 +-1234.4567 +-1234 +-1234 +0.4567 +0.4567 +--- +-1234500 +-1234500 +-1234500 +-1234500