feat: add filename, line and column number to error reporting
This commit is contained in:
parent
996bb6460f
commit
4e13453930
@ -22,13 +22,22 @@ pub const ErrorData = struct {
|
|||||||
|
|
||||||
/// Generates an error string. `alloc` is used to create the string,
|
/// Generates an error string. `alloc` is used to create the string,
|
||||||
/// the caller should call `free` on the returning slice.
|
/// the caller should call `free` on the returning slice.
|
||||||
pub fn get_error_str(self: *@This(), source_code: []const u8, alloc: std.mem.Allocator) ![]u8 {
|
pub fn get_error_str(self: *@This(), source_code: []const u8, filename: []const u8, alloc: std.mem.Allocator) ![]u8 {
|
||||||
const faulty_line = get_line(source_code, self.start_position);
|
const faulty_line = get_line(source_code, self.start_position);
|
||||||
|
|
||||||
const error_message = try std.fmt.allocPrint(alloc,
|
const error_message = try std.fmt.allocPrint(alloc,
|
||||||
\\Error: {s}
|
\\Error: {s}
|
||||||
\\{s}
|
\\[{s}:{d}:{d}]
|
||||||
, .{ self.reason, faulty_line });
|
\\
|
||||||
|
\\ {d} | {s}
|
||||||
|
, .{
|
||||||
|
self.reason,
|
||||||
|
filename,
|
||||||
|
faulty_line.line_number,
|
||||||
|
faulty_line.column_number,
|
||||||
|
faulty_line.line_number,
|
||||||
|
faulty_line.line,
|
||||||
|
});
|
||||||
|
|
||||||
return error_message;
|
return error_message;
|
||||||
}
|
}
|
||||||
@ -44,7 +53,16 @@ pub const ErrorData = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn get_line(input: []const u8, at: usize) []const u8 {
|
const LineInfo = struct {
|
||||||
|
line: []const u8,
|
||||||
|
/// 1 based
|
||||||
|
line_number: usize,
|
||||||
|
/// 1 based
|
||||||
|
column_number: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn get_line(input: []const u8, at: usize) LineInfo {
|
||||||
|
var line_number: usize = 1;
|
||||||
var line_start: usize = 0;
|
var line_start: usize = 0;
|
||||||
var line_end: usize = 0;
|
var line_end: usize = 0;
|
||||||
var current_pos: usize = 0;
|
var current_pos: usize = 0;
|
||||||
@ -54,9 +72,13 @@ fn get_line(input: []const u8, at: usize) []const u8 {
|
|||||||
while (current_pos < cap and current_pos < at) : (current_pos += 1) {
|
while (current_pos < cap and current_pos < at) : (current_pos += 1) {
|
||||||
if (input[current_pos] == '\n' and current_pos + 1 < cap) {
|
if (input[current_pos] == '\n' and current_pos + 1 < cap) {
|
||||||
line_start = current_pos + 1;
|
line_start = current_pos + 1;
|
||||||
|
line_number += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute the column number
|
||||||
|
const column_number: usize = current_pos - line_start + 1;
|
||||||
|
|
||||||
// search the end pos of the line
|
// search the end pos of the line
|
||||||
while (current_pos < cap) : (current_pos += 1) {
|
while (current_pos < cap) : (current_pos += 1) {
|
||||||
// EOF is EOL
|
// EOF is EOL
|
||||||
@ -71,7 +93,11 @@ fn get_line(input: []const u8, at: usize) []const u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return input[line_start..line_end];
|
return .{
|
||||||
|
.line = input[line_start..line_end],
|
||||||
|
.line_number = line_number,
|
||||||
|
.column_number = column_number,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
@ -83,7 +109,9 @@ test "should get a single line" {
|
|||||||
const at = 4;
|
const at = 4;
|
||||||
const output = get_line(input, at);
|
const output = get_line(input, at);
|
||||||
|
|
||||||
try std.testing.expectEqualStrings("print(hello)", output);
|
try std.testing.expectEqualStrings("print(hello)", output.line);
|
||||||
|
try std.testing.expectEqual(1, output.line_number);
|
||||||
|
try std.testing.expectEqual(5, output.column_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "should get line from 2 lines (1)" {
|
test "should get line from 2 lines (1)" {
|
||||||
@ -91,7 +119,9 @@ test "should get line from 2 lines (1)" {
|
|||||||
const at = 4;
|
const at = 4;
|
||||||
const output = get_line(input, at);
|
const output = get_line(input, at);
|
||||||
|
|
||||||
try std.testing.expectEqualStrings("print(hello)", output);
|
try std.testing.expectEqualStrings("print(hello)", output.line);
|
||||||
|
try std.testing.expectEqual(1, output.line_number);
|
||||||
|
try std.testing.expectEqual(5, output.column_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "should get line from 2 lines (2)" {
|
test "should get line from 2 lines (2)" {
|
||||||
@ -99,7 +129,9 @@ test "should get line from 2 lines (2)" {
|
|||||||
const at = 15;
|
const at = 15;
|
||||||
const output = get_line(input, at);
|
const output = get_line(input, at);
|
||||||
|
|
||||||
try std.testing.expectEqualStrings("print(bye)", output);
|
try std.testing.expectEqualStrings("print(bye)", output.line);
|
||||||
|
try std.testing.expectEqual(2, output.line_number);
|
||||||
|
try std.testing.expectEqual(3, output.column_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "should get line from 2 lines (3)" {
|
test "should get line from 2 lines (3)" {
|
||||||
@ -107,7 +139,9 @@ test "should get line from 2 lines (3)" {
|
|||||||
const at = 15;
|
const at = 15;
|
||||||
const output = get_line(input, at);
|
const output = get_line(input, at);
|
||||||
|
|
||||||
try std.testing.expectEqualStrings("print(sure?)", output);
|
try std.testing.expectEqualStrings("print(sure?)", output.line);
|
||||||
|
try std.testing.expectEqual(2, output.line_number);
|
||||||
|
try std.testing.expectEqual(3, output.column_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "should gen error message" {
|
test "should gen error message" {
|
||||||
@ -118,11 +152,13 @@ test "should gen error message" {
|
|||||||
.start_position = 6,
|
.start_position = 6,
|
||||||
.end_position = 9,
|
.end_position = 9,
|
||||||
};
|
};
|
||||||
const out = try err.get_error_str(source, std.testing.allocator);
|
const out = try err.get_error_str(source, "repl", std.testing.allocator);
|
||||||
defer std.testing.allocator.free(out);
|
defer std.testing.allocator.free(out);
|
||||||
|
|
||||||
try std.testing.expectEqualStrings(
|
try std.testing.expectEqualStrings(
|
||||||
\\Error: Invalid identifier
|
\\Error: Invalid identifier
|
||||||
\\print(ehh)
|
\\[repl:1:7]
|
||||||
|
\\
|
||||||
|
\\ 1 | print(ehh)
|
||||||
, out);
|
, out);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user