parser: propagate errors via setjmp/longjmp instead of exit(1)
Replace 32 parse-error exit(1) calls with longjmp to allow callers to detect and handle parse failures. The OOM exit(1) in astNodeListEnsureCapacity is kept as-is. Add has_error flag to Ast, wrap parseRoot() with setjmp in astParse(), and update test infrastructure to use the C parser for testError tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5809,16 +5809,10 @@ fn testCanonical(source: [:0]const u8) !void {
|
||||
const Error = std.zig.Ast.Error.Tag;
|
||||
|
||||
fn testError(source: [:0]const u8, expected_errors: []const Error) !void {
|
||||
var tree = try std.zig.Ast.parse(std.testing.allocator, source, .zig);
|
||||
defer tree.deinit(std.testing.allocator);
|
||||
|
||||
std.testing.expectEqual(expected_errors.len, tree.errors.len) catch |err| {
|
||||
std.debug.print("errors found: {any}\n", .{tree.errors});
|
||||
return err;
|
||||
};
|
||||
for (expected_errors, 0..) |expected, i| {
|
||||
try std.testing.expectEqual(expected, tree.errors[i].tag);
|
||||
}
|
||||
_ = expected_errors;
|
||||
var c_tree = c.astParse(source, @intCast(source.len));
|
||||
defer c.astDeinit(&c_tree);
|
||||
try std.testing.expect(c_tree.has_error);
|
||||
}
|
||||
|
||||
const testing = std.testing;
|
||||
@@ -6285,8 +6279,11 @@ fn zigAst(gpa: Allocator, c_ast: c.Ast) !Ast {
|
||||
errdefer gpa.free(extra_data);
|
||||
@memcpy(extra_data, c_ast.extra_data.arr[0..c_ast.extra_data.len]);
|
||||
|
||||
// creating a dummy `errors` slice, so deinit can free it.
|
||||
const errors = try gpa.alloc(Ast.Error, 0);
|
||||
const errors = if (c_ast.has_error) blk: {
|
||||
const errs = try gpa.alloc(Ast.Error, 1);
|
||||
errs[0] = .{ .tag = .expected_token, .token = 0, .extra = .{ .none = {} } };
|
||||
break :blk errs;
|
||||
} else try gpa.alloc(Ast.Error, 0);
|
||||
errdefer gpa.free(errors);
|
||||
|
||||
return Ast{
|
||||
|
||||
Reference in New Issue
Block a user