lib/chant/src/lower/expression/atom.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const choir = @import("choir");
 2 const ast = @import("../../ast/root.zig");
 3 const lower_mod = @import("../root.zig");
 4 const types = @import("types.zig");
 5 
 6 const ArithDialect = choir.dialects.ArithDialect;
 7 const Error = lower_mod.Error;
 8 const Lowerer = lower_mod.Lowerer;
 9 const Typed = types.Typed;
10 
11 pub fn lower(lowerer: *Lowerer, expr: *ast.Expr) Error!Typed {
12     switch (expr.*) {
13         .integer_literal => |literal| return lowerIntegerLiteral(lowerer, literal),
14         .float_literal => |literal| return lowerFloatLiteral(lowerer, literal),
15         .string_literal => return error.UnsupportedConstruct,
16         .identifier => |identifier| return lowerIdentifier(lowerer, identifier),
17         .initializer_list => return error.UnsupportedConstruct,
18         else => unreachable,
19     }
20 }
21 
22 fn lowerIntegerLiteral(lowerer: *Lowerer, literal: ast.expr.IntegerLiteral) Error!Typed {
23     const result_type = try lower_mod.convert.scalarType(lowerer, literal.type);
24     const constant = ArithDialect.ConstantOp.createInt(lowerer.ctx, lowerer.loc, result_type, @bitCast(literal.value)) catch return error.OutOfMemory;
25     try lower_mod.emit.append(lowerer, constant.op);
26     var mutable = constant;
27     return .{ .value = mutable.getResult(), .c_type = literal.type };
28 }
29 
30 fn lowerFloatLiteral(lowerer: *Lowerer, literal: ast.expr.FloatLiteral) Error!Typed {
31     const result_type = try lower_mod.convert.scalarType(lowerer, literal.type);
32     const constant = ArithDialect.ConstantOp.createFloat(lowerer.ctx, lowerer.loc, result_type, literal.value) catch return error.OutOfMemory;
33     try lower_mod.emit.append(lowerer, constant.op);
34     var mutable = constant;
35     return .{ .value = mutable.getResult(), .c_type = literal.type };
36 }
37 
38 fn lowerIdentifier(lowerer: *Lowerer, identifier: ast.expr.Identifier) Error!Typed {
39     const local = lower_mod.scope.lookup(lowerer, identifier.name) orelse return error.UndefinedName;
40     switch (local.kind) {
41         .loop_iv => return .{ .value = local.value, .c_type = local.c_type },
42         .pointer_param => return .{ .value = local.value, .c_type = local.c_type },
43         .slot => {
44             if (local.c_type.kind == .array) return .{ .value = local.value, .c_type = local.c_type };
45             const loaded = try lower_mod.memory.loadScalar(lowerer, local.value, local.c_type);
46             return .{ .value = loaded, .c_type = local.c_type };
47         },
48     }
49 }