summaryrefslogtreecommitdiff
path: root/core/math/expression.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/math/expression.cpp')
-rw-r--r--core/math/expression.cpp68
1 files changed, 47 insertions, 21 deletions
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 203566579d..0ddac9744e 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -37,10 +37,6 @@
#include "core/os/os.h"
#include "core/variant/variant_parser.h"
-static bool _is_number(char32_t c) {
- return (c >= '0' && c <= '9');
-}
-
Error Expression::_get_token(Token &r_token) {
while (true) {
#define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++])
@@ -88,7 +84,7 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_INPUT;
int index = 0;
do {
- if (!_is_number(expression[str_ofs])) {
+ if (!is_digit(expression[str_ofs])) {
_set_error("Expected number after '$'");
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
@@ -97,7 +93,7 @@ Error Expression::_get_token(Token &r_token) {
index += expression[str_ofs] - '0';
str_ofs++;
- } while (_is_number(expression[str_ofs]));
+ } while (is_digit(expression[str_ofs]));
r_token.value = index;
return OK;
@@ -247,13 +243,13 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
- if (!(_is_number(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
+ if (!is_hex_digit(c)) {
_set_error("Malformed hex constant in string");
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
char32_t v;
- if (_is_number(c)) {
+ if (is_digit(c)) {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
v = c - 'a';
@@ -328,39 +324,67 @@ Error Expression::_get_token(Token &r_token) {
}
char32_t next_char = (str_ofs >= expression.length()) ? 0 : expression[str_ofs];
- if (_is_number(cchar) || (cchar == '.' && _is_number(next_char))) {
+ if (is_digit(cchar) || (cchar == '.' && is_digit(next_char))) {
//a number
String num;
#define READING_SIGN 0
#define READING_INT 1
-#define READING_DEC 2
-#define READING_EXP 3
-#define READING_DONE 4
+#define READING_HEX 2
+#define READING_BIN 3
+#define READING_DEC 4
+#define READING_EXP 5
+#define READING_DONE 6
int reading = READING_INT;
char32_t c = cchar;
bool exp_sign = false;
bool exp_beg = false;
+ bool bin_beg = false;
+ bool hex_beg = false;
bool is_float = false;
+ bool is_first_char = true;
while (true) {
switch (reading) {
case READING_INT: {
- if (_is_number(c)) {
- //pass
+ if (is_digit(c)) {
+ if (is_first_char && c == '0') {
+ if (next_char == 'b') {
+ reading = READING_BIN;
+ } else if (next_char == 'x') {
+ reading = READING_HEX;
+ }
+ }
} else if (c == '.') {
reading = READING_DEC;
is_float = true;
} else if (c == 'e') {
reading = READING_EXP;
+ is_float = true;
} else {
reading = READING_DONE;
}
} break;
+ case READING_BIN: {
+ if (bin_beg && !is_binary_digit(c)) {
+ reading = READING_DONE;
+ } else if (c == 'b') {
+ bin_beg = true;
+ }
+
+ } break;
+ case READING_HEX: {
+ if (hex_beg && !is_hex_digit(c)) {
+ reading = READING_DONE;
+ } else if (c == 'x') {
+ hex_beg = true;
+ }
+
+ } break;
case READING_DEC: {
- if (_is_number(c)) {
+ if (is_digit(c)) {
} else if (c == 'e') {
reading = READING_EXP;
@@ -370,13 +394,10 @@ Error Expression::_get_token(Token &r_token) {
} break;
case READING_EXP: {
- if (_is_number(c)) {
+ if (is_digit(c)) {
exp_beg = true;
} else if ((c == '-' || c == '+') && !exp_sign && !exp_beg) {
- if (c == '-') {
- is_float = true;
- }
exp_sign = true;
} else {
@@ -390,6 +411,7 @@ Error Expression::_get_token(Token &r_token) {
}
num += String::chr(c);
c = GET_CHAR();
+ is_first_char = false;
}
str_ofs--;
@@ -398,16 +420,20 @@ Error Expression::_get_token(Token &r_token) {
if (is_float) {
r_token.value = num.to_float();
+ } else if (bin_beg) {
+ r_token.value = num.bin_to_int();
+ } else if (hex_beg) {
+ r_token.value = num.hex_to_int();
} else {
r_token.value = num.to_int();
}
return OK;
- } else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') {
+ } else if (is_ascii_char(cchar) || is_underscore(cchar)) {
String id;
bool first = true;
- while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && _is_number(cchar))) {
+ while (is_ascii_char(cchar) || is_underscore(cchar) || (!first && is_digit(cchar))) {
id += String::chr(cchar);
cchar = GET_CHAR();
first = false;