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;
|
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 {
|
int String::to_int() const {
|
||||||
|
|
||||||
if (length() == 0)
|
if (length() == 0)
|
||||||
|
|
|
@ -251,6 +251,7 @@ public:
|
||||||
int to_int() const;
|
int to_int() const;
|
||||||
|
|
||||||
int64_t hex_to_int64(bool p_with_prefix = true) 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;
|
int64_t to_int64() const;
|
||||||
static int to_int(const char *p_str, int p_len = -1);
|
static int to_int(const char *p_str, int p_len = -1);
|
||||||
static double to_double(const char *p_str);
|
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'));
|
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> GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) {
|
||||||
Map<int, TextEdit::HighlighterInfo> color_map;
|
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_member_variable = false;
|
||||||
bool in_node_path = false;
|
bool in_node_path = false;
|
||||||
bool is_hex_notation = false;
|
bool is_hex_notation = false;
|
||||||
|
bool is_bin_notation = false;
|
||||||
bool expect_type = false;
|
bool expect_type = false;
|
||||||
Color keyword_color;
|
Color keyword_color;
|
||||||
Color color;
|
Color color;
|
||||||
|
@ -118,14 +123,26 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_
|
||||||
is_hex_notation = false;
|
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
|
// 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_number = true;
|
||||||
is_symbol = false;
|
is_symbol = false;
|
||||||
is_char = false;
|
is_char = false;
|
||||||
|
|
||||||
if (str[j] == 'x' && str[j - 1] == '0') {
|
if (str[j] == 'x' && str[j - 1] == '0') {
|
||||||
is_hex_notation = true;
|
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');
|
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) {
|
void GDScriptTokenizerText::_make_token(Token p_type) {
|
||||||
|
|
||||||
TokenData &tk = tk_rb[tk_rb_pos];
|
TokenData &tk = tk_rb[tk_rb_pos];
|
||||||
|
@ -877,6 +882,7 @@ void GDScriptTokenizerText::_advance() {
|
||||||
bool period_found = false;
|
bool period_found = false;
|
||||||
bool exponent_found = false;
|
bool exponent_found = false;
|
||||||
bool hexa_found = false;
|
bool hexa_found = false;
|
||||||
|
bool bin_found = false;
|
||||||
bool sign_found = false;
|
bool sign_found = false;
|
||||||
|
|
||||||
String str;
|
String str;
|
||||||
|
@ -887,16 +893,28 @@ void GDScriptTokenizerText::_advance() {
|
||||||
if (period_found || exponent_found) {
|
if (period_found || exponent_found) {
|
||||||
_make_error("Invalid numeric constant at '.'");
|
_make_error("Invalid numeric constant at '.'");
|
||||||
return;
|
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;
|
period_found = true;
|
||||||
} else if (GETCHAR(i) == 'x') {
|
} 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'");
|
_make_error("Invalid numeric constant at 'x'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hexa_found = true;
|
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') {
|
} else if (!hexa_found && GETCHAR(i) == 'e') {
|
||||||
if (exponent_found) {
|
if (exponent_found || bin_found) {
|
||||||
_make_error("Invalid numeric constant at 'e'");
|
_make_error("Invalid numeric constant at 'e'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -905,6 +923,8 @@ void GDScriptTokenizerText::_advance() {
|
||||||
//all ok
|
//all ok
|
||||||
} else if (hexa_found && _is_hex(GETCHAR(i))) {
|
} else if (hexa_found && _is_hex(GETCHAR(i))) {
|
||||||
|
|
||||||
|
} else if (bin_found && _is_bin(GETCHAR(i))) {
|
||||||
|
|
||||||
} else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) {
|
} else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) {
|
||||||
if (sign_found) {
|
if (sign_found) {
|
||||||
_make_error("Invalid numeric constant at '-'");
|
_make_error("Invalid numeric constant at '-'");
|
||||||
|
@ -930,6 +950,9 @@ void GDScriptTokenizerText::_advance() {
|
||||||
if (hexa_found) {
|
if (hexa_found) {
|
||||||
int64_t val = str.hex_to_int64();
|
int64_t val = str.hex_to_int64();
|
||||||
_make_constant(val);
|
_make_constant(val);
|
||||||
|
} else if (bin_found) {
|
||||||
|
int64_t val = str.bin_to_int64();
|
||||||
|
_make_constant(val);
|
||||||
} else if (period_found || exponent_found) {
|
} else if (period_found || exponent_found) {
|
||||||
double val = str.to_double();
|
double val = str.to_double();
|
||||||
_make_constant(val);
|
_make_constant(val);
|
||||||
|
|
Loading…
Reference in a new issue