From 2ac5e19b324f920c34e825776c52e0852ca3ab2a Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Thu, 18 Apr 2024 07:41:59 -0600 Subject: [PATCH] One's complement implementation --- bootstrap/Compilation.zig | 29 +++++++++++++++++++++++++ bootstrap/frontend/lexer.zig | 4 ++++ bootstrap/frontend/parser.zig | 2 ++ lib/std/std.nat | 5 +++++ src/main.nat | 9 -------- test/standalone/one_complement/main.nat | 15 +++++++++++++ 6 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 test/standalone/one_complement/main.nat diff --git a/bootstrap/Compilation.zig b/bootstrap/Compilation.zig index 7dae379..bf97e34 100644 --- a/bootstrap/Compilation.zig +++ b/bootstrap/Compilation.zig @@ -11766,6 +11766,34 @@ pub const Builder = struct { .type => |type_index| try builder.resolveContainerLiteral(unit, context, &.{}, type_index), else => |t| @panic(@tagName(t)), }, + .one_complement => block: { + const value = try builder.resolveRuntimeValue(unit, context, type_expect, node.left, .right); + const not = try unit.instructions.append(context.my_allocator, .{ + .integer_binary_operation = .{ + .id = .bit_xor, + .left = value, + .right = .{ + .value = .{ + .@"comptime" = .{ + .constant_int = .{ + .value = @bitCast(@as(i64, -1)), + }, + }, + }, + .type = value.type, + }, + .signedness = .unsigned, + }, + }); + try builder.appendInstruction(unit, context, not); + + break :block V{ + .type = value.type, + .value = .{ + .runtime = not, + }, + }; + }, else => |t| @panic(@tagName(t)), }; @@ -16831,6 +16859,7 @@ pub const Token = struct { operator_dollar, operator_switch_case, operator_backtick, + operator_tilde, // Binary operator_assign, operator_add, diff --git a/bootstrap/frontend/lexer.zig b/bootstrap/frontend/lexer.zig index 2ee575e..4c92030 100644 --- a/bootstrap/frontend/lexer.zig +++ b/bootstrap/frontend/lexer.zig @@ -265,6 +265,10 @@ pub fn analyze(allocator: *MyAllocator, text: []const u8, token_buffer: *Token.B index += 1; break :blk .operator_colon; }, + '~' => blk: { + index += 1; + break :blk .operator_tilde; + }, '!' => blk: { index += 1; switch (text[index]) { diff --git a/bootstrap/frontend/parser.zig b/bootstrap/frontend/parser.zig index 103bd5a..0496b2d 100644 --- a/bootstrap/frontend/parser.zig +++ b/bootstrap/frontend/parser.zig @@ -156,6 +156,7 @@ pub const Node = struct { slice, range, negation, + one_complement, anonymous_container_literal, anonymous_array_literal, array_literal, @@ -1226,6 +1227,7 @@ const Analyzer = struct { }, .operator_bang => .boolean_not, .operator_minus => .negation, + .operator_tilde => .one_complement, .fixed_keyword_try => .try_expression, // .tilde => |t| @panic(@tagName(t)), }; diff --git a/lib/std/std.nat b/lib/std/std.nat index 69b2b40..336722e 100644 --- a/lib/std/std.nat +++ b/lib/std/std.nat @@ -210,6 +210,11 @@ const concatenate_bytes = fn (arena: &Arena, byte_sequences: []const []const u8) return concatenation; } +const align_forward = fn(value: u64, alignment: u64) u64 { + const mask = alignment - 1; + return (value + mask) & ~mask; +} + test "concatenate" { var arena = try Arena.init(2*1024*1024); const concatenation = try concatenate_bytes(arena, .{ "ABC", "DEF" }.&); diff --git a/src/main.nat b/src/main.nat index 478121b..cdb005c 100644 --- a/src/main.nat +++ b/src/main.nat @@ -31,15 +31,6 @@ const lex = fn (arena: &Arena, bytes: []const u8) *!void { index += 1; } - - print("Line count: "); - print_usize(line_count); - print("\n"); - - for (line_offsets[0..line_count]) |offset| { - print_usize(offset); - print("\n"); - } } const get_argument = fn (real_argument: []const u8, wanted_argument: []const u8, command_arguments: []const [&:0]const u8, i_ptr: &usize) ?[]const u8 { diff --git a/test/standalone/one_complement/main.nat b/test/standalone/one_complement/main.nat new file mode 100644 index 0000000..a0a0483 --- /dev/null +++ b/test/standalone/one_complement/main.nat @@ -0,0 +1,15 @@ +const std = #import("std"); +const align_forward = std.align_forward; +const expect = std.testing.expect; + +const main = fn () *!void { + const a: u64 = 1; + const aligned_a = align_forward(a, 8); + try expect(aligned_a == 8); + const b: u64 = 9; + const aligned_b = align_forward(b, 8); + try expect(aligned_b == 16); + const c = 512; + const aligned_c = align_forward(c, 0x1000); + try expect(aligned_c == 0x1000); +}