Merge pull request #28416 from JellyWX/binary-literals
Support for binary literals in GDScript
This commit is contained in:
commit
36591b1ae8
4 changed files with 83 additions and 3 deletions
|
@ -1725,6 +1725,45 @@ int64_t String::hex_to_int64(bool p_with_prefix) const {
|
|||
return hex * sign;
|
||||
}
|
||||
|
||||
int64_t String::bin_to_int64(bool p_with_prefix) const {
|
||||
|
||||
if (p_with_prefix && length() < 3)
|
||||
return 0;
|
||||
|
||||
const CharType *s = ptr();
|
||||
|
||||
int64_t sign = s[0] == '-' ? -1 : 1;
|
||||
|
||||
if (sign < 0) {
|
||||
s++;
|
||||
}
|
||||
|
||||
if (p_with_prefix) {
|
||||
if (s[0] != '0' || s[1] != 'b')
|
||||
return 0;
|
||||
s += 2;
|
||||
}
|
||||
|
||||
int64_t binary = 0;
|
||||
|
||||
while (*s) {
|
||||
|
||||
CharType c = LOWERCASE(*s);
|
||||
int64_t n;
|
||||
if (c == '0' || c == '1') {
|
||||
n = c - '0';
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
binary *= 2;
|
||||
binary += n;
|
||||
s++;
|
||||
}
|
||||
|
||||
return binary * sign;
|
||||
}
|
||||
|
||||
int String::to_int() const {
|
||||
|
||||
if (length() == 0)
|
||||
|
|
|
@ -251,6 +251,7 @@ public:
|
|||
int to_int() const;
|
||||
|
||||
int64_t hex_to_int64(bool p_with_prefix = true) const;
|
||||
int64_t bin_to_int64(bool p_with_prefix = true) const;
|
||||
int64_t to_int64() const;
|
||||
static int to_int(const char *p_str, int p_len = -1);
|
||||
static double to_double(const char *p_str);
|
||||
|
|
|
@ -56,6 +56,10 @@ static bool _is_hex_symbol(CharType c) {
|
|||
return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
|
||||
}
|
||||
|
||||
static bool _is_bin_symbol(CharType c) {
|
||||
return (c == '0' || c == '1');
|
||||
}
|
||||
|
||||
Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) {
|
||||
Map<int, TextEdit::HighlighterInfo> color_map;
|
||||
|
||||
|
@ -76,6 +80,7 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_
|
|||
bool in_member_variable = false;
|
||||
bool in_node_path = false;
|
||||
bool is_hex_notation = false;
|
||||
bool is_bin_notation = false;
|
||||
bool expect_type = false;
|
||||
Color keyword_color;
|
||||
Color color;
|
||||
|
@ -118,14 +123,26 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_
|
|||
is_hex_notation = false;
|
||||
}
|
||||
|
||||
// disallow anything not a 0 or 1
|
||||
if (is_bin_notation && (_is_bin_symbol(str[j]))) {
|
||||
is_number = true;
|
||||
} else if (is_bin_notation) {
|
||||
is_bin_notation = false;
|
||||
is_number = false;
|
||||
} else {
|
||||
is_bin_notation = false;
|
||||
}
|
||||
|
||||
// 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] == 'e') && !in_word && prev_is_number && !is_number) {
|
||||
if ((str[j] == '.' || str[j] == 'x' || str[j] == 'b' || str[j] == '_' || str[j] == 'e') && !in_word && prev_is_number && !is_number) {
|
||||
is_number = true;
|
||||
is_symbol = false;
|
||||
is_char = false;
|
||||
|
||||
if (str[j] == 'x' && str[j - 1] == '0') {
|
||||
is_hex_notation = true;
|
||||
} else if (str[j] == 'b' && str[j - 1] == '0') {
|
||||
is_bin_notation = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -376,6 +376,11 @@ static bool _is_hex(CharType c) {
|
|||
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
|
||||
}
|
||||
|
||||
static bool _is_bin(CharType c) {
|
||||
|
||||
return (c == '0' || c == '1');
|
||||
}
|
||||
|
||||
void GDScriptTokenizerText::_make_token(Token p_type) {
|
||||
|
||||
TokenData &tk = tk_rb[tk_rb_pos];
|
||||
|
@ -877,6 +882,7 @@ void GDScriptTokenizerText::_advance() {
|
|||
bool period_found = false;
|
||||
bool exponent_found = false;
|
||||
bool hexa_found = false;
|
||||
bool bin_found = false;
|
||||
bool sign_found = false;
|
||||
|
||||
String str;
|
||||
|
@ -887,16 +893,28 @@ void GDScriptTokenizerText::_advance() {
|
|||
if (period_found || exponent_found) {
|
||||
_make_error("Invalid numeric constant at '.'");
|
||||
return;
|
||||
} else if (bin_found) {
|
||||
_make_error("Invalid binary constant at '.'");
|
||||
return;
|
||||
} else if (hexa_found) {
|
||||
_make_error("Invalid hexadecimal constant at '.'");
|
||||
return;
|
||||
}
|
||||
period_found = true;
|
||||
} else if (GETCHAR(i) == 'x') {
|
||||
if (hexa_found || str.length() != 1 || !((i == 1 && str[0] == '0') || (i == 2 && str[1] == '0' && str[0] == '-'))) {
|
||||
if (hexa_found || bin_found || str.length() != 1 || !((i == 1 && str[0] == '0') || (i == 2 && str[1] == '0' && str[0] == '-'))) {
|
||||
_make_error("Invalid numeric constant at 'x'");
|
||||
return;
|
||||
}
|
||||
hexa_found = true;
|
||||
} else if (GETCHAR(i) == 'b') {
|
||||
if (hexa_found || bin_found || str.length() != 1 || !((i == 1 && str[0] == '0') || (i == 2 && str[1] == '0' && str[0] == '-'))) {
|
||||
_make_error("Invalid numeric constant at 'b'");
|
||||
return;
|
||||
}
|
||||
bin_found = true;
|
||||
} else if (!hexa_found && GETCHAR(i) == 'e') {
|
||||
if (exponent_found) {
|
||||
if (exponent_found || bin_found) {
|
||||
_make_error("Invalid numeric constant at 'e'");
|
||||
return;
|
||||
}
|
||||
|
@ -905,6 +923,8 @@ void GDScriptTokenizerText::_advance() {
|
|||
//all ok
|
||||
} else if (hexa_found && _is_hex(GETCHAR(i))) {
|
||||
|
||||
} else if (bin_found && _is_bin(GETCHAR(i))) {
|
||||
|
||||
} else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) {
|
||||
if (sign_found) {
|
||||
_make_error("Invalid numeric constant at '-'");
|
||||
|
@ -930,6 +950,9 @@ void GDScriptTokenizerText::_advance() {
|
|||
if (hexa_found) {
|
||||
int64_t val = str.hex_to_int64();
|
||||
_make_constant(val);
|
||||
} else if (bin_found) {
|
||||
int64_t val = str.bin_to_int64();
|
||||
_make_constant(val);
|
||||
} else if (period_found || exponent_found) {
|
||||
double val = str.to_double();
|
||||
_make_constant(val);
|
||||
|
|
Loading…
Reference in a new issue