Browse Source

Added hex and bin literal support to Expression parser

fixed formatting
Hayden Leete 3 years ago
parent
commit
018de19eba
1 changed files with 44 additions and 4 deletions
  1. 44 4
      core/math/expression.cpp

+ 44 - 4
core/math/expression.cpp

@@ -41,6 +41,14 @@ static bool _is_number(char32_t c) {
 	return (c >= '0' && c <= '9');
 }
 
+static bool _is_hex_digit(char32_t c) {
+	return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
+}
+
+static bool _is_binary_digit(char32_t c) {
+	return (c == '0' || c == '1');
+}
+
 Error Expression::_get_token(Token &r_token) {
 	while (true) {
 #define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++])
@@ -334,21 +342,32 @@ Error Expression::_get_token(Token &r_token) {
 					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_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;
@@ -358,6 +377,22 @@ Error Expression::_get_token(Token &r_token) {
 									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)) {
@@ -390,6 +425,7 @@ Error Expression::_get_token(Token &r_token) {
 						}
 						num += String::chr(c);
 						c = GET_CHAR();
+						is_first_char = false;
 					}
 
 					str_ofs--;
@@ -398,6 +434,10 @@ 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();
 					}