From c2c59495b3450934ddb8c95d8e8612ac582bc104 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Wed, 23 Aug 2023 19:34:09 -0700 Subject: [PATCH] lexer: add support for binary number literals --- grammar.txt | 15 +++++++++++---- lexer.cpp | 26 +++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/grammar.txt b/grammar.txt index a09e048..2b4fabf 100644 --- a/grammar.txt +++ b/grammar.txt @@ -6,12 +6,19 @@ unary → ( "~" | "+" | "-" ) unary shift → andl ( ( "<<" | ">>" ) andl )* andl → orl ( "&" orl )* orl → andl ( ( "|" | "^" ) andl )* -primary → NUMBER +primary → number | "(" expression ")" -uimm8 → expression -uimm19 → expression -uimm25 → expression +number → "%" base2-number + | "$" base16-number + | "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 diff --git a/lexer.cpp b/lexer.cpp index cbc28f9..7f44134 100644 --- a/lexer.cpp +++ b/lexer.cpp @@ -53,6 +53,19 @@ constexpr static N parse_number(const std::string_view s) return n; } +struct bin_t { + constexpr static bool pred(const char c) + { + return c >= '0' && c <= '1'; + } + + template + constexpr static N parse(const std::string_view s) + { + return parse_number(s); + } +}; + struct dec_t { constexpr static bool pred(const char c) { @@ -159,7 +172,6 @@ std::optional lexer_t::lex_token() case '-': return {{pos, minus, lexeme()}}; case '*': return {{pos, star, lexeme()}}; case '/': return {{pos, slash, lexeme()}}; - case '%': return {{pos, percent, lexeme()}}; case '~': return {{pos, tilde, lexeme()}}; case '&': return {{pos, ampersand, lexeme()}}; case '|': return {{pos, bar, lexeme()}}; @@ -188,6 +200,13 @@ std::optional lexer_t::lex_token() return {{tmp, eol, lexeme()}}; } break; + case '%': + if (bin_t::pred(peek())) { + start_ix += 1; + return {_number()}; + } else { + return {{pos, percent, lexeme()}}; + } case '$': if (hex_t::pred(peek())) { start_ix += 1; @@ -200,6 +219,11 @@ std::optional lexer_t::lex_token() start_ix += 2; return {_number()}; } + } else if (match('b')) { + if (bin_t::pred(peek())) { + start_ix += 2; + return {_number()}; + } } [[fallthrough]]; default: