From 86285533c637d673dc14d4e34530ce8864831600 Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Sat, 2 Aug 2025 02:40:04 -0400 Subject: whole bunch of graph stuff, fixing up, basic arithmetic peepholes... --- lex.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'lex.c') diff --git a/lex.c b/lex.c index 12cd284..a254e7b 100644 --- a/lex.c +++ b/lex.c @@ -6,6 +6,7 @@ #include "strio.h" void lex_start(Lexer *l, const char *path) { + l->ofs = 0; l->filename = str_dup(str_from_cstr(path), &l->arena); FILE *f = fopen(path, "r/o"); if (!f) { @@ -57,9 +58,11 @@ void lex_expected_not(Lexer *l, TokMask t) { } } -void lex_pos(Lexer *l, int *line, int *col) { +/* should only be called in the event of errors, so probably not + * much of an issue that this has to scan the whole file */ +void lex_pos(Lexer *l, int ofs, int *line, int *col) { int ln = 0, c = 0; - for (int i = 0; i < l->ofs; i++) { + for (int i = 0; i < ofs; i++) { if (l->buf.s[i] == '\n') { ln++; c = 0; @@ -75,9 +78,12 @@ void lex_pos(Lexer *l, int *line, int *col) { } void lex_error(Lexer *l, LexErr e, Str msg) { + lex_error_at(l, l->pos, e, msg); +} + +void lex_error_at(Lexer *l, LexSpan pos, LexErr e, Str msg) { int line, col; - l->ofs -= l->ident.n; - lex_pos(l, &line, &col); + lex_pos(l, pos.ofs, &line, &col); fprintf(stderr, "%s", e == LE_ERROR ? "\x1b[1;31m" : "\x1b[1;33m"); @@ -85,14 +91,14 @@ void lex_error(Lexer *l, LexErr e, Str msg) { (int)l->filename.n, l->filename.s, line + 1, col + 1, (int)msg.n, msg.s); { - int ofs = l->ofs; + int ofs = pos.ofs; int line_start = ofs; while (line_start > 0 && l->buf.s[line_start - 1] != '\n') line_start--; int line_end = line_start; while (line_end < l->buf.n && l->buf.s[line_end] != '\n') line_end++; fprintf(stderr, "%.*s\n", line_end - line_start, &l->buf.s[line_start]); - for (int i = 0; i < col; i++) putchar(' '); - for (int i = ofs; i < ofs + l->ident.n && i < line_end; i++) putchar('^'); + for (int i = 0; i < col; i++) fputc(' ', stderr); + for (int i = ofs; i < ofs + pos.n && i < line_end; i++) fputc('^', stderr); putchar('\n'); } @@ -142,6 +148,7 @@ recurse: int start_ofs = i; l->ident = (Str) { &l->buf.s[start_ofs], 0 }; + l->pos = (LexSpan) { start_ofs, 0 }; if (i >= l->buf.n) { l->tok = TOK_EOF; return; @@ -186,6 +193,7 @@ recurse: lex_error(l, LE_ERROR, S("Invalid token")); } l->ident.n = i - start_ofs; + l->pos.n = i - start_ofs; l->ofs = i; if (l->tok == TOK_IDENT) { l->tok = ident_to_keyword(l->ident); -- cgit v1.2.3