summaryrefslogtreecommitdiff
path: root/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'lex.c')
-rw-r--r--lex.c33
1 files changed, 21 insertions, 12 deletions
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;