lib/chant/src/lower/statement/branch.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const ast = @import("../../ast/root.zig");
 2 const lower_mod = @import("../root.zig");
 3 const condition_mod = @import("condition.zig");
 4 const types = @import("types.zig");
 5 
 6 const ScfDialect = @import("choir").dialects.ScfDialect;
 7 const Error = lower_mod.Error;
 8 const Lowerer = lower_mod.Lowerer;
 9 
10 pub fn lower(lowerer: *Lowerer, if_stmt: ast.Stmt.If, comptime recurse: types.LowerStatement) Error!void {
11     const condition = try condition_mod.lower(lowerer, if_stmt.condition);
12 
13     const if_op = if (if_stmt.else_body != null)
14         ScfDialect.IfOp.create(lowerer.ctx, lowerer.loc, condition, &.{}) catch return error.OutOfMemory
15     else
16         ScfDialect.IfOp.createWithoutElse(lowerer.ctx, lowerer.loc, condition) catch return error.OutOfMemory;
17     try lower_mod.emit.append(lowerer, if_op.op);
18 
19     {
20         const saved = lowerer.block;
21         lowerer.block = if_op.getThenBlock();
22         defer lowerer.block = saved;
23         try lower_mod.scope.push(lowerer);
24         defer lower_mod.scope.pop(lowerer);
25         try recurse(lowerer, if_stmt.then_body);
26         try lower_mod.emit.emitYield(lowerer, &.{});
27     }
28     if (if_stmt.else_body) |else_body| {
29         const saved = lowerer.block;
30         lowerer.block = if_op.getElseBlock() orelse return error.UnsupportedConstruct;
31         defer lowerer.block = saved;
32         try lower_mod.scope.push(lowerer);
33         defer lower_mod.scope.pop(lowerer);
34         try recurse(lowerer, else_body);
35         try lower_mod.emit.emitYield(lowerer, &.{});
36     }
37 }