feat: improved parsing and regression test suite

This commit is contained in:
Brett Broadhurst 2026-02-27 18:07:02 -07:00
parent 4ebdd3c66e
commit 619eb3b338
Failed to generate hash of commit
39 changed files with 1116 additions and 339 deletions

View file

@ -12,10 +12,14 @@ errors: []Error,
pub const Node = struct {
tag: Tag,
source_start: usize,
source_end: usize,
loc: Span,
data: Data,
pub const Span = struct {
start: usize,
end: usize,
};
pub const Tag = enum {
file,
false_literal,
@ -107,6 +111,98 @@ pub const Node = struct {
children: ?[]*Node,
},
};
fn create(gpa: std.mem.Allocator, tag: Tag, loc: Span) !*Node {
const node = try gpa.create(Node);
node.* = .{ .tag = tag, .loc = loc, .data = undefined };
return node;
}
pub fn createLeaf(gpa: std.mem.Allocator, tag: Tag, loc: Span) !*Node {
const node = try Node.create(gpa, tag, loc);
node.data = .{ .leaf = undefined };
return node;
}
pub fn createBinary(
gpa: std.mem.Allocator,
tag: Tag,
span: Span,
lhs: ?*Node,
rhs: ?*Node,
) !*Node {
const node = try Node.create(gpa, tag, span);
node.data = .{
.bin = .{ .lhs = lhs, .rhs = rhs },
};
return node;
}
pub fn createList(
gpa: std.mem.Allocator,
tag: Tag,
span: Span,
items: ?[]*Node,
) !*Node {
const node = try Node.create(gpa, tag, span);
node.data = .{
.list = .{ .items = items },
};
return node;
}
pub fn createChoice(
gpa: std.mem.Allocator,
tag: Tag,
span: Span,
start_expr: ?*Node,
option_expr: ?*Node,
inner_expr: ?*Node,
) !*Node {
const node = try Node.create(gpa, tag, span);
node.data = .{
.choice_expr = .{
.start_expr = start_expr,
.option_expr = option_expr,
.inner_expr = inner_expr,
},
};
return node;
}
pub fn createSwitch(
gpa: std.mem.Allocator,
tag: Tag,
loc: Span,
condition_expr: ?*Node,
cases_list: ?[]*Node,
) !*Node {
const node = try Node.create(gpa, tag, loc);
node.data = .{
.switch_stmt = .{
.condition_expr = condition_expr,
.cases = cases_list,
},
};
return node;
}
pub fn createKnot(
gpa: std.mem.Allocator,
tag: Tag,
loc: Span,
prototype: *Node,
children: ?[]*Node,
) !*Node {
const node = try Node.create(gpa, tag, loc);
node.data = .{
.knot_decl = .{
.prototype = prototype,
.children = children,
},
};
return node;
}
};
pub const Error = struct {
@ -134,121 +230,6 @@ pub const Error = struct {
};
};
fn create(
gpa: std.mem.Allocator,
tag: Node.Tag,
source_start: usize,
source_end: usize,
) !*Node {
const node = try gpa.create(Node);
node.* = .{
.tag = tag,
.source_start = source_start,
.source_end = source_end,
.data = undefined,
};
return node;
}
pub fn createLeafNode(
gpa: std.mem.Allocator,
tag: Node.Tag,
source_start: usize,
source_end: usize,
) !*Node {
const node = try Ast.create(gpa, tag, source_start, source_end);
node.*.data = .{ .leaf = undefined };
return node;
}
pub fn createBinaryNode(
gpa: std.mem.Allocator,
tag: Node.Tag,
source_start: usize,
source_end: usize,
lhs: ?*Node,
rhs: ?*Node,
) !*Node {
const node = try Ast.create(gpa, tag, source_start, source_end);
node.*.data = .{
.bin = .{
.lhs = lhs,
.rhs = rhs,
},
};
return node;
}
pub fn createListNode(
gpa: std.mem.Allocator,
tag: Node.Tag,
source_start: usize,
source_end: usize,
items: ?[]*Node,
) !*Node {
const node = try Ast.create(gpa, tag, source_start, source_end);
node.*.data = .{
.list = .{ .items = items },
};
return node;
}
pub fn createChoiceExprNode(
gpa: std.mem.Allocator,
tag: Node.Tag,
source_start: usize,
source_end: usize,
start_expr: ?*Node,
option_expr: ?*Node,
inner_expr: ?*Node,
) !*Node {
const node = try Ast.create(gpa, tag, source_start, source_end);
node.*.data = .{
.choice_expr = .{
.start_expr = start_expr,
.option_expr = option_expr,
.inner_expr = inner_expr,
},
};
return node;
}
pub fn createSwitchNode(
gpa: std.mem.Allocator,
tag: Node.Tag,
source_start: usize,
source_end: usize,
condition_expr: ?*Node,
cases_list: ?[]*Node,
) !*Node {
const node = try Ast.create(gpa, tag, source_start, source_end);
node.*.data = .{
.switch_stmt = .{
.condition_expr = condition_expr,
.cases = cases_list,
},
};
return node;
}
pub fn createKnotDeclNode(
gpa: std.mem.Allocator,
tag: Node.Tag,
source_start: usize,
source_end: usize,
prototype: *Node,
children: ?[]*Node,
) !*Node {
const node = try Ast.create(gpa, tag, source_start, source_end);
node.*.data = .{
.knot_decl = .{
.prototype = prototype,
.children = children,
},
};
return node;
}
pub fn parse(
gpa: std.mem.Allocator,
arena: std.mem.Allocator,