diff options
| author | Isaac Freund <ifreund@ifreund.xyz> | 2021-02-16 22:06:35 +0100 |
|---|---|---|
| committer | Isaac Freund <ifreund@ifreund.xyz> | 2021-02-16 23:20:46 +0100 |
| commit | 070e548acf8b5cb22459b779ce771b42157f49f7 (patch) | |
| tree | 2f5fbceac083172b52835db49429567278ca061b /src/codegen | |
| parent | 4006a3afb31f89be28721bdcd50fa64de63d6cbb (diff) | |
| download | zig-070e548acf8b5cb22459b779ce771b42157f49f7.tar.gz zig-070e548acf8b5cb22459b779ce771b42157f49f7.zip | |
std: remove io.AutoIndentingStream
This type is not widely applicable enough to be a public part of the
public interface of the std.
The current implementation in only fully utilized by the zig fmt
implementation, which could benefit by even tighter integration as
will be demonstrated in the next commit. Therefore, move the current
io.AutoIndentingStream to lib/std/zig/render.zig.
The C backend of the self hosted compiler also use this type currently,
but it does not require anywhere near its full complexity. Therefore,
implement a greatly simplified version of this interface in
src/codegen/c.zig.
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/c.zig | 58 |
1 files changed, 56 insertions, 2 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index cb3271a57f..d8c81ad0e4 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const assert = std.debug.assert; const mem = std.mem; const log = std.log.scoped(.c); @@ -42,7 +43,7 @@ pub const Object = struct { next_arg_index: usize = 0, next_local_index: usize = 0, next_block_index: usize = 0, - indent_writer: std.io.AutoIndentingStream(std.ArrayList(u8).Writer), + indent_writer: IndentWriter(std.ArrayList(u8).Writer), fn resolveInst(o: *Object, inst: *Inst) !CValue { if (inst.value()) |_| { @@ -63,7 +64,7 @@ pub const Object = struct { return local_value; } - fn writer(o: *Object) std.io.AutoIndentingStream(std.ArrayList(u8).Writer).Writer { + fn writer(o: *Object) IndentWriter(std.ArrayList(u8).Writer).Writer { return o.indent_writer.writer(); } @@ -796,3 +797,56 @@ fn genAsm(o: *Object, as: *Inst.Assembly) !CValue { return o.dg.fail(o.dg.decl.src(), "TODO: C backend: inline asm expression result used", .{}); } + +fn IndentWriter(comptime UnderlyingWriter: type) type { + return struct { + const Self = @This(); + pub const Error = UnderlyingWriter.Error; + pub const Writer = std.io.Writer(*Self, Error, write); + + pub const indent_delta = 4; + + underlying_writer: UnderlyingWriter, + indent_count: usize = 0, + current_line_empty: bool = true, + + pub fn writer(self: *Self) Writer { + return .{ .context = self }; + } + + pub fn write(self: *Self, bytes: []const u8) Error!usize { + if (bytes.len == 0) return @as(usize, 0); + + const current_indent = self.indent_count * Self.indent_delta; + if (self.current_line_empty and current_indent > 0) { + try self.underlying_writer.writeByteNTimes(' ', current_indent); + } + self.current_line_empty = false; + + return self.writeNoIndent(bytes); + } + + pub fn insertNewline(self: *Self) Error!void { + _ = try self.writeNoIndent("\n"); + } + + pub fn pushIndent(self: *Self) void { + self.indent_count += 1; + } + + pub fn popIndent(self: *Self) void { + assert(self.indent_count != 0); + self.indent_count -= 1; + } + + fn writeNoIndent(self: *Self, bytes: []const u8) Error!usize { + if (bytes.len == 0) return @as(usize, 0); + + try self.underlying_writer.writeAll(bytes); + if (bytes[bytes.len - 1] == '\n') { + self.current_line_empty = true; + } + return bytes.len; + } + }; +} |
