diff options
| author | Mel <mel@rnrd.eu> | 2026-05-24 18:18:23 +0200 |
|---|---|---|
| committer | Mel <mel@rnrd.eu> | 2026-05-24 18:18:23 +0200 |
| commit | a76fd9b5af153773273121c7aec2a9cbeed1dfb7 (patch) | |
| tree | a6c619e44df4f38f60c457b9122e207b0a3c09f0 /boot/parse.c | |
| parent | 8c4c219c945dfb41415e04654f488f7880e58ca2 (diff) | |
| download | catskill-a76fd9b5af153773273121c7aec2a9cbeed1dfb7.tar.zst catskill-a76fd9b5af153773273121c7aec2a9cbeed1dfb7.zip | |
Make diagnostics generic over passes, condensing different error handling
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'boot/parse.c')
| -rw-r--r-- | boot/parse.c | 79 |
1 files changed, 26 insertions, 53 deletions
diff --git a/boot/parse.c b/boot/parse.c index db5e029..2b5d859 100644 --- a/boot/parse.c +++ b/boot/parse.c @@ -103,56 +103,22 @@ parser_error_is_none(const struct Parser_Error* error) return error->kind == PARSER_ERROR_NONE; } -struct Span -token_span_to_line_span(struct Span span, struct String source) -{ - Pos line_start = span.start, line_end = span.start; - - // go backwards from the start of the token's span to find line start. - while (line_start > 0 && string_at(source, line_start - 1) != '\n') line_start--; - // go forwards from the end of the token's span to find line end. - while (line_end < string_length(source) && string_at(source, line_end) != '\n') line_end++; - - return span_new(line_start, line_end); -} - -// print out nice, human-readable error message -// pointing to the location of the error in the source file. -// TODO: bring out the infrastructure for displaying errors in the same format -// outside of the parser, so that it can be used in other places. void parser_error_display(const struct Parser_Error* error, struct Source_File source_file) { if (parser_error_is_none(error)) return; - uint line = error->cause.location.line; - uint column = error->cause.location.column; - - struct Token cause = error->cause; - - STRING_FORMAT_TO(source_file.path, stderr, ANSI_WHITE "%s:%lu:%lu:\n", line, column); - fprintf(stderr, ANSI_BOLD ANSI_RED "error: " ANSI_WHITE); + struct String_View lexeme = token_lexeme(&error->cause, source_file.source); if (error->subkind != PARSER_ERROR_NONE) { - fprintf(stderr, "%s: %s", parser_error_kind_to_string(error->kind), - parser_error_kind_to_string(error->subkind)); + diagnostic_render( + source_file, stderr, DIAGNOSTIC_ERROR, error->cause.span, "%s: %s, got '%S'", + parser_error_kind_to_string(error->kind), parser_error_kind_to_string(error->subkind), + STR(lexeme)); } else { - fprintf(stderr, "%s", parser_error_kind_to_string(error->kind)); + diagnostic_render( + source_file, stderr, DIAGNOSTIC_ERROR, error->cause.span, "%s, got '%S'", + parser_error_kind_to_string(error->kind), STR(lexeme)); } - struct String_View cause_lexeme = token_lexeme(&cause, source_file.source); - STRING_FORMAT_TO(cause_lexeme, stderr, ", got '%S' :(\n"); - - struct Span line_span = token_span_to_line_span(cause.span, source_file.source); - - struct String_View source_line = - string_substring(source_file.source, line_span.start, line_span.end); - - fprintf(stderr, ANSI_WHITE ANSI_NO_BOLD "%lu| ", line); - STRING_FORMAT_TO(source_line, stderr, "%S\n"); - - 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); } // a parser context descibes the current surrounding structure @@ -405,7 +371,8 @@ parser_block_node(struct Parser* p, struct Parser_Error* error) struct Tree_Statement* current = nil; while (!parser_probe(p, TOKEN_CURLY_CLOSE)) { - struct Tree_Statement* statement = CHECK_RETURN(parser_statement(p, error), struct Tree_Block); + struct Tree_Statement* statement = + CHECK_RETURN(parser_statement(p, error), struct Tree_Block); // statement ending token isn't required when the block ends on the same line, // as in e.g.: `if (true) { print("yes") }` @@ -956,7 +923,8 @@ parser_expression_primary_boolean(struct Parser* p, struct Parser_Error* error) "expected boolean literal"); bool literal = token.kind == TOKEN_WORD_TRUE; union Tree_Expression_Value expr_value = { .bool_literal = { literal } }; - return tree_expression_new(TREE_EXPRESSION_BOOLEAN_LITERAL, expr_value, token.span, token.location); + return tree_expression_new( + TREE_EXPRESSION_BOOLEAN_LITERAL, expr_value, token.span, token.location); } struct Tree_Expression* @@ -1008,7 +976,8 @@ parser_expression_type(struct Parser* p, struct Parser_Error* error) struct Span span = span_merge(start_token.span, type->span); return tree_expression_new( - TREE_EXPRESSION_TYPE, (union Tree_Expression_Value){ .type = { type } }, span, start_token.location); + TREE_EXPRESSION_TYPE, (union Tree_Expression_Value){ .type = { type } }, span, + start_token.location); } struct Tree_Expression* @@ -1198,8 +1167,8 @@ parser_expression_postfix(struct Parser* p, struct Parser_Error* error) struct Span span = span_merge(expression->span, token.span); union Tree_Expression_Value value = { .increment_decrement = inc_dec }; - expression = - tree_expression_new(TREE_EXPRESSION_INCREMENT_DECREMENT, value, span, token.location); + expression = tree_expression_new( + TREE_EXPRESSION_INCREMENT_DECREMENT, value, span, token.location); continue; } @@ -1234,7 +1203,8 @@ parser_expression_unary_operation(struct Parser* p, struct Parser_Error* error) struct Span span = span_merge(token.span, inc_dec.subject->span); union Tree_Expression_Value value = { .increment_decrement = inc_dec }; - return tree_expression_new(TREE_EXPRESSION_INCREMENT_DECREMENT, value, span, token.location); + return tree_expression_new( + TREE_EXPRESSION_INCREMENT_DECREMENT, value, span, token.location); } return parser_expression_postfix(p, error); @@ -1357,7 +1327,8 @@ parser_statement_conditional(struct Parser* p, struct Parser_Error* error) CONTEXT_END(in_statement_clause); struct Tree_Block then_block = CHECK(parser_block_node(p, error)); - conditional.conditions[conditional.condition_count++] = (struct Tree_Statement_Conditional_Branch){ + conditional + .conditions[conditional.condition_count++] = (struct Tree_Statement_Conditional_Branch){ .when = if_condition, .then = then_block, }; @@ -1397,8 +1368,8 @@ parser_statement_conditional(struct Parser* p, struct Parser_Error* error) } return tree_statement_new( - TREE_STATEMENT_CONDITIONAL, (union Tree_Statement_Value){ .conditional = conditional }, span, - if_token.location); + TREE_STATEMENT_CONDITIONAL, (union Tree_Statement_Value){ .conditional = conditional }, + span, if_token.location); } struct Tree_Statement* @@ -1475,7 +1446,8 @@ parser_statement_block(struct Parser* p, struct Parser_Error* error) { struct Tree_Block block = CHECK(parser_block_node(p, error)); return tree_statement_new( - TREE_STATEMENT_BLOCK, (union Tree_Statement_Value){ .block = { block } }, block.span, block.location); + TREE_STATEMENT_BLOCK, (union Tree_Statement_Value){ .block = { block } }, block.span, + block.location); } struct Tree_Statement* @@ -1496,7 +1468,8 @@ parser_statement_break(struct Parser* p, struct Parser_Error* error) { struct Token break_token = CHECK(parser_need(p, TOKEN_WORD_BREAK, error)); struct Span span = break_token.span; - return tree_statement_new(TREE_STATEMENT_BREAK, (union Tree_Statement_Value){ 0 }, span, break_token.location); + return tree_statement_new( + TREE_STATEMENT_BREAK, (union Tree_Statement_Value){ 0 }, span, break_token.location); } struct Tree_Statement* |
