diff options
-rw-r--r-- | src/lexer.c | 26 | ||||
-rw-r--r-- | src/lexer.h | 1 |
2 files changed, 27 insertions, 0 deletions
diff --git a/src/lexer.c b/src/lexer.c index 8b121b3..0aa318b 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -20,6 +20,12 @@ static bool skip_comment(const uchar **, const uchar *); static struct lexemes_soa mk_lexemes_soa(void); static void lexemes_soa_resz(struct lexemes_soa *); +static const bool is_numeric_lookup[UCHAR_MAX + 1] = { + ['0'] = true, ['1'] = true, ['2'] = true, ['3'] = true, + ['4'] = true, ['5'] = true, ['6'] = true, ['7'] = true, + ['8'] = true, ['9'] = true, ['\''] = true, +}; + struct lexemes_soa lexstring(const uchar *code, size_t codesz) { @@ -72,6 +78,26 @@ lexstring(const uchar *code, size_t codesz) } break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + data.kinds[data.len] = LEXNUM; + data.strs[data.len].p = spnbeg; + + while (likely(code < end) && is_numeric_lookup[code[0]]) { + if (unlikely(code[0] == '\'' && code[-1] == '\'')) { + err("Adjacent numeric separators at byte %td", + code - start); + } + code++; + } + if (unlikely(code < end && code[-1] == '\'')) { + err("Numeric literal ends with numeric separator at byte %td", + code - start); + } + + data.strs[data.len++].len = code - spnbeg; + break; + default: if (!rune_is_xids(ch)) continue; diff --git a/src/lexer.h b/src/lexer.h index 7fd8533..33c5078 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -8,6 +8,7 @@ enum { LEXIDENT, /* Identifier */ + LEXNUM, /* Numeric constant */ LEXAMP = '&', LEXCOLON = ':', |