Return type builtin

This commit is contained in:
David Gonzalez Martin 2025-03-23 20:08:28 +01:00
parent 0a778aa94f
commit 4fa1ba260a
4 changed files with 83 additions and 10 deletions

View File

@ -1,4 +1,4 @@
Linux_PROT = bits u32 OS_Linux_PROT = bits u32
{ {
read: u1, read: u1,
write: u1, write: u1,
@ -7,14 +7,45 @@ Linux_PROT = bits u32
_: u28, _: u28,
} }
OSProtectionFlags = bits OS_Linux_MAP_Type = enum u4
{
shared = 0x1,
private = 0x2,
shared_validate = 0x3,
}
OS_Linux_MAP = bits u32
{
type: OS_Linux_MAP_Type,
fixed: u1,
anonymous: u1,
bit_32: u1,
_: u1,
grows_down: u1,
_: u2,
deny_write: u1,
executable: u1,
locked: u1,
no_reserve: u1,
populate: u1,
non_block: u1,
stack: u1,
huge_tlb: u1,
sync: u1,
fixed_noreplace: u1,
_: u5,
uninitialized: u1,
_: u5,
}
OS_ProtectionFlags = bits
{ {
read: u1, read: u1,
write: u1, write: u1,
execute: u1, execute: u1,
} }
OSMapFlags = bits OS_MapFlags = bits
{ {
private: u1, private: u1,
anonymous: u1, anonymous: u1,
@ -22,7 +53,11 @@ OSMapFlags = bits
populate: u1, populate: u1,
} }
os_reserve = fn (base: u64, protection: OSProtectionFlags, map: OSMapFlags) &u8 os_linux_map_flags = fn(map_flags: OS_MapFlags) OS_Linux_MAP
{
}
os_reserve = fn (base: u64, protection: OS_ProtectionFlags, map: OS_MapFlags) &u8
{ {
} }

View File

@ -1231,7 +1231,7 @@ pub const Type = struct {
.void, .forward_declaration, .function, .noreturn => unreachable, .void, .forward_declaration, .function, .noreturn => unreachable,
.array => |*array| array.element_type.get_bit_size() * array.element_count.?, .array => |*array| array.element_type.get_bit_size() * array.element_count.?,
.pointer => 64, .pointer => 64,
.enumerator => @trap(), .enumerator => |enumerator| enumerator.backing_type.get_bit_size(),
.float => @trap(), .float => @trap(),
.vector => @trap(), .vector => @trap(),
}; };
@ -1480,6 +1480,7 @@ const Converter = struct {
.type = element_type, .type = element_type,
}); });
}, },
'#' => return converter.parse_type_intrinsic(module),
else => @trap(), else => @trap(),
} }
} }
@ -2126,7 +2127,7 @@ const Converter = struct {
.value = local_storage, .value = local_storage,
}; };
} else if (statement_start_ch == '#') { } else if (statement_start_ch == '#') {
const intrinsic = converter.parse_intrinsic(module, null); const intrinsic = converter.parse_value_intrinsic(module, null);
switch (intrinsic.type.bb) { switch (intrinsic.type.bb) {
.void, .noreturn => {}, .void, .noreturn => {},
else => @trap(), else => @trap(),
@ -2575,7 +2576,7 @@ const Converter = struct {
not_zero, not_zero,
}; };
const Intrinsic = enum { const ValueIntrinsic = enum {
byte_size, byte_size,
cast, cast,
cast_to, cast_to,
@ -2589,11 +2590,11 @@ const Converter = struct {
va_arg, va_arg,
}; };
fn parse_intrinsic(noalias converter: *Converter, noalias module: *Module, expected_type: ?*Type) *Value { fn parse_value_intrinsic(noalias converter: *Converter, noalias module: *Module, expected_type: ?*Type) *Value {
converter.expect_character('#'); converter.expect_character('#');
converter.skip_space(); converter.skip_space();
const intrinsic_name = converter.parse_identifier(); const intrinsic_name = converter.parse_identifier();
const intrinsic_keyword = string_to_enum(Intrinsic, intrinsic_name) orelse converter.report_error(); const intrinsic_keyword = string_to_enum(ValueIntrinsic, intrinsic_name) orelse converter.report_error();
converter.skip_space(); converter.skip_space();
converter.expect_character(left_parenthesis); converter.expect_character(left_parenthesis);
@ -2921,6 +2922,34 @@ const Converter = struct {
} }
} }
const TypeIntrinsic = enum {
ReturnType,
};
fn parse_type_intrinsic(noalias converter: *Converter, noalias module: *Module) *Type {
converter.expect_character('#');
converter.skip_space();
const intrinsic_name = converter.parse_identifier();
const intrinsic_keyword = string_to_enum(TypeIntrinsic, intrinsic_name) orelse converter.report_error();
converter.skip_space();
converter.expect_character(left_parenthesis);
converter.skip_space();
switch (intrinsic_keyword) {
.ReturnType => {
converter.skip_space();
converter.expect_character(right_parenthesis);
const current_function_variable = module.current_function orelse converter.report_error();
const return_type = current_function_variable.value.type.bb.pointer.type.bb.function.return_type_abi.semantic_type;
return return_type;
},
}
@trap();
}
fn parse_single_value(noalias converter: *Converter, noalias module: *Module, expected_type: ?*Type, value_kind: ValueKind) *Value { fn parse_single_value(noalias converter: *Converter, noalias module: *Module, expected_type: ?*Type, value_kind: ValueKind) *Value {
converter.skip_space(); converter.skip_space();
@ -3211,7 +3240,7 @@ const Converter = struct {
else => @trap(), else => @trap(),
} }
}, },
'#' => return converter.parse_intrinsic(module, expected_type), '#' => return converter.parse_value_intrinsic(module, expected_type),
'&' => { '&' => {
converter.offset += 1; converter.offset += 1;
return converter.parse_value(module, expected_type, .pointer); return converter.parse_value(module, expected_type, .pointer);

View File

@ -380,3 +380,7 @@ test "bits_no_backing_type" {
test "basic_enum" { test "basic_enum" {
try invsrc(@src()); try invsrc(@src());
} }
test "return_type_builtin" {
try invsrc(@src());
}

View File

@ -0,0 +1,5 @@
[export] main = fn () s32
{
>result: #ReturnType() = 0;
return result;
}