From d99604749d658f5f344d53e77dd52fbb0f6d176c Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Wed, 1 Jun 2022 12:36:44 +0200 Subject: syntax: adjust number literal parsing and string to number conversion - Recognize new number literal prefixes `0o` and `0O` for octal as well as `0b` and `0B` for binary number literals - Treat number literals with leading zeros as octal while parsing but as decimal ones on implicit number conversions, means `012` will yield `10` while `+"012"` or `"012" + 0` will yield `12` Signed-off-by: Jo-Philipp Wich --- lexer.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'lexer.c') diff --git a/lexer.c b/lexer.c index 9ccc3ae..aae3e2f 100644 --- a/lexer.c +++ b/lexer.c @@ -696,10 +696,38 @@ is_numeric_char(uc_lexer_t *lex, char c) { char prev = lex->lookbehindlen ? lex->lookbehind[lex->lookbehindlen-1] : 0; - if ((prev == 'e' || prev == 'E') && (c == '-' || c == '+')) + switch (c|32) { + case '.': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': return true; - return prev ? (isxdigit(c) || c == 'x' || c == 'X' || c == '.') : (isdigit(c) || c == '.'); + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'o': + case 'x': + /* require previous char, a number literal cannot start with these */ + return prev != 0; + + case '+': + case '-': + /* sign is only allowed after an exponent char */ + return (prev|32) == 'e'; + } + + return false; } static uc_token_t * @@ -713,7 +741,7 @@ parse_number(uc_lexer_t *lex) if (!buf_remaining(lex) || !is_numeric_char(lex, lex->bufstart[0])) { lookbehind_append(lex, "\0", 1); - nv = uc_number_parse(lex->lookbehind, &e); + nv = uc_number_parse_octal(lex->lookbehind, &e); switch (ucv_type(nv)) { case UC_DOUBLE: -- cgit v1.2.3