diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-06-18 16:27:16 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-06-18 16:27:16 +0200 |
commit | 1ce2425c0efe2c8ce245d62adb3001040e44d0ab (patch) | |
tree | 005801e6ba23ba87e7060bbf41ee2bea98c87b5e | |
parent | 11ee6fcef06beea2a2ff2214003e71a45875a695 (diff) | |
parent | d15511725acdfe90f9d5967119294b591becd8fa (diff) | |
download | redot-engine-1ce2425c0efe2c8ce245d62adb3001040e44d0ab.tar.gz |
Merge pull request #73363 from dalexeev/gds-fix-min-int-not-representable
GDScript: Fix `MIN_INT` not representable as numeric literal
4 files changed, 66 insertions, 0 deletions
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 075e104cde..04509b7a9b 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -163,6 +163,24 @@ const char *GDScriptTokenizer::Token::get_name() const { return token_names[type]; } +bool GDScriptTokenizer::Token::can_precede_bin_op() const { + switch (type) { + case IDENTIFIER: + case LITERAL: + case SELF: + case BRACKET_CLOSE: + case BRACE_CLOSE: + case PARENTHESIS_CLOSE: + case CONST_PI: + case CONST_TAU: + case CONST_INF: + case CONST_NAN: + return true; + default: + return false; + } +} + bool GDScriptTokenizer::Token::is_identifier() const { // Note: Most keywords should not be recognized as identifiers. // These are only exceptions for stuff that already is on the engine's API. @@ -383,6 +401,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::make_token(Token::Type p_type) { } } + last_token = token; return token; } @@ -628,6 +647,7 @@ void GDScriptTokenizer::newline(bool p_make_token) { newline.leftmost_column = newline.start_column; newline.rightmost_column = newline.end_column; pending_newline = true; + last_token = newline; last_newline = newline; } @@ -644,6 +664,11 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() { bool has_error = false; bool (*digit_check_func)(char32_t) = is_digit; + // Sign before hexadecimal or binary. + if ((_peek(-1) == '+' || _peek(-1) == '-') && _peek() == '0') { + _advance(); + } + if (_peek(-1) == '.') { has_decimal = true; } else if (_peek(-1) == '0') { @@ -1463,6 +1488,9 @@ GDScriptTokenizer::Token GDScriptTokenizer::scan() { if (_peek() == '=') { _advance(); return make_token(Token::PLUS_EQUAL); + } else if (is_digit(_peek()) && !last_token.can_precede_bin_op()) { + // Number starting with '+'. + return number(); } else { return make_token(Token::PLUS); } @@ -1470,6 +1498,9 @@ GDScriptTokenizer::Token GDScriptTokenizer::scan() { if (_peek() == '=') { _advance(); return make_token(Token::MINUS_EQUAL); + } else if (is_digit(_peek()) && !last_token.can_precede_bin_op()) { + // Number starting with '-'. + return number(); } else if (_peek() == '>') { _advance(); return make_token(Token::FORWARD_ARROW); diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 608840d3f1..068393cee9 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -171,6 +171,7 @@ public: String source; const char *get_name() const; + bool can_precede_bin_op() const; bool is_identifier() const; bool is_node_name() const; StringName get_identifier() const { return source; } @@ -216,6 +217,7 @@ private: bool multiline_mode = false; List<Token> error_stack; bool pending_newline = false; + Token last_token; Token last_newline; int pending_indents = 0; List<int> indent_stack; diff --git a/modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.gd b/modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.gd new file mode 100644 index 0000000000..cf7fb1518c --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.gd @@ -0,0 +1,17 @@ +func test(): + print(-9223372036854775808 == (1 << 63)) + print(-2) + print(- 2) + print(---2) + print(3 - 2) + print(3-2) + print(3---2) + print(-3 - 2) + print(-3 - -2) + print(-(3 - 2)-2) + print([1, 2, 3][0]-1) + var t = 1 + print(t-1) + print(-0xFF) + print(1--0xFF) + print(floor(PI-1)) diff --git a/modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.out b/modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.out new file mode 100644 index 0000000000..c5958365ec --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.out @@ -0,0 +1,16 @@ +GDTEST_OK +true +-2 +-2 +-2 +1 +1 +1 +-5 +-1 +-3 +0 +0 +-255 +256 +2 |