diff --git a/.gitignore b/.gitignore index 291266b..d96d990 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ imgui.ini /.gdb_history /.zig-cache/ /zig-out/ +/bb-cache/ diff --git a/build.zig b/build.zig index 0fca90e..9518d1b 100644 --- a/build.zig +++ b/build.zig @@ -274,7 +274,13 @@ fn debug_binary(b: *std.Build, exe: *std.Build.Step.Compile) *std.Build.Step.Run run_step.addArg("gdb"); run_step.addArg("-ex"); run_step.addArg("r"); - run_step.addArtifactArg(exe); + if (b.args) |args| { + run_step.addArg("--args"); + run_step.addArtifactArg(exe); + run_step.addArgs(args); + } else { + run_step.addArtifactArg(exe); + } return run_step; } diff --git a/src/compiler.bbb b/src/compiler.bbb new file mode 100644 index 0000000..5ff19c1 --- /dev/null +++ b/src/compiler.bbb @@ -0,0 +1,4 @@ +[export] main = fn [cc(c)] () s32 +{ + return 0; +} diff --git a/src/lib.zig b/src/lib.zig index ecaa8d0..c396c39 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -279,6 +279,16 @@ pub const os = struct { } } + pub fn make_directory(path: [*:0]const u8) void { + switch (builtin.os.tag) { + .windows => @compileError("TODO"), + else => { + const result = posix.mkdir(path, 0o755); + _ = result; + }, + } + } + const linux = struct { pub const CPU_SETSIZE = 128; pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize; @@ -409,6 +419,7 @@ pub const os = struct { extern "c" fn read(fd: system.FileDescriptor, pointer: [*]u8, byte_count: usize) isize; extern "c" fn write(fd: system.FileDescriptor, pointer: [*]const u8, byte_count: usize) isize; extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int; + extern "c" fn mkdir(path: [*:0]const u8, mode: mode_t) c_int; const mode_t = usize; @@ -522,6 +533,29 @@ pub const string = struct { } return result; } + + pub fn first_character(str: []const u8, ch: u8) ?usize { + for (str, 0..) |existing_ch, i| { + if (ch == existing_ch) { + return i; + } + } + + return null; + } + + pub fn last_character(str: []const u8, ch: u8) ?usize { + var i = str.len; + while (i > 0) { + i -= 1; + + if (str[i] == ch) { + return i; + } + } + + return null; + } }; pub const cstring = struct { @@ -2474,6 +2508,7 @@ pub const GlobalState = struct { thread_count: usize, pub var initialized = false; + pub fn initialize() void { assert(!initialized); defer initialized = true; @@ -2515,7 +2550,7 @@ pub fn print(format_string: [*:0]const u8, ...) callconv(.C) void { @cVaEnd(&args); } -pub const print_string = print_string_stdout; +pub const print_string = print_string_stderr; pub fn print_string_stdout(str: []const u8) void { os.get_stdout().write(str); diff --git a/src/main.zig b/src/main.zig index dd442bc..36a45d1 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,4 +1,5 @@ const lib = @import("lib.zig"); +const os = lib.os; const llvm = @import("LLVM.zig"); const converter = @import("converter.zig"); const Arena = lib.Arena; @@ -136,9 +137,45 @@ pub const panic = struct { } }; -var global_persistent_arena: *Arena = undefined; +pub fn main(argc: c_int, argv: [*:null]const ?[*:0]const u8) callconv(.C) c_int { + if (argc != 2) { + lib.print_string("Failed to match argument count"); + return 1; + } + const file_path_pointer = argv[1] orelse return 1; + const file_path = lib.cstring.to_slice(file_path_pointer); + if (file_path.len < 5) { + return 1; + } -pub fn main() callconv(.C) c_int { + const extension_start = lib.string.last_character(file_path, '.') orelse return 1; + if (!lib.string.equal(file_path[extension_start..], ".bbb")) { + return 1; + } + const separator_index = lib.string.last_character(file_path, '/') orelse 0; + const base_start = separator_index + @intFromBool(separator_index != 0 or file_path[separator_index] == '/'); + const base_name = file_path[base_start..extension_start]; + + lib.GlobalState.initialize(); + + const arena = lib.global.arena; + + const build_dir = "bb-cache"; + os.make_directory(build_dir); + const output_path_base = arena.join_string(&.{ build_dir, "/", base_name }); + const output_object_path = arena.join_string(&.{ output_path_base, ".o" }); + const output_executable_path = output_path_base; + + const file_content = lib.file.read(arena, file_path); + converter.convert(.{ + .executable = output_executable_path, + .object = output_object_path, + .name = base_name, + .build_mode = .debug_none, + .content = file_content, + .path = file_path, + .has_debug_info = 1, + }); return 0; }