Merge pull request #28416 from JellyWX/binary-literals

Support for binary literals in GDScript
This commit is contained in:
Rémi Verschelde 2019-05-29 08:41:05 +02:00 committed by GitHub
commit 36591b1ae8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 83 additions and 3 deletions

View file

@ -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)

View file

@ -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);

View file

@ -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;
} }
} }

View file

@ -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);