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 }