diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d7d0917..a0e478a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,44 +20,44 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: Set up Zig - uses: davidgm94/setup-zig@foo + uses: goto-bus-stop/setup-zig@v2 with: version: master - name: Test run: zig build test -Dself_hosted_ci=true -Dllvm_path=../../../../../dev/llvm/llvm-static-release-zen4-17.0.6/out/x86_64-linux-musl-native - macos_m1: - runs-on: macos-14 - timeout-minutes: 15 - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Zig - uses: davidgm94/setup-zig@foo - with: - version: master - - name: Build - run: zig build -Dthird_party_ci=true -Dtarget=aarch64-macos-none -Dcpu=apple_m1 - linux_x86_64_v3: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Zig - uses: davidgm94/setup-zig@foo - with: - version: master - - name: Build - run: zig build -Dthird_party_ci=true -Dtarget=x86_64-linux-musl -Dcpu=x86_64_v3 - windows_x86_64_v3: - runs-on: windows-latest - timeout-minutes: 15 - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Zig - uses: davidgm94/setup-zig@foo - with: - version: master - - name: Build - run: zig build -Dthird_party_ci=true -Dtarget=x86_64-windows-gnu -Dcpu=x86_64_v3 + # macos_m1: + # runs-on: macos-14 + # timeout-minutes: 15 + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + # - name: Set up Zig + # uses: davidgm94/setup-zig@foo + # with: + # version: master + # - name: Build + # run: zig build -Dthird_party_ci=true -Dtarget=aarch64-macos-none -Dcpu=apple_m1 + # linux_x86_64_v3: + # runs-on: ubuntu-latest + # timeout-minutes: 15 + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + # - name: Set up Zig + # uses: davidgm94/setup-zig@foo + # with: + # version: master + # - name: Build + # run: zig build -Dthird_party_ci=true -Dtarget=x86_64-linux-musl -Dcpu=x86_64_v3 + # windows_x86_64_v3: + # runs-on: windows-latest + # timeout-minutes: 15 + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + # - name: Set up Zig + # uses: davidgm94/setup-zig@foo + # with: + # version: master + # - name: Build + # run: zig build -Dthird_party_ci=true -Dtarget=x86_64-windows-gnu -Dcpu=x86_64_v3 diff --git a/bootstrap/Compilation.zig b/bootstrap/Compilation.zig index 5a97569..a4ccb36 100644 --- a/bootstrap/Compilation.zig +++ b/bootstrap/Compilation.zig @@ -558,7 +558,15 @@ pub const Instruction = union(enum) { const Id = enum{ add, + div, + mod, mul, + sub, + bit_and, + bit_or, + bit_xor, + shift_left, + shift_right, }; }; @@ -578,6 +586,7 @@ pub const Instruction = union(enum) { type: Type.Index, const Id = enum{ + bitcast, enum_to_int, int_to_pointer, sign_extend, @@ -760,6 +769,7 @@ pub const Debug = struct{ pub const Local = struct{ declaration: Declaration, + init_value: V, pub const List = BlockList(@This(), enum{}); pub usingnamespace List.Index; }; @@ -976,7 +986,8 @@ pub const Builder = struct { else => |t| @panic(@tagName(t)), }, .identifier => b: { - const result = try builder.resolveIdentifier(unit, context, Type.Expect.none, operand_node_index, .left); + const identifier = unit.getExpectedTokenBytes(operand_node.token, .identifier); + const result = try builder.resolveIdentifier(unit, context, Type.Expect.none, identifier, .left); break :b .{ .value = result, @@ -1052,7 +1063,8 @@ pub const Builder = struct { .unsigned => .sign_extend, }; } else { - unreachable; + assert(destination_integer.signedness != source_integer.signedness); + break :b .bitcast; } }, else => |t| @panic(@tagName(t)), @@ -1660,14 +1672,16 @@ pub const Builder = struct { const local_declaration = @fieldParentPtr(Debug.Declaration.Local, "declaration", declaration); const local_scope = @fieldParentPtr(Debug.Scope.Local, "scope", scope); - const instruction_index = local_scope.local_declaration_map.get(local_declaration).?; - - return .{ - .value = .{ - .runtime = instruction_index, - }, - .type = declaration.type, - }; + if (local_scope.local_declaration_map.get(local_declaration)) |instruction_index| { + return .{ + .value = .{ + .runtime = instruction_index, + }, + .type = declaration.type, + }; + } else { + return local_declaration.init_value; + } } const TypeCheckResult = enum{ @@ -1709,6 +1723,20 @@ pub const Builder = struct { else =>|t| @panic(@tagName(t)), } }, + .integer => |destination_integer| { + switch (source.*) { + .integer => |source_integer| { + if (destination_integer.signedness == source_integer.signedness) { + if (destination_integer.bit_count == source_integer.bit_count) { + unreachable; + } + } + + unreachable; + }, + else => |t| @panic(@tagName(t)), + } + }, else => |t| @panic(@tagName(t)), } unreachable; @@ -1720,10 +1748,7 @@ pub const Builder = struct { right, }; - fn resolveIdentifier(builder: *Builder, unit: *Unit, context: *const Context, type_expect: Type.Expect, node_index: Node.Index, side: Side) !V { - const node = unit.getNode(node_index); - const identifier = unit.getExpectedTokenBytes(node.token, .identifier); - + fn resolveIdentifier(builder: *Builder, unit: *Unit, context: *const Context, type_expect: Type.Expect, identifier: []const u8, side: Side) !V { const hash = try unit.processIdentifier(context, identifier); const look_in_parent_scopes = true; @@ -2350,7 +2375,8 @@ pub const Builder = struct { const node = unit.getNode(node_index); switch (node.id) { .identifier => { - const result = try builder.resolveIdentifier(unit, context, type_expect, node_index, side); + const identifier = unit.getExpectedTokenBytes(node.token, .identifier); + const result = try builder.resolveIdentifier(unit, context, type_expect, identifier, side); return result; }, .intrinsic => { @@ -2397,18 +2423,18 @@ pub const Builder = struct { .type = load_type, }; }, - .add, .mul => { + .add, .sub, .mul, .div, .mod, .bit_and, .bit_or, .bit_xor, .shift_left, .shift_right => { const left_node_index = node.left; const right_node_index = node.left; const binary_operation_id: BinaryOperationId = switch (node.id) { .add => .add, .sub => .sub, - .bit_and => .bit_and, - .bit_xor => .bit_xor, - .bit_or => .bit_or, .mul => .mul, .div => .div, .mod => .mod, + .bit_and => .bit_and, + .bit_xor => .bit_xor, + .bit_or => .bit_or, .shift_left => .shift_left, .shift_right => .shift_right, .compare_equal => .compare_equal, @@ -2490,7 +2516,15 @@ pub const Builder = struct { .integer => |integer| b: { const id: Instruction.IntegerBinaryOperation.Id = switch (binary_operation_id) { .add => .add, + .div => .div, + .mod => .mod, .mul => .mul, + .sub => .sub, + .bit_and => .bit_and, + .bit_or => .bit_or, + .bit_xor => .bit_xor, + .shift_left => .shift_left, + .shift_right => .shift_right, else => |t| @panic(@tagName(t)), }; @@ -2748,9 +2782,11 @@ pub const Builder = struct { .column = token_debug_info.column, .kind = .local, }, + .init_value = initialization, }); const local_declaration = unit.local_declarations.get(declaration_index); + assert(builder.current_scope.kind == .block); try builder.current_scope.declarations.putNoClobber(context.allocator, identifier_hash, &local_declaration.declaration); if (emit) { diff --git a/bootstrap/backend/llvm.zig b/bootstrap/backend/llvm.zig index 1ba5b09..a7d03c0 100644 --- a/bootstrap/backend/llvm.zig +++ b/bootstrap/backend/llvm.zig @@ -3181,6 +3181,10 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo .pointer_var_to_const => { try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, value); }, + .bitcast => { + const bitcast = llvm.builder.createCast(.bitcast, value, dest_type, "bitcast", "bitcast".len) orelse return LLVM.Value.Instruction.Error.cast; + try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, bitcast); + }, else => |t| @panic(@tagName(t)), } }, @@ -3206,11 +3210,27 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo const no_signed_wrapping = binary_operation.signedness == .signed; const no_unsigned_wrapping = binary_operation.signedness == .unsigned; const name = @tagName(binary_operation.id); - // + const is_exact = false; const instruction = switch (binary_operation.id) { .add => llvm.builder.createAdd(left, right, name.ptr, name.len, no_unsigned_wrapping, no_signed_wrapping) orelse return LLVM.Value.Instruction.Error.add, .mul => llvm.builder.createMultiply(left, right, name.ptr, name.len, no_unsigned_wrapping, no_signed_wrapping) orelse return LLVM.Value.Instruction.Error.multiply, - // .sub => llvm.builder.createSub(left, right, name.ptr, name.len, no_unsigned_wrapping, no_signed_wrapping) orelse return LLVM.Value.Instruction.Error.add, + .sub => llvm.builder.createSub(left, right, name.ptr, name.len, no_unsigned_wrapping, no_signed_wrapping) orelse return LLVM.Value.Instruction.Error.add, + .div => switch (binary_operation.signedness) { + .unsigned => llvm.builder.createUDiv(left, right, name.ptr, name.len, is_exact) orelse unreachable, + .signed => llvm.builder.createSDiv(left, right, name.ptr, name.len, is_exact) orelse unreachable, + }, + .mod => switch (binary_operation.signedness) { + .unsigned => llvm.builder.createURem(left, right, name.ptr, name.len) orelse unreachable, + .signed => llvm.builder.createSRem(left, right, name.ptr, name.len) orelse unreachable, + }, + .bit_and => llvm.builder.createAnd(left, right, name.ptr, name.len) orelse unreachable, + .bit_or => llvm.builder.createOr(left, right, name.ptr, name.len) orelse unreachable, + .bit_xor => llvm.builder.createXor(left, right, name.ptr, name.len) orelse unreachable, + .shift_left => llvm.builder.createShiftLeft(left, right, name.ptr, name.len, no_unsigned_wrapping, no_signed_wrapping) orelse unreachable, + .shift_right => switch (binary_operation.signedness) { + .unsigned => llvm.builder.createLogicalShiftRight(left, right, name.ptr, name.len, is_exact) orelse unreachable, + .signed => llvm.builder.createArithmeticShiftRight(left, right, name.ptr, name.len, is_exact) orelse unreachable, + }, //else => |t| @panic(@tagName(t)), }; try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, instruction); diff --git a/build/test_runner.zig b/build/test_runner.zig index 94ff32c..30d8d3f 100644 --- a/build/test_runner.zig +++ b/build/test_runner.zig @@ -55,10 +55,10 @@ pub fn main() !void { }; std.debug.print("[{s}]\n", .{if (success) "OK" else "FAIL"}); if (process_run.stdout.len > 0) { - std.debug.print("\tSTDOUT:\n{s}\n\n", .{process_run.stdout}); + std.debug.print("STDOUT:\n\n{s}\n\n", .{process_run.stdout}); } if (process_run.stderr.len > 0) { - std.debug.print("\tSTDERR:\n{s}\n\n", .{process_run.stderr}); + std.debug.print("STDERR:\n\n{s}\n\n", .{process_run.stderr}); } } diff --git a/todo_test/standalone/add_sub/main.nat b/test/standalone/add_sub/main.nat similarity index 100% rename from todo_test/standalone/add_sub/main.nat rename to test/standalone/add_sub/main.nat diff --git a/todo_test/standalone/and/main.nat b/test/standalone/and/main.nat similarity index 100% rename from todo_test/standalone/and/main.nat rename to test/standalone/and/main.nat diff --git a/todo_test/standalone/div/main.nat b/test/standalone/div/main.nat similarity index 100% rename from todo_test/standalone/div/main.nat rename to test/standalone/div/main.nat diff --git a/todo_test/standalone/imul/main.nat b/test/standalone/imul/main.nat similarity index 100% rename from todo_test/standalone/imul/main.nat rename to test/standalone/imul/main.nat diff --git a/todo_test/standalone/or/main.nat b/test/standalone/or/main.nat similarity index 100% rename from todo_test/standalone/or/main.nat rename to test/standalone/or/main.nat diff --git a/todo_test/standalone/shifts/main.nat b/test/standalone/shifts/main.nat similarity index 80% rename from todo_test/standalone/shifts/main.nat rename to test/standalone/shifts/main.nat index dfc8fdd..bd19287 100644 --- a/todo_test/standalone/shifts/main.nat +++ b/test/standalone/shifts/main.nat @@ -3,5 +3,5 @@ const main = fn() s32 { x = x << 5; x = x >> 5; const b: u32 = 1; - return x - b; + return #cast(x - b); } diff --git a/todo_test/standalone/xor/main.nat b/test/standalone/xor/main.nat similarity index 100% rename from todo_test/standalone/xor/main.nat rename to test/standalone/xor/main.nat