feat: full path for error reporting in variable parser

This commit is contained in:
Fernando Araoz 2025-01-27 22:04:54 -05:00
parent 7c95e669a4
commit 3a97e59886
3 changed files with 34 additions and 6 deletions

View File

@ -41,9 +41,19 @@ pub const Module = struct {
// parse many statements
while (current_pos < input_len) {
var stmt: statement.Statement = undefined;
var current_error: errors.ErrorData = undefined;
// TODO: handle other errors of vardef parsing
const next_pos = try stmt.init(tokens, current_pos, allocator);
const next_pos = stmt.init(tokens, current_pos, &current_error, allocator) catch |e| switch (e) {
error.Error => {
// add the error to the list of errors,
// and exit for now because i havent implemented
// error recovery yet
try err_arrl.append(current_error);
return error.Error;
},
else => return e,
};
if (next_pos) |next_pos_actual| {
current_pos = next_pos_actual;

View File

@ -20,6 +20,7 @@ pub const Statement = struct {
target: *Statement,
tokens: *const TokenStream,
pos: usize,
err: *errors.ErrorData,
allocator: std.mem.Allocator,
) ParseError!?usize {
// try to parse a variable definition
@ -27,8 +28,8 @@ pub const Statement = struct {
var vardef = try allocator.create(variable.VariableBinding);
errdefer allocator.destroy(vardef);
// TODO: handle other errors of vardef parsing
if (try vardef.init(tokens, pos, undefined, allocator)) |vardef_end| {
const vardef_result = try vardef.init(tokens, pos, err, allocator);
if (vardef_result) |vardef_end| {
// variable definition parsed
// return the parsed variable definition
target.* = .{
@ -61,7 +62,7 @@ test "should parse a variable declaration statement" {
defer tokens.deinit();
var statement: Statement = undefined;
_ = try statement.init(&tokens, 0, std.testing.allocator);
_ = try statement.init(&tokens, 0, undefined, std.testing.allocator);
defer statement.deinit();
switch (statement.value) {
@ -80,7 +81,7 @@ test "should fail on other constructs" {
defer tokens.deinit();
var statement: Statement = undefined;
const result = try statement.init(&tokens, 0, std.testing.allocator);
const result = try statement.init(&tokens, 0, undefined, std.testing.allocator);
if (result == null) {
// good path
return;

View File

@ -74,6 +74,10 @@ fn repl() !void {
//
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, alloc, &error_array) catch |e| switch (e) {
error.OutOfMemory => {
@ -114,7 +118,20 @@ fn repl() !void {
// Syntax analysis
//
var ast: syntax.Module = undefined;
try ast.init(&tokens, 0, alloc, &error_array);
ast.init(&tokens, 0, alloc, &error_array) catch |e| switch (e) {
error.Error => {
// Print all the errors
for (error_array.items) |ee| {
var err_item = ee;
const err_str = try err_item.get_error_str(line, "repl", alloc);
try stdout.print("\n{s}\n", .{err_str});
try bw.flush();
alloc.free(err_str);
}
continue;
},
else => return e,
};
// next repl line
}