summaryrefslogtreecommitdiffhomepage
path: root/lexer.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-06-01 12:36:44 +0200
committerJo-Philipp Wich <jo@mein.io>2022-06-01 12:53:26 +0200
commitd99604749d658f5f344d53e77dd52fbb0f6d176c (patch)
tree2e60555dc4ce9e81b42b7556dd2e2491473f776c /lexer.c
parent9efbe183d7805eb60652a3745ec48cd32682ef8d (diff)
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 <jo@mein.io>
Diffstat (limited to 'lexer.c')
-rw-r--r--lexer.c34
1 files changed, 31 insertions, 3 deletions
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: