fix: float and int literals

This commit is contained in:
TopchetoEU 2022-10-11 13:12:42 +03:00
parent 1190f09e3a
commit a8cda64516
2 changed files with 24 additions and 25 deletions

View File

@ -15,7 +15,7 @@ struct res_t {
bool _repeat; bool _repeat;
bool _add; bool _add;
res_t add(bool val = false) { res_t add(bool val = true) {
this->_add = val; this->_add = val;
return *this; return *this;
} }
@ -26,14 +26,14 @@ struct res_t {
}; };
static bool isoct(char c) { static inline bool isoct(char c) {
return c >= '0' && c <= '7'; return c >= '0' && c <= '7';
} }
static bool is_any(char c, std::string chars) { static inline bool is_any(char c, std::string chars) {
auto res = chars.find(c) != std::string::npos; auto res = chars.find(c) != std::string::npos;
return res; return res;
} }
static bool is_operator(char c) { static inline bool is_operator(char c) {
return is_any(c, "=!<>+-*/%&|^?:,.(){}[];"); return is_any(c, "=!<>+-*/%&|^?:,.(){}[];");
} }
@ -85,9 +85,9 @@ static res_t lexlet_dec(char c, std::vector<char> &tok) {
}; };
static res_t lexlet_zero(char c, std::vector<char> &tok) { static res_t lexlet_zero(char c, std::vector<char> &tok) {
if (c == '.') return lexer_switch(lexlet_float); if (c == '.') return lexer_switch(lexlet_float).add();
else if (c == 'b') return lexer_switch(lexlet_bin); else if (c == 'b') return lexer_switch(lexlet_bin).add();
else if (c == 'x') return lexer_switch(lexlet_hex); else if (c == 'x') return lexer_switch(lexlet_hex).add();
else if (isdigit(c)) return lexer_switch(lexlet_oct, true); else if (isdigit(c)) return lexer_switch(lexlet_oct, true);
else return lexer_end(token_t::DEC_LITERAL); else return lexer_end(token_t::DEC_LITERAL);
}; };
@ -107,11 +107,14 @@ static res_t lexlet_multicomment(char c, std::vector<char> &tok) {
static res_t lexlet_operator(char c, std::vector<char> &tok) { static res_t lexlet_operator(char c, std::vector<char> &tok) {
bool failed = false; bool failed = false;
if (tok.size() > 0) { if (tok.size() > 0) {
failed = true; failed = true;
char first_op = tok[0]; char first_op = tok[0];
size_t op_i = tok.size(); size_t op_i = tok.size();
if (first_op == '.' && isdigit(c)) return lexer_switch(lexlet_float).add();
if (first_op == c && op_i == 1 && is_any(c, ":+-&|?<>")) failed = false; if (first_op == c && op_i == 1 && is_any(c, ":+-&|?<>")) failed = false;
if (c == '=') { if (c == '=') {
if (op_i == 1 && is_any(first_op, "<>=!+-/*%")) failed = false; if (op_i == 1 && is_any(first_op, "<>=!+-/*%")) failed = false;
@ -138,18 +141,16 @@ static res_t lexlet_char(char c, std::vector<char> &tok) {
}; };
static res_t lexlet_default(char c, std::vector<char> &tok) { static res_t lexlet_default(char c, std::vector<char> &tok) {
tok.push_back(c); if (c == '"') return lexer_switch(lexlet_string).add();
if (c == '"') return lexer_switch(lexlet_string); if (c == '\'') return lexer_switch(lexlet_char).add();
if (c == '\'') return lexer_switch(lexlet_char); if (c == '0') return lexer_switch(lexlet_zero).add();
if (c == '0') return lexer_switch(lexlet_zero); if (is_operator(c)) return lexer_switch(lexlet_operator).add();
if (c == '.') return lexer_switch(lexlet_float); if (isdigit(c)) return lexer_switch(lexlet_dec).add();
if (is_operator(c)) return lexer_switch(lexlet_operator);
if (isdigit(c)) return lexer_switch(lexlet_dec);
if (isspace(c)) { if (isspace(c)) {
tok.clear(); tok.clear();
return lexer_none().add(false); return lexer_none().add(false);
} }
return lexer_switch(lexlet_identifier); return lexer_switch(lexlet_identifier).add();
}; };
std::vector<token_t> token_t::parse_many(ppc::messages::msg_stack_t &msg_stack, const std::string &filename, const std::string &_src) { std::vector<token_t> token_t::parse_many(ppc::messages::msg_stack_t &msg_stack, const std::string &filename, const std::string &_src) {

View File

@ -7,7 +7,7 @@ using namespace messages;
using namespace comp::tree; using namespace comp::tree;
using namespace std::string_literals; using namespace std::string_literals;
static std::vector<char> parse_string(msg_stack_t &msg_stack, bool is_char, lex::token_t token) { static std::vector<char> parse_string(msg_stack_t &msg_stack, bool is_char, const lex::token_t &token) {
char literal_char = is_char ? '\'' : '"'; char literal_char = is_char ? '\'' : '"';
bool escaping = false; bool escaping = false;
@ -52,7 +52,7 @@ static std::vector<char> parse_string(msg_stack_t &msg_stack, bool is_char, lex:
if (is_char) throw message_t(message_t::ERROR, "Unterminated char literal.", token.location); if (is_char) throw message_t(message_t::ERROR, "Unterminated char literal.", token.location);
else throw message_t(message_t::ERROR, "Unterminated string literal.", token.location); else throw message_t(message_t::ERROR, "Unterminated string literal.", token.location);
} }
static token_t parse_int(msg_stack_t &msg_stack, lex::token_t token) { static token_t parse_int(msg_stack_t &msg_stack, const lex::token_t &token) {
enum radix_t { enum radix_t {
BINARY, BINARY,
OCTAL, OCTAL,
@ -82,11 +82,9 @@ static token_t parse_int(msg_stack_t &msg_stack, lex::token_t token) {
throw "WTF r u doing bro?"s; throw "WTF r u doing bro?"s;
} }
std::size_t j = token.data.length() - 1;
uint64_t res = 0; uint64_t res = 0;
for (; i <= j; i++) { for (; i <= token.data.length() - 1; i++) {
char c = token.data[i]; char c = token.data[i];
int8_t digit; int8_t digit;
switch (radix) { switch (radix) {
@ -109,8 +107,8 @@ static token_t parse_int(msg_stack_t &msg_stack, lex::token_t token) {
res += digit; res += digit;
break; break;
case 3: case 3:
if (c >= 'a' && c <= 'f') digit = c - 'a' + 9; if (c >= 'a' && c <= 'f') digit = c - 'a' + 10;
else if (c >= 'A' && c <= 'F') digit = c - 'A' + 9; else if (c >= 'A' && c <= 'F') digit = c - 'A' + 10;
else if (c >= '0' && c <= '9') digit = c - '0'; else if (c >= '0' && c <= '9') digit = c - '0';
else throw message_t(message_t::ERROR, "Invalid character '"s + c + "' in hex literal.", token.location); else throw message_t(message_t::ERROR, "Invalid character '"s + c + "' in hex literal.", token.location);
res <<= 4; res <<= 4;
@ -121,13 +119,13 @@ static token_t parse_int(msg_stack_t &msg_stack, lex::token_t token) {
return token_t(res, token.location); return token_t(res, token.location);
} }
static token_t parse_float(msg_stack_t &msg_stack, lex::token_t token) { static token_t parse_float(msg_stack_t &msg_stack, const lex::token_t &token) {
double whole = 0, fract = 0; double whole = 0, fract = 0;
char c; char c;
std::size_t i; std::size_t i;
for (i = 0; i < token.data.length() && ((c = token.data[i]) > '0' && c < '9'); i++) { for (i = 0; i < token.data.length() && isdigit(c = token.data[i]); i++) {
if (c == '.') break; if (c == '.') break;
int digit = c - '0'; int digit = c - '0';
whole *= 10; whole *= 10;
@ -136,7 +134,7 @@ static token_t parse_float(msg_stack_t &msg_stack, lex::token_t token) {
if (c == '.') { if (c == '.') {
i++; i++;
for (; i < token.data.length() && ((c = token.data[i]) > '0' && c < '9'); i++) { for (; i < token.data.length() && isdigit(c = token.data[i]); i++) {
int digit = c - '0'; int digit = c - '0';
fract += digit; fract += digit;
fract /= 10; fract /= 10;