summaryrefslogtreecommitdiff
path: root/lex.c
diff options
context:
space:
mode:
authorWormHeamer2025-08-02 02:40:04 -0400
committerWormHeamer2025-08-02 02:40:04 -0400
commit86285533c637d673dc14d4e34530ce8864831600 (patch)
treea1f4a0a16708f8c8ecc3cb64a08ab47e1ab8d846 /lex.c
parent9455b73b42d0fb7100b9afd662818b0199ae510c (diff)
whole bunch of graph stuff, fixing up, basic arithmetic peepholes...
Diffstat (limited to 'lex.c')
-rw-r--r--lex.c22
1 files changed, 15 insertions, 7 deletions
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);