diff options
| author | Mel <mel@rnrd.eu> | 2025-07-09 17:06:19 +0200 |
|---|---|---|
| committer | Mel <mel@rnrd.eu> | 2025-07-09 17:06:19 +0200 |
| commit | deb7edadc446653a70c03e9312bc949cc27ce8c4 (patch) | |
| tree | 235d39d33a39d6da0023c829aed413cdf743cf99 /boot/parse.c | |
| parent | efa510e6b58ce13c53e94f13a5be0007240e9dcc (diff) | |
| download | catskill-deb7edadc446653a70c03e9312bc949cc27ce8c4.tar.zst catskill-deb7edadc446653a70c03e9312bc949cc27ce8c4.zip | |
Multi-error display and fix up finding line boundries
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'boot/parse.c')
| -rw-r--r-- | boot/parse.c | 54 |
1 files changed, 28 insertions, 26 deletions
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); |
