diff --git a/build.zig b/build.zig index 1c1d4f832e..84c3b05eda 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 705281e441..209ee829e5 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 96abaeb762..73a38fff5b 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 c520e98b15..3e7a38d043 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 13ae25f914..323eee203e 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 87a46b05eb..b677e457f7 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); + } +}; +