From deb7edadc446653a70c03e9312bc949cc27ce8c4 Mon Sep 17 00:00:00 2001 From: Mel Date: Wed, 9 Jul 2025 17:06:19 +0200 Subject: Multi-error display and fix up finding line boundries Signed-off-by: Mel --- boot/parse.c | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'boot/parse.c') diff --git a/boot/parse.c b/boot/parse.c index 6daca8f..2891a0f 100644 --- a/boot/parse.c +++ b/boot/parse.c @@ -103,18 +103,13 @@ token_span_to_line_span(struct Span span, struct String source) Pos line_start = span.start + 1, line_end = span.end - 1; // expand `line_start` to start from the beginning of the line, // and `line_end` to end at the end of the line. - ascii c; - if (line_start > 0) { - do { - c = string_at(source, line_start - 1); - line_start--; - } while (line_start > 0 && c != '\n'); + while (line_start > 0) { + if (string_at(source, line_start - 1) == '\n') break; + line_start--; } - if (line_end < string_length(source)) { - do { - c = string_at(source, line_end + 1); - line_end++; - } while (line_end < string_length(source) && c != '\n'); + while (line_end < string_length(source)) { + if (string_at(source, line_end) == '\n') break; + line_end++; } return span_new(line_start, line_end); @@ -137,13 +132,13 @@ parser_error_display(const struct Parser_Error* error, struct Source_File source fprintf(stderr, ANSI_WHITE "%s:%lu:%lu:\n", source_file.path.data, line, column); fprintf(stderr, ANSI_BOLD ANSI_RED "error: " ANSI_WHITE); if (error->subkind != PARSER_ERROR_NONE) { - fprintf(stderr, "%s: %s ", parser_error_kind_to_string(error->kind), + fprintf(stderr, "%s: %s", parser_error_kind_to_string(error->kind), parser_error_kind_to_string(error->subkind)); } else { - fprintf(stderr, "%s ", parser_error_kind_to_string(error->kind)); + fprintf(stderr, "%s", parser_error_kind_to_string(error->kind)); } // TODO: display tokens nicely - fprintf(stderr, "'%s' :(\n", token_kind_to_string(cause.kind)); + fprintf(stderr, ", got '%s' :(\n", token_kind_to_string(cause.kind)); struct Span line_span = token_span_to_line_span(cause.span, source_file.source); @@ -151,7 +146,9 @@ parser_error_display(const struct Parser_Error* error, struct Source_File source int source_line_length = line_span.end - line_span.start; fprintf(stderr, ANSI_WHITE ANSI_NO_BOLD "%lu| %.*s\n", line, source_line_length, source_line); - fprintf(stderr, ANSI_RED "%*s", (int)column + 3 - 1, " "); // +3 for the line number and space + + uint line_number_length = ceil(log10(line + 1)); + fprintf(stderr, ANSI_RED "%*s", (int)(column + 1 + line_number_length), " "); for (uint w = 0; w < span_length(cause.span); w++) { fprintf(stderr, "^"); } fprintf(stderr, "\n" ANSI_RESET); } @@ -1475,23 +1472,28 @@ parser_do_your_thing(struct Parser* p, struct Tree* tree) parser_error_none(&error); struct Statement* head = nil; - struct Statement* current = nil; while (!parser_reached_end(p)) { struct Statement* next = parser_statement(p, &error); parser_handle_error(p, &error); - if (!next) break; // on eof - - parser_end_statement(p, &error); - parser_handle_error(p, &error); - - if (current) { - current->next = next; - } else { - head = next; + if (next) { + parser_end_statement(p, &error); + + if (parser_error_is_none(&error)) { + if (current) { + current->next = next; + } else { + head = next; + } + current = next; + } else { + parser_handle_error(p, &error); + } + } else if (parser_reached_end(p)) { + // `parser_statement` returns nil on EOF. + break; } - current = next; } parser_error_none(&error); -- cgit 1.4.1