Local type inference

This commit is contained in:
David Gonzalez Martin 2025-02-28 14:37:55 -06:00
parent 629a9bea96
commit 8ab11bcf5b
3 changed files with 56 additions and 44 deletions

View File

@ -420,7 +420,7 @@ pub const Value = struct {
llvm: *llvm.Value, llvm: *llvm.Value,
const Array = struct { const Array = struct {
buffer: [64]Value = undefined, buffer: [1024]Value = undefined,
count: usize = 0, count: usize = 0,
pub fn add(values: *Array) *Value { pub fn add(values: *Array) *Value {
@ -954,8 +954,6 @@ const Converter = struct {
fn parse_call(noalias converter: *Converter, noalias module: *Module, callable: *Value) *Value { fn parse_call(noalias converter: *Converter, noalias module: *Module, callable: *Value) *Value {
var llvm_abi_argument_value_buffer: [64]*llvm.Value = undefined; var llvm_abi_argument_value_buffer: [64]*llvm.Value = undefined;
const function_type = &callable.type.bb.function; const function_type = &callable.type.bb.function;
const calling_convention = function_type.calling_convention;
_ = calling_convention;
const llvm_indirect_return_value: ?*Value = switch (function_type.return_type_abi.kind) { const llvm_indirect_return_value: ?*Value = switch (function_type.return_type_abi.kind) {
.indirect => @trap(), .indirect => @trap(),
else => null, else => null,
@ -979,6 +977,8 @@ const Converter = struct {
const semantic_argument_value = converter.parse_value(module, function_type.semantic_argument_types[semantic_argument_index], .value); const semantic_argument_value = converter.parse_value(module, function_type.semantic_argument_types[semantic_argument_index], .value);
_ = converter.consume_character_if_match(',');
const argument_abi = function_type.argument_type_abis[semantic_argument_index]; const argument_abi = function_type.argument_type_abis[semantic_argument_index];
switch (argument_abi.kind) { switch (argument_abi.kind) {
@ -1044,7 +1044,10 @@ const Converter = struct {
@trap(); @trap();
}, },
.direct => {}, .direct => {},
else => @trap(), .direct_pair => @trap(),
.direct_coerce => @trap(),
.direct_coerce_int => @trap(),
.expand_coerce => @trap(),
} }
if (llvm_indirect_return_value) |indirect_value| { if (llvm_indirect_return_value) |indirect_value| {
@ -1115,23 +1118,21 @@ const Converter = struct {
converter.skip_space(); converter.skip_space();
if (converter.consume_character_if_match(':')) { const has_type = converter.consume_character_if_match(':');
converter.skip_space(); converter.skip_space();
const local_type = converter.parse_type(module); const local_type_inference: ?*Type = switch (has_type) {
true => converter.parse_type(module),
false => null,
};
converter.skip_space(); converter.skip_space();
converter.expect_character('='); converter.expect_character('=');
converter.skip_space(); const value = converter.parse_value(module, local_type_inference, .value);
const local_type = local_type_inference orelse value.type;
if (module.llvm.di_builder) |_| {
module.llvm.builder.clear_current_debug_location();
}
const value = converter.parse_value(module, local_type, .value);
const local_storage = module.values.add(); const local_storage = module.values.add();
local_storage.* = .{ local_storage.* = .{
.llvm = module.llvm.builder.create_alloca(local_type.llvm.handle, local_name), .llvm = module.llvm.builder.create_alloca(local_type.llvm.handle, local_name),
@ -1159,9 +1160,6 @@ const Converter = struct {
.name = local_name, .name = local_name,
.value = local_storage, .value = local_storage,
}; };
} else {
converter.report_error();
}
} else if (statement_start_ch == '#') { } else if (statement_start_ch == '#') {
const intrinsic = converter.parse_intrinsic(module, null); const intrinsic = converter.parse_intrinsic(module, null);
switch (intrinsic.type.bb) { switch (intrinsic.type.bb) {

View File

@ -189,3 +189,7 @@ test "if_no_else" {
test "comments" { test "comments" {
try invsrc(@src()); try invsrc(@src());
} }
test "local_type_inference" {
try invsrc(@src());
}

View File

@ -0,0 +1,10 @@
foo = fn() s32
{
return 0;
}
[export] main = fn [cc(c)] () s32
{
>a: s32 = 0;
>result = foo() + a;
return result;
}