lexer: add support for binary number literals

This commit is contained in:
Zack Buhman 2023-08-23 19:34:09 -07:00
parent 118942521e
commit c2c59495b3
2 changed files with 36 additions and 5 deletions

View File

@ -6,12 +6,19 @@ unary → ( "~" | "+" | "-" ) unary
shift → andl ( ( "<<" | ">>" ) andl )* shift → andl ( ( "<<" | ">>" ) andl )*
andl → orl ( "&" orl )* andl → orl ( "&" orl )*
orl → andl ( ( "|" | "^" ) andl )* orl → andl ( ( "|" | "^" ) andl )*
primary → NUMBER primary → number
| "(" expression ")" | "(" expression ")"
uimm8 → expression number → "%" base2-number
uimm19 → expression | "$" base16-number
uimm25 → expression | "0b" base2-number
| "0x" base16-number
| base10-number
imm → ("#")? expression
uimm8 → imm
uimm19 → imm
uimm25 → imm
alu → and | or | xor | add | sub | ad2 | sr | rr | sl | rl | rl8 alu → and | or | xor | add | sub | ad2 | sr | rr | sl | rl | rl8

View File

@ -53,6 +53,19 @@ constexpr static N parse_number(const std::string_view s)
return n; return n;
} }
struct bin_t {
constexpr static bool pred(const char c)
{
return c >= '0' && c <= '1';
}
template <typename N>
constexpr static N parse(const std::string_view s)
{
return parse_number<N, 2>(s);
}
};
struct dec_t { struct dec_t {
constexpr static bool pred(const char c) constexpr static bool pred(const char c)
{ {
@ -159,7 +172,6 @@ std::optional<token_t> lexer_t::lex_token()
case '-': return {{pos, minus, lexeme()}}; case '-': return {{pos, minus, lexeme()}};
case '*': return {{pos, star, lexeme()}}; case '*': return {{pos, star, lexeme()}};
case '/': return {{pos, slash, lexeme()}}; case '/': return {{pos, slash, lexeme()}};
case '%': return {{pos, percent, lexeme()}};
case '~': return {{pos, tilde, lexeme()}}; case '~': return {{pos, tilde, lexeme()}};
case '&': return {{pos, ampersand, lexeme()}}; case '&': return {{pos, ampersand, lexeme()}};
case '|': return {{pos, bar, lexeme()}}; case '|': return {{pos, bar, lexeme()}};
@ -188,6 +200,13 @@ std::optional<token_t> lexer_t::lex_token()
return {{tmp, eol, lexeme()}}; return {{tmp, eol, lexeme()}};
} }
break; break;
case '%':
if (bin_t::pred(peek())) {
start_ix += 1;
return {_number<bin_t>()};
} else {
return {{pos, percent, lexeme()}};
}
case '$': case '$':
if (hex_t::pred(peek())) { if (hex_t::pred(peek())) {
start_ix += 1; start_ix += 1;
@ -200,6 +219,11 @@ std::optional<token_t> lexer_t::lex_token()
start_ix += 2; start_ix += 2;
return {_number<hex_t>()}; return {_number<hex_t>()};
} }
} else if (match('b')) {
if (bin_t::pred(peek())) {
start_ix += 2;
return {_number<bin_t>()};
}
} }
[[fallthrough]]; [[fallthrough]];
default: default: