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

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 const choir = @import("choir");
 3 const ast = @import("../../ast/root.zig");
 4 const lower_mod = @import("../root.zig");
 5 const builtin = @import("builtin.zig");
 6 const types = @import("types.zig");
 7 
 8 const FuncDialect = choir.dialects.FuncDialect;
 9 const Error = lower_mod.Error;
10 const Lowerer = lower_mod.Lowerer;
11 const Typed = types.Typed;
12 
13 pub fn lower(lowerer: *Lowerer, call: ast.expr.Call, comptime recurse: types.LowerExpression) Error!Typed {
14     if (try builtin.lower(lowerer, call, recurse)) |result| return result;
15 
16     const signature = lowerer.functions.get(call.callee) orelse return error.UndefinedName;
17     if (signature.params.len != call.arguments.len) return error.UnsupportedConstruct;
18 
19     var arguments = std.ArrayListUnmanaged(*choir.Value).empty;
20     defer arguments.deinit(lowerer.gpa);
21     for (call.arguments, 0..) |argument, i| {
22         const lowered = try recurse(lowerer, argument);
23         const converted = try lower_mod.convert.convert(lowerer, lowered.value, lowered.c_type, signature.params[i].type);
24         try arguments.append(lowerer.gpa, converted);
25     }
26 
27     const return_c_type = signature.child orelse return error.UnsupportedType;
28     var result_types = std.ArrayListUnmanaged(choir.Type).empty;
29     defer result_types.deinit(lowerer.gpa);
30     if (return_c_type.kind != .void_type) {
31         try result_types.append(lowerer.gpa, try lower_mod.convert.scalarType(lowerer, return_c_type));
32     }
33 
34     const call_op = FuncDialect.CallOp.create(lowerer.ctx, lowerer.loc, call.callee, arguments.items, result_types.items) catch return error.OutOfMemory;
35     try lower_mod.emit.append(lowerer, call_op.op);
36     if (return_c_type.kind == .void_type) {
37         return .{ .value = undefined, .c_type = &ast.types.void_type };
38     }
39     const result = call_op.getResult(0) orelse return error.UnsupportedConstruct;
40     return .{ .value = result, .c_type = return_c_type };
41 }