From dbfb6ab16c6ff83291b9401a0432d814f9c6fda0 Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Sat, 2 Aug 2025 03:54:21 -0400 Subject: bunch of stuff to make error messages look more like gcc lol --- lex.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'lex.c') diff --git a/lex.c b/lex.c index a254e7b..7cfc1ec 100644 --- a/lex.c +++ b/lex.c @@ -48,13 +48,13 @@ void lex_expect_not(Lexer *l, TokMask t) { void lex_expected(Lexer *l, TokMask t) { if (!(TMASK(l->tok) & t)) { - lex_error(l, LE_ERROR, str_fmt(&l->arena, "Expected %S but got %s", lex_mask_str(l, t), lex_tok_str[l->tok])); + lex_error(l, LE_ERROR, str_fmt(&l->arena, "expected %S but got %s", lex_mask_str(l, t), lex_tok_str[l->tok])); } } void lex_expected_not(Lexer *l, TokMask t) { if (TMASK(l->tok) & t) { - lex_error(l, LE_ERROR, str_fmt(&l->arena, "Unexpected %s", lex_tok_str[l->tok])); + lex_error(l, LE_ERROR, str_fmt(&l->arena, "unexpected %s", lex_tok_str[l->tok])); } } @@ -81,14 +81,20 @@ void lex_error(Lexer *l, LexErr e, Str msg) { lex_error_at(l, l->pos, e, msg); } +void lex_err_color(LexErr e) { + fprintf(stderr, "%s", e == LE_NONE ? "\x1b[0m" : (e == LE_ERROR ? "\x1b[1;31m" : "\x1b[1;33m")); +} + void lex_error_at(Lexer *l, LexSpan pos, LexErr e, Str msg) { int line, col; lex_pos(l, pos.ofs, &line, &col); - fprintf(stderr, "%s", e == LE_ERROR ? "\x1b[1;31m" : "\x1b[1;33m"); - fprintf(stderr, "%.*s:%d:%d: %.*s\n\n", - (int)l->filename.n, l->filename.s, line + 1, col + 1, (int)msg.n, msg.s); + fprintf(stderr, "\x1b[1m%.*s:%d:%d:\x1b[0m ", (int)l->filename.n, l->filename.s, line + 1, col + 1); + lex_err_color(e); + if (e != LE_NONE) fprintf(stderr, "%s", e == LE_ERROR ? "error" : "warn"); + lex_err_color(LE_NONE); + fprintf(stderr, ": %.*s\n\n", (int)msg.n, msg.s); { int ofs = pos.ofs; @@ -96,13 +102,16 @@ void lex_error_at(Lexer *l, LexSpan pos, LexErr e, Str msg) { 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++; + lex_err_color(e); fprintf(stderr, "%.*s\n", line_end - line_start, &l->buf.s[line_start]); 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'); + fputc('^', stderr); + for (int i = ofs + 1; i < ofs + pos.n && i < line_end; i++) fputc('~', stderr); + lex_err_color(LE_NONE); + fputc('\n', stderr); } - fprintf(stderr, "\x1b[0m\n"); + fputc('\n', stderr); if (e == LE_ERROR) { exit(1); @@ -170,15 +179,15 @@ recurse: T(TOK_LIT_CHAR); if (i < l->buf.n && l->buf.s[i] == '\\') i += 2; else i++; - if (i >= l->buf.n) lex_error(l, LE_ERROR, S("Unterminated character literal")); - if (l->buf.s[i] != '\'') lex_error(l, LE_ERROR, S("Overlong character literal")); + if (i >= l->buf.n) lex_error(l, LE_ERROR, S("unterminated character literal")); + if (l->buf.s[i] != '\'') lex_error(l, LE_ERROR, S("overlong character literal")); i++; break; case '"': T(TOK_LIT_STR); for (;;) { if (i >= l->buf.n) { - lex_error(l, LE_ERROR, S("Unterminated string literal")); + lex_error(l, LE_ERROR, S("unterminated string literal")); } if (l->buf.s[i] == '\\') { i += 2; @@ -190,7 +199,7 @@ recurse: } } if (l->tok == TOK_MAX) { - lex_error(l, LE_ERROR, S("Invalid token")); + lex_error(l, LE_ERROR, S("parse error")); } l->ident.n = i - start_ofs; l->pos.n = i - start_ofs; -- cgit v1.2.3