From 8b1013b3e75b4d06f67c9346ddcb632c264648ec Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Mon, 24 Mar 2025 12:44:18 +0100 Subject: [PATCH] Implement `integer_max` --- src/compiler.bbb | 14 +++++++++++++- src/converter.zig | 33 ++++++++++++++++++++++++++++++++- src/converter_test.zig | 4 ++++ tests/integer_max.bbb | 5 +++++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 tests/integer_max.bbb diff --git a/src/compiler.bbb b/src/compiler.bbb index 51cff58..f42a28d 100644 --- a/src/compiler.bbb +++ b/src/compiler.bbb @@ -38,6 +38,8 @@ OS_Linux_MAP = bits u32 _: u5, } +[extern] mmap = fn [cc(c)] (address: u64, size: u64, protection: OS_Linux_PROT, map: OS_Linux_MAP, file_descriptor: s32, offset: s64) &u8; + OS_ProtectionFlags = bits { read: u1, @@ -74,8 +76,18 @@ os_linux_map_flags = fn(map_flags: OS_MapFlags) OS_Linux_MAP }; } -os_reserve = fn (base: u64, protection: OS_ProtectionFlags, map: OS_MapFlags) &u8 +os_reserve = fn (base: u64, size: u64, protection: OS_ProtectionFlags, map: OS_MapFlags) &u8 { + >protection_flags = os_linux_protection_flags(protection); + >map_flags = os_linux_map_flags(map); + >address = mmap(base, size, protection_flags, map_flags, -1, 0); + //if (address == #integer_max(u64)) + //{ + // unreachable; + //} + //else + //{ + //} } Arena = struct diff --git a/src/converter.zig b/src/converter.zig index 9ad76b2..5991c67 100644 --- a/src/converter.zig +++ b/src/converter.zig @@ -1802,7 +1802,7 @@ const Converter = struct { }; _ = &v; - if (coerce_to_type != v.type) { + if (!coerce_to_type.is_abi_equal(v.type)) { switch (v.type) { else => @trap(), } @@ -2637,6 +2637,7 @@ const Converter = struct { cast, cast_to, extend, + integer_max, int_from_enum, select, trap, @@ -2735,6 +2736,36 @@ const Converter = struct { return value; }, + .integer_max => { + converter.skip_space(); + const ty = converter.parse_type(module); + converter.expect_character(right_parenthesis); + if (ty.bb != .integer) { + converter.report_error(); + } + const bit_count = ty.bb.integer.bit_count; + const max_value = if (bit_count == 64) ~@as(u64, 0) else (@as(u64, 1) << @intCast(bit_count - @intFromBool(ty.bb.integer.signed))) - 1; + const expected_ty = expected_type orelse ty; + if (ty.get_bit_size() > expected_ty.get_bit_size()) { + converter.report_error(); + } + const constant_integer = expected_ty.llvm.handle.to_integer().get_constant(max_value, @intFromBool(false)); + const value = module.values.add(); + value.* = .{ + .llvm = constant_integer.to_value(), + .type = expected_ty, + .bb = .{ + .constant_integer = .{ + .value = max_value, + .signed = false, + }, + }, + .lvalue = false, + .dereference_to_assign = false, + }; + + return value; + }, .int_from_enum => { const source_value = converter.parse_value(module, null, .value); converter.skip_space(); diff --git a/src/converter_test.zig b/src/converter_test.zig index bf03b6e..0e944ef 100644 --- a/src/converter_test.zig +++ b/src/converter_test.zig @@ -400,3 +400,7 @@ test "select" { test "bits_return_u1" { try invsrc(@src()); } + +test "integer_max" { + try invsrc(@src()); +} diff --git a/tests/integer_max.bbb b/tests/integer_max.bbb new file mode 100644 index 0000000..585cf43 --- /dev/null +++ b/tests/integer_max.bbb @@ -0,0 +1,5 @@ +[export] main = fn [cc(c)] () s32 +{ + >a = #integer_max(u64); + return #truncate(a + 1); +}