diff --git a/build.zig b/build.zig index 1c1d4f832edf1db9fbb7fd0673a2e5d67de2e3d6..84c3b05edac66898d23d1d677909c99a3a01f037 100644 --- a/build.zig +++ b/build.zig @@ -53,6 +53,10 @@ pub fn build(b: &Builder) { "std/special/compiler_rt/index.zig", "compiler-rt", "Run the compiler_rt tests", with_lldb)); + test_step.dependOn(tests.addPkgTests(b, test_filter, + "src-self-hosted/main.zig", "fmt", "Run the fmt tests", + with_lldb)); + test_step.dependOn(tests.addCompareOutputTests(b, test_filter)); test_step.dependOn(tests.addBuildExampleTests(b, test_filter)); test_step.dependOn(tests.addCompileErrorTests(b, test_filter)); diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 705281e441d855ca6f8d50d3c1f10036fc456202..209ee829e593cd7317d56b6037690ba1b22c07b2 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -1387,6 +1387,7 @@ const Parser = struct { %return stream.print("("); + %return stack.append(RenderState { .Text = "\n" }); if (fn_proto.fn_def_node == null) { %return stack.append(RenderState { .Text = ";" }); } @@ -1536,3 +1537,37 @@ fn removeNullCast(x: var) -> {const InnerPtr = @typeOf(x).Child.Child; &InnerPtr const InnerPtr = @typeOf(x).Child.Child; return @ptrCast(&InnerPtr, x); } + + + +fn testCanonical(source: []const u8) { + const allocator = std.debug.global_allocator; + std.debug.global_allocator_index = 0; + + var tokenizer = Tokenizer.init(source); + var parser = Parser.init(&tokenizer, allocator, "(memory buffer)"); + defer parser.deinit(); + + const root_node = parser.parse() %% unreachable; + defer parser.freeAst(root_node); + + var buffer = std.Buffer.initSize(allocator, 0) %% unreachable; + var buffer_out_stream = io.BufferOutStream.init(&buffer); + parser.renderSource(&buffer_out_stream.stream, root_node) %% unreachable; + + if (!mem.eql(u8, buffer.toSliceConst(), source)) { + warn("\n====== expected this output: =========\n"); + warn("{}", source); + warn("\n======== instead found this: =========\n"); + warn("{}", buffer.toSliceConst()); + warn("\n======================================\n"); + @panic("test failed"); + } +} + +test "zig fmt" { + testCanonical( + \\extern fn puts(s: &const u8) -> c_int; + \\ + ); +} diff --git a/std/buffer.zig b/std/buffer.zig index 96abaeb762ce854cf21aa0d41135adf2d0cb4a55..73a38fff5bee6641c9c10e926694d4f747261a74 100644 --- a/std/buffer.zig +++ b/std/buffer.zig @@ -98,14 +98,17 @@ pub const Buffer = struct { mem.copy(u8, self.list.toSlice()[old_len..], m); } + // TODO: remove, use OutStream for this pub fn appendFormat(self: &Buffer, comptime format: []const u8, args: ...) -> %void { return fmt.format(self, append, format, args); } + // TODO: remove, use OutStream for this pub fn appendByte(self: &Buffer, byte: u8) -> %void { return self.appendByteNTimes(byte, 1); } + // TODO: remove, use OutStream for this pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) -> %void { var prev_size: usize = self.len(); %return self.resize(prev_size + count); diff --git a/std/debug.zig b/std/debug.zig index c520e98b1569473f4e08111381524618ada44691..3e7a38d04302c8155087fcca3025c848d4484c9a 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -966,28 +966,29 @@ fn readILeb128(in_stream: &io.InStream) -> %i64 { } pub const global_allocator = &global_allocator_state; + var global_allocator_state = mem.Allocator { .allocFn = globalAlloc, .reallocFn = globalRealloc, .freeFn = globalFree, }; -var some_mem: [100 * 1024]u8 = undefined; -var some_mem_index: usize = 0; +pub var global_allocator_mem: [100 * 1024]u8 = undefined; +pub var global_allocator_index: usize = 0; error OutOfMemory; fn globalAlloc(self: &mem.Allocator, n: usize, alignment: u29) -> %[]u8 { - const addr = @ptrToInt(&some_mem[some_mem_index]); + const addr = @ptrToInt(&global_allocator_mem[global_allocator_index]); const rem = @rem(addr, alignment); const march_forward_bytes = if (rem == 0) 0 else (alignment - rem); - const adjusted_index = some_mem_index + march_forward_bytes; + const adjusted_index = global_allocator_index + march_forward_bytes; const end_index = adjusted_index + n; - if (end_index > some_mem.len) { + if (end_index > global_allocator_mem.len) { return error.OutOfMemory; } - const result = some_mem[adjusted_index .. end_index]; - some_mem_index = end_index; + const result = global_allocator_mem[adjusted_index .. end_index]; + global_allocator_index = end_index; return result; } diff --git a/std/index.zig b/std/index.zig index 13ae25f9146579352a2e299143df51b391eccb56..323eee203eeb706838b4052a07970ab064c86936 100644 --- a/std/index.zig +++ b/std/index.zig @@ -3,6 +3,7 @@ pub const AlignedArrayList = @import("array_list.zig").AlignedArrayList; pub const BufMap = @import("buf_map.zig").BufMap; pub const BufSet = @import("buf_set.zig").BufSet; pub const Buffer = @import("buffer.zig").Buffer; +pub const BufferOutStream = @import("buffer.zig").BufferOutStream; pub const HashMap = @import("hash_map.zig").HashMap; pub const LinkedList = @import("linked_list.zig").LinkedList; diff --git a/std/io.zig b/std/io.zig index 87a46b05eb5c3e311a37d5b3b9b9938fd96f9215..b677e457f7f5d9cc05b8d61dfdf66d723bd04dcc 100644 --- a/std/io.zig +++ b/std/io.zig @@ -633,3 +633,24 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type { } }; } + +/// Implementation of OutStream trait for Buffer +pub const BufferOutStream = struct { + buffer: &Buffer, + stream: OutStream, + + pub fn init(buffer: &Buffer) -> BufferOutStream { + return BufferOutStream { + .buffer = buffer, + .stream = OutStream { + .writeFn = writeFn, + }, + }; + } + + fn writeFn(out_stream: &OutStream, bytes: []const u8) -> %void { + const self = @fieldParentPtr(BufferOutStream, "stream", out_stream); + return self.buffer.append(bytes); + } +}; +