diff --git a/src/compiler.bbb b/src/compiler.bbb index 5467f4c..8b1b1f1 100644 --- a/src/compiler.bbb +++ b/src/compiler.bbb @@ -174,8 +174,19 @@ global_state_initialize = fn () void }; } -[export] main = fn [cc(c)] (argument_count: u32) s32 +[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8) s32 { + if (argument_count != 2) + { + return 1; + } + + >relative_file_path_pointer = argv[1]; + if (!relative_file_path_pointer) + { + return 1; + } + global_state_initialize(); return 0; } diff --git a/src/converter.zig b/src/converter.zig index bca609b..e57f904 100644 --- a/src/converter.zig +++ b/src/converter.zig @@ -4047,6 +4047,26 @@ const Converter = struct { }; break :b load; }, + .pointer => |pointer| { + const pointer_load = module.create_load(.{ .type = appointee_type, .value = variable.value.llvm }); + const gep = module.llvm.builder.create_gep(.{ + .type = pointer.type.llvm.handle, + .aggregate = pointer_load, + .indices = &.{index.llvm}, + .inbounds = false, + }); + + const load_type = pointer.type; + const load = module.values.add(); + load.* = .{ + .llvm = module.create_load(.{ .type = load_type, .value = gep }), + .type = load_type, + .bb = .instruction, + .lvalue = false, + .dereference_to_assign = false, + }; + break :b load; + }, .structure => |structure| { if (!structure.is_slice) { converter.report_error(); @@ -4060,6 +4080,7 @@ const Converter = struct { .type = element_type.llvm.handle, .aggregate = pointer_load, .indices = &.{index.llvm}, + .inbounds = false, }); const element_load = module.create_load(.{ .type = element_type, .value = gep_to_element, .alignment = pointer_type.bb.pointer.alignment }); const load = module.values.add(); @@ -4118,7 +4139,11 @@ const Converter = struct { .negative, // Already done in 'parse_integer' // TODO: => {}, .not_zero => { - const llvm_value = module.llvm.builder.create_compare(.eq, value.llvm, value.type.llvm.handle.to_integer().get_constant(0, 0).to_value()); + const llvm_value = module.llvm.builder.create_compare(.eq, value.llvm, switch (value.type.bb) { + .integer => value.type.llvm.handle.to_integer().get_constant(0, 0).to_value(), + .pointer => value.type.llvm.handle.get_zero().to_value(), + else => @trap(), + }); value.* = .{ .llvm = llvm_value, .bb = .instruction, diff --git a/src/converter_test.zig b/src/converter_test.zig index 0e84c45..a157598 100644 --- a/src/converter_test.zig +++ b/src/converter_test.zig @@ -19,6 +19,7 @@ fn invoke(name: []const u8) !void { defer arena.restore(arena_position); const c_abi_object_path = arena.duplicate_string(configuration.c_abi_object_path); + const file_path = arena.join_string(&.{ "tests/", name, ".bbb" }); inline for (@typeInfo(BuildMode).@"enum".fields) |f| { const build_mode = @field(BuildMode, f.name); @@ -34,12 +35,13 @@ fn invoke(name: []const u8) !void { try unit_test(arena, allocator, .{ .object_paths = if (lib.string.equal(name, "c_abi")) &.{ object_path, c_abi_object_path } else &.{object_path}, .executable_path = executable_path, - .file_path = arena.join_string(&.{ "tests/", name, ".bbb" }), + .file_path = file_path, .name = name, .directory_path = directory_path, .build_mode = build_mode, .has_debug_info = has_debug_info, .self_hosted_path = null, + .run = true, }); } @@ -54,12 +56,13 @@ fn invoke(name: []const u8) !void { try unit_test(arena, allocator, .{ .object_paths = if (lib.string.equal(name, "c_abi")) &.{ object_path, c_abi_object_path } else &.{object_path}, .executable_path = executable_path, - .file_path = arena.join_string(&.{ "tests/", name, ".bbb" }), + .file_path = file_path, .name = name, .directory_path = directory_path, .build_mode = build_mode, .has_debug_info = has_debug_info, .self_hosted_path = arena.join_string(&.{ "bb-cache/", compiler_basename(arena, build_mode, has_debug_info) }), + .run = true, }); } } @@ -94,6 +97,7 @@ fn compile_the_compiler() !void { const executable_path = base_path; const directory_path = "bb-cache"; const object_path = arena.join_string(&.{ base_path, ".o" }); + try unit_test(arena, allocator, .{ .object_paths = &.{object_path}, .executable_path = executable_path, @@ -103,6 +107,7 @@ fn compile_the_compiler() !void { .build_mode = build_mode, .has_debug_info = has_debug_info, .self_hosted_path = null, + .run = false, }); } } @@ -118,6 +123,7 @@ const InvokeWrapper = struct { has_debug_info: bool, directory_path: [:0]const u8, self_hosted_path: ?[]const u8, + run: bool, }; fn unit_test(arena: *Arena, allocator: std.mem.Allocator, options: InvokeWrapper) anyerror!void { @@ -128,19 +134,20 @@ fn unit_test(arena: *Arena, allocator: std.mem.Allocator, options: InvokeWrapper if (options.self_hosted_path) |self_hosted_path| { try compile_the_compiler(); + const argv = [_][]const u8{ + self_hosted_path, + options.file_path, + }; const run_result = try std.process.Child.run(.{ .allocator = allocator, - .argv = &.{ - self_hosted_path, - options.file_path, - }, + .argv = &argv, }); const success = switch (run_result.term) { .Exited => |exit_code| exit_code == 0, else => false, }; if (!success) { - std.debug.print("{}\n{}\n", .{ run_result, options }); + std.debug.print("{s}\n{}\n{}\n", .{ argv, run_result, options }); return error.compiler_failed_to_run_successfully; } } else { @@ -154,29 +161,33 @@ fn unit_test(arena: *Arena, allocator: std.mem.Allocator, options: InvokeWrapper .has_debug_info = options.has_debug_info, .target = converter.Target.get_native(), }); - const run_result = std.process.Child.run(.{ - .allocator = allocator, - .argv = &.{options.executable_path}, - }) catch |err| { - std.debug.print("error: {}\n", .{err}); - const r = try std.process.Child.run(.{ - .allocator = allocator, - .argv = &.{ "/usr/bin/ls", "-lasR", options.directory_path }, - .max_output_bytes = std.math.maxInt(usize), - }); - defer allocator.free(r.stdout); - defer allocator.free(r.stderr); - std.debug.print("ls {s} {s}\n", .{ options.directory_path, r.stdout }); - return err; - }; - const success = switch (run_result.term) { - .Exited => |exit_code| exit_code == 0, - else => false, - }; - if (!success) { - std.debug.print("{}\n{}\n", .{ run_result, options }); - return error.executable_failed_to_run_successfully; + if (options.run) { + const argv = [_][]const u8{options.executable_path}; + const run_result = std.process.Child.run(.{ + .allocator = allocator, + .argv = &argv, + }) catch |err| { + std.debug.print("error: {}\n", .{err}); + const r = try std.process.Child.run(.{ + .allocator = allocator, + .argv = &.{ "/usr/bin/ls", "-lasR", options.directory_path }, + .max_output_bytes = std.math.maxInt(usize), + }); + defer allocator.free(r.stdout); + defer allocator.free(r.stderr); + std.debug.print("ls {s} {s}\n", .{ options.directory_path, r.stdout }); + return err; + }; + + const success = switch (run_result.term) { + .Exited => |exit_code| exit_code == 0, + else => false, + }; + if (!success) { + std.debug.print("{s} {}\n{}\n", .{ argv, run_result, options }); + return error.executable_failed_to_run_successfully; + } } } } @@ -428,3 +439,7 @@ test "basic_slice" { test "basic_string" { try invsrc(@src()); } + +test "argv" { + try invsrc(@src()); +} diff --git a/src/main.zig b/src/main.zig index d1b9635..d8b79d0 100644 --- a/src/main.zig +++ b/src/main.zig @@ -45,7 +45,7 @@ pub fn main(argc: c_int, argv: [*:null]const ?[*:0]const u8) callconv(.C) c_int .build_mode = .debug_none, .content = file_content, .path = file_path, - .has_debug_info = false, + .has_debug_info = true, .target = converter.Target.get_native(), }); return 0; diff --git a/tests/argv.bbb b/tests/argv.bbb new file mode 100644 index 0000000..690c97a --- /dev/null +++ b/tests/argv.bbb @@ -0,0 +1,13 @@ +[export] main = fn [cc(c)] (argument_count: u32, argument_pointer: &&u8) s32 +{ + if (argument_count != 1) + { + return 1; + } + >arg = argument_pointer[0]; + if (arg != argument_pointer[0]) + { + return 1; + } + return 0; +}