refactor: remove error module

This commit is contained in:
Fernando Araoz 2025-01-31 06:26:15 -05:00
parent 2aa81dd39f
commit d0feb04b55
4 changed files with 0 additions and 253 deletions

View File

@ -26,17 +26,6 @@ pub fn build(b: *std.Build) void {
// Add options to executable // Add options to executable
exe.root_module.addImport("config", options_module); exe.root_module.addImport("config", options_module);
//
// Error handling module
//
const error_module = b.addModule("errors", .{
.root_source_file = b.path("src/errors/root.zig"),
.target = target,
.optimize = optimize,
});
error_module.addImport("config", options_module);
exe.root_module.addImport("errors", error_module);
// //
// Context module // Context module
// //
@ -57,7 +46,6 @@ pub fn build(b: *std.Build) void {
.optimize = optimize, .optimize = optimize,
}); });
lexic_module.addImport("config", options_module); lexic_module.addImport("config", options_module);
lexic_module.addImport("errors", error_module);
lexic_module.addImport("context", context_module); lexic_module.addImport("context", context_module);
exe.root_module.addImport("lexic", lexic_module); exe.root_module.addImport("lexic", lexic_module);
@ -71,7 +59,6 @@ pub fn build(b: *std.Build) void {
}); });
syntax_module.addImport("config", options_module); syntax_module.addImport("config", options_module);
syntax_module.addImport("lexic", lexic_module); syntax_module.addImport("lexic", lexic_module);
syntax_module.addImport("errors", error_module);
syntax_module.addImport("context", context_module); syntax_module.addImport("context", context_module);
exe.root_module.addImport("syntax", syntax_module); exe.root_module.addImport("syntax", syntax_module);
@ -100,7 +87,6 @@ pub fn build(b: *std.Build) void {
exe_unit_tests.root_module.addImport("config", options_module); exe_unit_tests.root_module.addImport("config", options_module);
exe_unit_tests.root_module.addImport("lexic", lexic_module); exe_unit_tests.root_module.addImport("lexic", lexic_module);
exe_unit_tests.root_module.addImport("syntax", syntax_module); exe_unit_tests.root_module.addImport("syntax", syntax_module);
exe_unit_tests.root_module.addImport("errors", error_module);
exe_unit_tests.root_module.addImport("context", context_module); exe_unit_tests.root_module.addImport("context", context_module);
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
@ -112,7 +98,6 @@ pub fn build(b: *std.Build) void {
const files = [_][]const u8{ const files = [_][]const u8{
"src/01_lexic/root.zig", "src/01_lexic/root.zig",
"src/02_syntax/root.zig", "src/02_syntax/root.zig",
"src/errors/root.zig",
"src/context/root.zig", "src/context/root.zig",
}; };
for (files) |file| { for (files) |file| {
@ -124,7 +109,6 @@ pub fn build(b: *std.Build) void {
file_unit_test.root_module.addImport("config", options_module); file_unit_test.root_module.addImport("config", options_module);
file_unit_test.root_module.addImport("lexic", lexic_module); file_unit_test.root_module.addImport("lexic", lexic_module);
file_unit_test.root_module.addImport("syntax", syntax_module); file_unit_test.root_module.addImport("syntax", syntax_module);
file_unit_test.root_module.addImport("errors", error_module);
file_unit_test.root_module.addImport("context", context_module); file_unit_test.root_module.addImport("context", context_module);
var test_artifact = b.addRunArtifact(file_unit_test); var test_artifact = b.addRunArtifact(file_unit_test);

View File

@ -1,7 +0,0 @@
const std = @import("std");
pub const ErrorLabel = struct {
message: []const u8,
start: usize,
end: usize,
};

View File

@ -1,222 +0,0 @@
const std = @import("std");
pub const ErrorLabel = @import("./error_label.zig").ErrorLabel;
/// Holds information about errors generated during the compilation,
/// and pretty prints them.
pub const ErrorData = struct {
reason: []const u8,
help: ?[]const u8,
start_position: usize,
end_position: usize,
labels: std.ArrayList(ErrorLabel),
alloc: std.mem.Allocator,
pub fn init(
target: *@This(),
reason: []const u8,
start_position: usize,
end_position: usize,
alloc: std.mem.Allocator,
) !void {
target.* = .{
.reason = reason,
.start_position = start_position,
.end_position = end_position,
.labels = std.ArrayList(ErrorLabel).init(alloc),
.help = null,
.alloc = alloc,
};
}
pub fn add_label(self: *@This(), message: []const u8, start: usize, end: usize) !void {
try self.labels.append(.{
.message = message,
.start = start,
.end = end,
});
}
/// Sets the help message of this error.
pub fn set_help(self: *@This(), help: []const u8) void {
self.help = help;
}
/// Generates an error string. `alloc` is used to create the string,
/// the caller should call `free` on the returning slice.
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);
var error_message = try std.fmt.allocPrint(alloc,
\\Error: {s}
\\[{s}:{d}:{d}]
, .{
self.reason,
filename,
faulty_line.line_number,
faulty_line.column_number,
});
errdefer alloc.free(error_message);
// generate errors for each label, and concat
for (self.labels.items) |label| {
const label_line = get_line(source_code, label.start);
// Build the error position indicator
const column_number_len_str = try std.fmt.allocPrint(
alloc,
"{d}",
.{label_line.line_number},
);
const column_number_len = column_number_len_str.len;
alloc.free(column_number_len_str);
// position up to where the error starts
const error_start_len = column_number_len + 4 + label_line.column_number - 1;
const error_len = label.end - label.start;
// chars for the error
const empty_space_before_indicator = try alloc.alloc(u8, error_start_len);
defer alloc.free(empty_space_before_indicator);
@memset(empty_space_before_indicator, ' ');
// top error indicator: unicode box drawing characters in the range U+250x-U+257x (3 bytes)
const error_indicator = try alloc.alloc(u8, error_len * 3);
defer alloc.free(error_indicator);
// the first char is always '╭', the rest are lines
error_indicator[0] = '\xe2';
error_indicator[1] = '\x95';
error_indicator[2] = '\xad';
// set bytes of the rest
var i: usize = 1;
while (i < error_len) : (i += 1) {
// set bytes
error_indicator[i * 3 + 0] = '\xe2';
error_indicator[i * 3 + 1] = '\x94';
error_indicator[i * 3 + 2] = '\x80';
}
// bottom error indicator: always
const bottom_error_indicator = "╰─";
const help_message: []u8 = msg: {
if (self.help) |help_text| {
// this will be manually freed later
break :msg try std.fmt.allocPrint(alloc, "\n Help: {s}", .{help_text});
} else {
break :msg "";
}
};
defer if (help_message.len > 0) {
alloc.free(help_message);
};
const label_error = try std.fmt.allocPrint(alloc,
\\
\\
\\ {d} | {s}
\\{s}{s}
\\{s}{s} {s}
\\{s}
, .{
label_line.line_number,
label_line.line,
empty_space_before_indicator,
error_indicator,
empty_space_before_indicator,
bottom_error_indicator,
label.message,
help_message,
});
errdefer alloc.free(label_error);
// append the previous bytes to the current ones,
// in a temp variable
const new_bytes = try std.mem.concat(alloc, u8, &[_][]const u8{ error_message, label_error });
// free the previous bytes
alloc.free(label_error);
alloc.free(error_message);
// reference the new bytes
error_message = new_bytes;
// continue
}
return error_message;
}
// TODO:
// - transform absolute position into line:column
// - Get previous, current and next line
// - Display message
/// Writes this error as a JSON to the writer
pub fn write_json(self: ErrorData, alloc: std.mem.Allocator, writer: anytype) !void {
// get this as JSON
const json_str = try std.json.stringifyAlloc(alloc, .{
.reason = self.reason,
.help = self.help,
.start_position = self.start_position,
.end_position = self.end_position,
.labels = self.labels.items,
}, .{});
defer alloc.free(json_str);
// write the JSON to the writer
try writer.writeAll(json_str);
}
pub fn deinit(self: *@This()) void {
self.labels.deinit();
}
};
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_end: usize = 0;
var current_pos: usize = 0;
const cap = input.len;
// search the start pos of the line
while (current_pos < cap and current_pos < at) : (current_pos += 1) {
if (input[current_pos] == '\n' and current_pos + 1 < cap) {
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
while (current_pos < cap) : (current_pos += 1) {
// EOF is EOL
if (current_pos + 1 == cap) {
line_end = current_pos + 1;
break;
}
if (input[current_pos] == '\n') {
// dont count the newline as part of the... line
line_end = current_pos;
break;
}
}
return .{
.line = input[line_start..line_end],
.line_number = line_number,
.column_number = column_number,
};
}

View File

@ -1,7 +1,6 @@
const std = @import("std"); const std = @import("std");
const lexic = @import("lexic"); const lexic = @import("lexic");
const syntax = @import("syntax"); const syntax = @import("syntax");
const errors = @import("errors");
const context = @import("context"); const context = @import("context");
const cli = @import("cli.zig"); const cli = @import("cli.zig");
@ -77,13 +76,6 @@ fn repl() !void {
// //
// Tokenize // Tokenize
// //
var error_array = std.ArrayList(errors.ErrorData).init(alloc);
defer error_array.deinit();
defer for (error_array.items) |item| {
var i = item;
i.deinit();
};
const tokens = lexic.tokenize(line, &ctx) catch |e| switch (e) { const tokens = lexic.tokenize(line, &ctx) catch |e| switch (e) {
error.OutOfMemory => { error.OutOfMemory => {
try stdout.print("FATAL ERROR: System Out of Memory!", .{}); try stdout.print("FATAL ERROR: System Out of Memory!", .{});