commit 53f2eb16ec410428a1f9d61fa9fbd18db4f78642
parent 65ba9fee4f8cd4e963f1eb976286ff71ff882787
Author: Sebastian <sebastian@sebsite.pw>
Date: Fri, 17 Jun 2022 17:14:57 -0400
lex: fix number lexing
The following invalid number literals are now forbidden:
0x
0xz
0xu
0xu64
0be+0
0bf64
Fixes: https://todo.sr.ht/~sircmpwn/hare/514
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/lex.c b/src/lex.c
@@ -283,6 +283,7 @@ lex_literal(struct lexer *lexer, struct token *out)
uint32_t c = next(lexer, &out->loc, true);
assert(c != UTF8_INVALID && c <= 0x7F && isdigit(c));
+ bool started = false;
int base = 10;
const char *basechrs = "0123456789";
if (c == '0') {
@@ -303,9 +304,12 @@ lex_literal(struct lexer *lexer, struct token *out)
consume(lexer, 2);
break;
default:
+ started = true;
push(lexer, c, true);
break;
}
+ } else {
+ started = true;
}
char *suff = NULL;
@@ -315,6 +319,10 @@ lex_literal(struct lexer *lexer, struct token *out)
if (!strchr(basechrs, c)) {
switch (c) {
case '.':
+ if (!started) {
+ push(lexer, c, true);
+ goto finalize;
+ }
if (lexer->require_int) {
push(lexer, '.', true);
goto finalize;
@@ -333,6 +341,10 @@ lex_literal(struct lexer *lexer, struct token *out)
isfloat = true;
break;
case 'e':
+ if (!started) {
+ push(lexer, c, true);
+ goto finalize;
+ }
if (exp || suff) {
push(lexer, c, true);
goto finalize;
@@ -351,7 +363,7 @@ lex_literal(struct lexer *lexer, struct token *out)
case 'u':
case 'f':
case 'z':
- if (suff) {
+ if (suff || !started) {
push(lexer, c, true);
goto finalize;
}
@@ -363,9 +375,15 @@ lex_literal(struct lexer *lexer, struct token *out)
goto finalize;
}
}
+ started = true;
}
finalize:
+ if (!started) {
+ out->token = T_ERROR;
+ consume(lexer, -1);
+ return out->token;
+ }
lexer->require_int = false;
out->token = T_LITERAL;
if (isfloat) {