refactor: new direction for error reporting
This commit is contained in:
parent
72b686d750
commit
c940374f27
11 changed files with 758 additions and 582 deletions
|
|
@ -123,62 +123,6 @@ fn nodeTagToString(tag: Ast.Node.Tag) []const u8 {
|
|||
};
|
||||
}
|
||||
|
||||
fn makeErrorInfo(r: *Render, err: Ast.Error, message: []const u8) ErrorInfo {
|
||||
const line_index = r.lines.calculateLine(err.loc.start);
|
||||
const snippet_range = r.lines.ranges.items[line_index];
|
||||
const column = err.loc.start - snippet_range.start;
|
||||
const snippet = r.tree.source[snippet_range.start..snippet_range.end];
|
||||
|
||||
return ErrorInfo{
|
||||
.filename = r.tree.filename,
|
||||
.message = message,
|
||||
.line = line_index,
|
||||
.column = column,
|
||||
.snippet = snippet,
|
||||
};
|
||||
}
|
||||
|
||||
fn renderErrorf(r: *Render, writer: *std.Io.Writer, err: Ast.Error, message: []const u8) !void {
|
||||
const error_info = makeErrorInfo(r, err, message);
|
||||
const filename = error_info.filename;
|
||||
const line = error_info.line + 1;
|
||||
const col = error_info.column + 1;
|
||||
const snippet = error_info.message;
|
||||
|
||||
try writer.print("{s}:{d}:{d}: error: {s}\n", .{ filename, line, col, snippet });
|
||||
try writer.print("{d:<4} | {s}\n", .{ line, error_info.snippet });
|
||||
try writer.writeAll(" | ");
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < col) : (i += 1) {
|
||||
try writer.writeByte(' ');
|
||||
}
|
||||
|
||||
try writer.writeByte('^');
|
||||
try writer.writeAll("\n\n");
|
||||
}
|
||||
|
||||
fn renderError(r: *Render, writer: *std.Io.Writer, err: Ast.Error) !void {
|
||||
switch (err.tag) {
|
||||
.panic => try renderErrorf(r, writer, err, "parser panicked"),
|
||||
.unknown_identifier => try renderErrorf(r, writer, err, "unknown identifier"),
|
||||
.redefined_identifier => try renderErrorf(r, writer, err, "redefined identifier"),
|
||||
.assignment_to_const => try renderErrorf(r, writer, err, "assignment to constant value"),
|
||||
.unexpected_token => try renderErrorf(r, writer, err, "unexpected token"),
|
||||
.expected_newline => try renderErrorf(r, writer, err, "expected newline"),
|
||||
.expected_double_quote => try renderErrorf(r, writer, err, "unterminated string, expected closing quote"),
|
||||
.expected_identifier => try renderErrorf(r, writer, err, "expected identifier"),
|
||||
.expected_expression => try renderErrorf(r, writer, err, "expected expression"),
|
||||
.invalid_expression => try renderErrorf(r, writer, err, "invalid expression"),
|
||||
.invalid_lvalue => try renderErrorf(r, writer, err, "invalid lvalue for assignment"),
|
||||
.too_many_arguments => try renderErrorf(r, writer, err, "too many arguments to '{s}'"),
|
||||
.too_many_parameters => try renderErrorf(r, writer, err, "too many parameters defined for '{s}'"),
|
||||
.unexpected_else_stmt => try renderErrorf(r, writer, err, "unexpected else stmt"),
|
||||
.invalid_else_stmt => try renderErrorf(r, writer, err, "invalid else stmt"),
|
||||
.invalid_switch_case => try renderErrorf(r, writer, err, "invalid switch case expression"),
|
||||
}
|
||||
}
|
||||
|
||||
const Prefix = struct {
|
||||
buf: std.ArrayListUnmanaged(u8) = .empty,
|
||||
|
||||
|
|
@ -211,10 +155,8 @@ fn writeType(r: *Render, writer: *std.Io.Writer, node: *const Ast.Node) !void {
|
|||
}
|
||||
|
||||
fn writeLexeme(r: *Render, writer: *std.Io.Writer, node: *const Ast.Node) !void {
|
||||
const bytes = r.tree.source;
|
||||
const lexeme = bytes[node.loc.start..node.loc.end];
|
||||
try r.tty_config.setColor(writer, .yellow);
|
||||
try writer.print("`{s}`", .{lexeme});
|
||||
try writer.print("`{s}`", .{r.tree.nodeSlice(node)});
|
||||
try r.tty_config.setColor(writer, .reset);
|
||||
}
|
||||
|
||||
|
|
@ -549,23 +491,3 @@ pub fn renderTree(
|
|||
}
|
||||
try writer.flush();
|
||||
}
|
||||
|
||||
pub fn renderErrors(
|
||||
gpa: std.mem.Allocator,
|
||||
writer: *std.Io.Writer,
|
||||
ast: *const Ast,
|
||||
options: Options,
|
||||
) !void {
|
||||
var r: Render = .{
|
||||
.gpa = gpa,
|
||||
.tree = ast,
|
||||
.tty_config = if (options.use_color) .escape_codes else .no_color,
|
||||
.prefix = .{},
|
||||
.lines = try LineCache.build(gpa, ast.source),
|
||||
};
|
||||
defer r.prefix.deinit(gpa);
|
||||
defer r.lines.deinit(gpa);
|
||||
|
||||
for (ast.errors) |err| try r.renderError(writer, err);
|
||||
try writer.flush();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue