From 4fa1ba260af906fe5fbca0f8f3814424d44006aa Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Sun, 23 Mar 2025 20:08:28 +0100 Subject: [PATCH] Return type builtin --- src/compiler.bbb | 43 +++++++++++++++++++++++++++++++---- src/converter.zig | 41 ++++++++++++++++++++++++++++----- src/converter_test.zig | 4 ++++ tests/return_type_builtin.bbb | 5 ++++ 4 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 tests/return_type_builtin.bbb diff --git a/src/compiler.bbb b/src/compiler.bbb index a4fe5cc..94746cb 100644 --- a/src/compiler.bbb +++ b/src/compiler.bbb @@ -1,4 +1,4 @@ -Linux_PROT = bits u32 +OS_Linux_PROT = bits u32 { read: u1, write: u1, @@ -7,14 +7,45 @@ Linux_PROT = bits u32 _: 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, write: u1, execute: u1, } -OSMapFlags = bits +OS_MapFlags = bits { private: u1, anonymous: u1, @@ -22,7 +53,11 @@ OSMapFlags = bits 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 { } diff --git a/src/converter.zig b/src/converter.zig index a31401e..fe9c156 100644 --- a/src/converter.zig +++ b/src/converter.zig @@ -1231,7 +1231,7 @@ pub const Type = struct { .void, .forward_declaration, .function, .noreturn => unreachable, .array => |*array| array.element_type.get_bit_size() * array.element_count.?, .pointer => 64, - .enumerator => @trap(), + .enumerator => |enumerator| enumerator.backing_type.get_bit_size(), .float => @trap(), .vector => @trap(), }; @@ -1480,6 +1480,7 @@ const Converter = struct { .type = element_type, }); }, + '#' => return converter.parse_type_intrinsic(module), else => @trap(), } } @@ -2126,7 +2127,7 @@ const Converter = struct { .value = local_storage, }; } else if (statement_start_ch == '#') { - const intrinsic = converter.parse_intrinsic(module, null); + const intrinsic = converter.parse_value_intrinsic(module, null); switch (intrinsic.type.bb) { .void, .noreturn => {}, else => @trap(), @@ -2575,7 +2576,7 @@ const Converter = struct { not_zero, }; - const Intrinsic = enum { + const ValueIntrinsic = enum { byte_size, cast, cast_to, @@ -2589,11 +2590,11 @@ const Converter = struct { 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.skip_space(); 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.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 { converter.skip_space(); @@ -3211,7 +3240,7 @@ const Converter = struct { else => @trap(), } }, - '#' => return converter.parse_intrinsic(module, expected_type), + '#' => return converter.parse_value_intrinsic(module, expected_type), '&' => { converter.offset += 1; return converter.parse_value(module, expected_type, .pointer); diff --git a/src/converter_test.zig b/src/converter_test.zig index e674bd3..d776e60 100644 --- a/src/converter_test.zig +++ b/src/converter_test.zig @@ -380,3 +380,7 @@ test "bits_no_backing_type" { test "basic_enum" { try invsrc(@src()); } + +test "return_type_builtin" { + try invsrc(@src()); +} diff --git a/tests/return_type_builtin.bbb b/tests/return_type_builtin.bbb new file mode 100644 index 0000000..039b897 --- /dev/null +++ b/tests/return_type_builtin.bbb @@ -0,0 +1,5 @@ +[export] main = fn () s32 +{ + >result: #ReturnType() = 0; + return result; +}