lib/chant/src/lower/statement/dispatch.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const ast = @import("../../ast/root.zig");
2 const lower_mod = @import("../root.zig");
3 const expression = @import("../expression/root.zig");
4 const branch = @import("branch.zig");
5 const loop = @import("loop.zig");
6
7 const FuncDialect = @import("choir").dialects.FuncDialect;
8 const Error = lower_mod.Error;
9 const Lowerer = lower_mod.Lowerer;
10
11 pub fn lowerStatement(lowerer: *Lowerer, stmt: *ast.Stmt) Error!void {
12 switch (stmt.*) {
13 .empty, .break_stmt, .continue_stmt => {
14 if (stmt.* != .empty) return error.UnsupportedConstruct;
15 },
16 .expression => |expr| {
17 _ = try expression.lowerExpression(lowerer, expr);
18 },
19 .declaration => |variables| {
20 for (variables) |variable| {
21 try lower_mod.local.declare(lowerer, variable);
22 }
23 },
24 .compound => |items| {
25 try lower_mod.scope.push(lowerer);
26 defer lower_mod.scope.pop(lowerer);
27 for (items) |item| {
28 try lowerStatement(lowerer, item);
29 }
30 },
31 .label => |label| try lowerStatement(lowerer, label.body),
32 .return_stmt => |value| try lowerReturn(lowerer, value),
33 .if_stmt => |if_stmt| try branch.lower(lowerer, if_stmt, lowerStatement),
34 .for_stmt => |for_stmt| try loop.lower(lowerer, for_stmt, lowerStatement),
35 .while_stmt, .do_stmt => return error.UnsupportedConstruct,
36 }
37 }
38
39 fn lowerReturn(lowerer: *Lowerer, value: ?*ast.Expr) Error!void {
40 if (value != null) return error.UnsupportedConstruct;
41 const ret = FuncDialect.ReturnOp.create(lowerer.ctx, lowerer.loc, &.{}) catch return error.OutOfMemory;
42 try lower_mod.emit.append(lowerer, ret.op);
43 lowerer.terminated = true;
44 }