harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 4361a31c8aac9e9f0663ced216b6b58af74bda2f
parent 99d77e15fc16eaa2eb0781893034d5aefa8b7241
Author: Sebastian <sebastian@sebsite.pw>
Date:   Fri, 29 Apr 2022 23:24:00 -0400

lex: fix nested tuple access lexing

Given a tuple named t, the expression t.0.1 now works as intended,
rather than erroring because 0.1 was lexed as a floating point literal.
This is done by requiring that a number literal lexed immediately after
a dot token is an integer.

Fixes: https://todo.sr.ht/~sircmpwn/hare/376
Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Minclude/lex.h | 1+
Msrc/lex.c | 16++++++++++++----
Mtests/21-tuples.ha | 6++++--
3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/include/lex.h b/include/lex.h @@ -168,6 +168,7 @@ struct lexer { struct token un; struct location loc; bool disable_labels; + bool require_int; }; void lex_init(struct lexer *lexer, FILE *f, const char *filename); diff --git a/src/lex.c b/src/lex.c @@ -315,6 +315,10 @@ lex_literal(struct lexer *lexer, struct token *out) if (!strchr(basechrs, c)) { switch (c) { case '.': + if (lexer->require_int) { + push(lexer, '.', true); + goto finalize; + } if (isfloat || suff || exp) { push(lexer, c, true); goto finalize; @@ -362,6 +366,7 @@ lex_literal(struct lexer *lexer, struct token *out) } finalize: + lexer->require_int = false; out->token = T_LITERAL; if (isfloat) { out->storage = STORAGE_FCONST; @@ -648,6 +653,7 @@ lex3(struct lexer *lexer, struct token *out, uint32_t c) default: push(lexer, c, false); out->token = T_DOT; + lexer->require_int = true; break; } break; @@ -912,14 +918,16 @@ _lex(struct lexer *lexer, struct token *out) return out->token; } - if (c <= 0x7F && (isalpha(c) || c == '_' || c == '@')) { + if (c <= 0x7F && isdigit(c)) { push(lexer, c, false); - return lex_name(lexer, out); + return lex_literal(lexer, out); } - if (c <= 0x7F && isdigit(c)) { + lexer->require_int = false; + + if (c <= 0x7F && (isalpha(c) || c == '_' || c == '@')) { push(lexer, c, false); - return lex_literal(lexer, out); + return lex_name(lexer, out); } char p[5]; diff --git a/tests/21-tuples.ha b/tests/21-tuples.ha @@ -6,8 +6,10 @@ fn storage() void = { }; fn indexing() void = { - let x: (int, size) = (42, 1337); - assert(x.0 == 42 && x.1 == 1337); + let x: ((int, uint), size) = ((42, 69), 1337); + assert(x.0.0 == 42); + assert(x.0.1 == 69); + assert(x.1 == 1337); }; fn func(in: (int, size)) (int, size) = (in.0 + 1, in.1 + 1);