comptime { _ = start; } test { _ = build; _ = builtin; _ = data_structures; _ = os; _ = start; } const build = #import("build.nat"); const builtin = #import("builtin.nat"); const testing = #import("testing.nat"); const data_structures = #import("data_structures.nat"); const c = #import("c.nat"); const os = #import("os.nat"); const start = #import("start.nat"); const assert = fn(ok: bool) void { if (!ok) { unreachable; } } const print = fn(bytes: []const u8) void { const file_descriptor = os.StdFileDescriptor.get(descriptor = .stdout); const file_writer = FileWriter{ .descriptor = file_descriptor, }; _ = file_writer.write_all(bytes) catch unreachable; } const format_usize = fn(n: usize, buffer: &[65]u8) []u8 { var index: usize = buffer.length; var absolute = n; while (true) { const digit: u8 = #cast(absolute % 10); index -= 1; const ch = '0' + digit; buffer[index] = ch; assert(buffer[index] == ch); absolute /= 10; if (absolute == 0) { break; } } return buffer[index..]; } const print_usize = fn(n: usize) void { var buffer: [65]u8 = undefined; const bytes = format_usize(n, buffer = buffer.&); assert(bytes.length < buffer.length); const file_descriptor = os.StdFileDescriptor.get(descriptor = .stdout); const file_writer = FileWriter{ .descriptor = file_descriptor, }; file_writer.write_all(bytes) catch unreachable; } const print_u8 = fn(n: u8) void { print_usize(n); } const kilobytes = fn (n: u64) u64 { return n * 1024; } const megabytes = fn (n: u64) u64 { return n * 1024 * 1024; } const gigabytes = fn (n: u64) u64 { return n * 1024 * 1024 * 1024; } const terabytes = fn (n: u64) u64 { return n * 1024 * 1024 * 1024 * 1024; } const Arena = struct{ position: u64, commit_position: u64, alignment: u64, size: u64, const Temporary = struct{ arena: &Arena, position: u64, }; const commit_granularity = 2 * 1024 * 1024; const allocate = fn (requested_size: u64) *!&Arena { var size = requested_size; const size_roundup_granularity = megabytes(64); size += size_roundup_granularity - 1; size -= size % size_roundup_granularity; const initial_commit_size = commit_granularity; assert(initial_commit_size >= #size(Arena)); const reserved_memory = try os.reserve(size); try os.commit(reserved_memory, initial_commit_size); const arena: &Arena = #cast(reserved_memory); arena.@ = .{ .position = #size(Arena), .commit_position = initial_commit_size, .alignment = 8, .size = size, }; return arena; } }; const Writer = struct{ callback: &const fn(writer: &Writer, bytes: []const u8) Writer.Error!usize, const Error = error{ write_failed, }; }; const FileWriter = struct{ descriptor: os.FileDescriptor, const write = fn(file_writer: FileWriter, bytes: []const u8) Writer.Error!usize { const bytes_written = file_writer.descriptor.write(bytes) catch return Writer.Error.write_failed; return bytes_written; } const write_all = fn(file_writer: FileWriter, bytes: []const u8) Writer.Error!void { var bytes_written: usize = 0; while (bytes_written < bytes.length) { const iteration_written_byte_count = try file_writer.write(bytes = bytes[bytes_written..]); bytes_written += iteration_written_byte_count; } assert(bytes_written == bytes.length); } }; const copy_bytes = fn(destination: []u8, source: []const u8) void { assert(ok = destination.length == source.length); for (0..destination.length) |i| { destination[i] = source[i]; } } const concatenate_bytes = fn(allocator: &Allocator, slices: []const []const u8) Allocator.Error![]u8 { var total_byte_count: usize = 0; for (slices) |slice| { total_byte_count += slice.length; } const bytes = try allocator.allocate(total_byte_count, 1); var offset: usize = 0; for (slice) |slice| { copy_bytes(bytes[offset..][0..slice.length], slice); offset += slice.length; } return bytes; } const Target = struct { cpu: builtin.Cpu, os: builtin.Os, abi: builtin.Abi, }; var page_allocator = PageAllocator{};