fix: parsing diverts within content

This commit is contained in:
Brett Broadhurst 2026-03-30 17:19:12 -06:00
parent 2ee43514b4
commit 066369cc13
Failed to generate hash of commit
4 changed files with 45 additions and 6 deletions

View file

@ -1077,6 +1077,7 @@ fn content(block: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!Ir.In
.multi_if_stmt => _ = try multiIfStmt(block, scope, child_node),
.switch_stmt => _ = try switchStmt(block, scope, child_node),
.inline_if_stmt => _ = try inlineIfStmt(block, scope, child_node),
.divert_expr => _ = try divertExpr(block, scope, child_node),
else => unreachable,
}
}

View file

@ -785,6 +785,9 @@ fn parseIdentifierExpr(p: *Parse) Error!*Ast.Node {
}
fn parseDivertExpr(p: *Parse) Error!*Ast.Node {
try p.pushGrammar(.expression);
defer p.popGrammar();
const main_token = p.nextToken();
const node = try parseIdentifierExpr(p);
return .createBinary(p.arena, .divert_expr, .{
@ -794,9 +797,6 @@ fn parseDivertExpr(p: *Parse) Error!*Ast.Node {
}
fn parseDivertStmt(p: *Parse) Error!*Ast.Node {
try p.pushGrammar(.expression);
defer p.popGrammar();
const main_token = p.token;
const node = try parseDivertExpr(p);
_ = try p.expectNewline();
@ -980,7 +980,7 @@ fn parseContent(p: *Parse, options: ContentOptions) Error!?*Ast.Node {
const node: ?*Ast.Node = switch (p.token.tag) {
.eof, .newline, .left_arrow, .right_brace => break,
.left_brace => try parseLbraceExpr(p),
.right_arrow => try parseDivertStmt(p),
.right_arrow => try parseDivertExpr(p),
.glue => blk: {
while (true) {
_ = p.nextToken();

View file

@ -119,10 +119,26 @@ test "fixture - I042 (Weave options)" {
try testRuntimeFixture("I042");
}
test "fixture - I046 (Left right glue matching)" {
try testRuntimeFixture("I046");
}
test "fixture - I048 (Simple glue)" {
try testRuntimeFixture("I048");
}
test "fixture - I051 (String constants)" {
try testRuntimeFixture("I051");
}
test "fixture - I055 (Same line divert is inline)" {
try testRuntimeFixture("I055");
}
test "fixture - I061 (Divert in conditional)" {
try testRuntimeFixture("I061");
}
test "fixture - I064 (Done stops thread)" {
try testRuntimeFixture("I064");
}
@ -132,10 +148,34 @@ test "fixture - I075 (Clean callstack reset on path choice)" {
try testRuntimeFixture("I075");
}
test "fixture - I076 (Call stack evaluation)" {
try testRuntimeFixture("I076");
}
test "fixture - I078 (Choice with brackets only)" {
try testRuntimeFixture("I078");
}
test "fixture - I082 (Choice diverts to done)" {
try testRuntimeFixture("I082");
}
test "fixture - I085 (Logic in choices)" {
try testRuntimeFixture("I085");
}
test "fixture - I087 (Non text in choice inner content)" {
try testRuntimeFixture("I087");
}
test "fixture - I095 (Multiline logic with glue)" {
try testRuntimeFixture("I095");
}
test "fixture - I097 (Logic lines with newlines)" {
try testRuntimeFixture("I097");
}
test "fixture - I117 (Factorial recursive)" {
try testRuntimeFixture("I117");
}

View file

@ -295,8 +295,6 @@ pub const Module = struct {
};
defer builder.deinit(gpa);
const debug_name_str = mod.intern_pool.getStrBytes(mod.ir, work_unit.decl_name);
std.debug.print("Analyzing {s}\n", .{debug_name_str});
switch (work_unit.tag) {
.knot => {
try sema.analyzeKnot(&builder, work_unit.inst_index);