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 }