about summary refs log tree commit diff
path: root/boot/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'boot/parse.c')
-rw-r--r--boot/parse.c79
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*