From 601916b828b8d94a89df6950da73ea68a20daa69 Mon Sep 17 00:00:00 2001 From: Mathias Magnusson Date: Mon, 2 Jun 2025 16:39:53 +0200 Subject: make print return integer length --- src/compile.zig | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) (limited to 'src/compile.zig') diff --git a/src/compile.zig b/src/compile.zig index 6a79efd..9513a93 100644 --- a/src/compile.zig +++ b/src/compile.zig @@ -15,6 +15,7 @@ pub const Instr = struct { constant: Constant, bin_op: BinOp, print: Print, + discard: Discard, }; pub const Constant = struct { @@ -43,6 +44,7 @@ pub const Instr = struct { }; pub const Print = struct { + dest: VReg, arg: VReg, pub fn sources(self: Print) Sources { @@ -50,6 +52,14 @@ pub const Instr = struct { } }; + pub const Discard = struct { + vreg: VReg, + + pub fn sources(self: Discard) Sources { + return Sources.fromSlice(&.{self.vreg}) catch unreachable; + } + }; + pub fn sources(self: Instr) Sources { return switch (self.type) { inline else => |instr| instr.sources(), @@ -58,8 +68,8 @@ pub const Instr = struct { pub fn dest(self: *const Instr) ?VReg { return switch (self.type) { - inline .constant, .bin_op => |s| s.dest, - inline .print => null, + inline .constant, .bin_op, .print => |s| s.dest, + // inline .x => null, }; } @@ -69,13 +79,16 @@ pub const Instr = struct { pub const Block = struct { // arguments: []Reg, instrs: []Instr, - vreg_last_use: std.AutoHashMap(VReg, usize), + vreg_last_use: std.AutoHashMap(usize, std.ArrayList(VReg)), fn init(allocator: Allocator, instrs: []Instr) !Block { - var vreg_last_use: std.AutoHashMap(VReg, usize) = .init(allocator); + var vreg_last_use: std.AutoHashMap(usize, std.ArrayList(VReg)) = .init(allocator); for (0.., instrs) |i, instr| { - for (instr.sources().slice()) |src| - try vreg_last_use.put(src, i); + for (instr.sources().slice()) |src| { + const kv = try vreg_last_use.getOrPut(i); + if (!kv.found_existing) kv.value_ptr.* = .init(allocator); + try kv.value_ptr.append(src); + } } return .{ .instrs = instrs, @@ -112,7 +125,10 @@ const CompileContext = struct { fn compileStmt(self: *Self, stmt: parse.Stmt) !void { switch (stmt.type) { - .expr => |expr| _ = try self.compileExpr(expr), + .expr => |expr| try self.addInstr(.{ + .loc = stmt.loc, + .type = .{ .discard = .{ .vreg = try self.compileExpr(expr) } }, + }), } } @@ -142,18 +158,15 @@ const CompileContext = struct { }); }, .call => |call| { - if (call.proc.type == .identifier and - std.mem.eql(u8, call.proc.loc.getIdent(self.source), "print")) - { - const arg = try self.compileExpr(call.arg); - try self.addInstr(.{ - .loc = expr.loc, - .type = .{ .print = .{ .arg = arg } }, - }); - // BUG: we're returning a bogus virtual register that we didn't write to - } else { + if (call.proc.type != .identifier or + !std.mem.eql(u8, call.proc.loc.getIdent(self.source), "print")) return error.CantCallAnythingButPrint; - } + + const arg = try self.compileExpr(call.arg); + try self.addInstr(.{ + .loc = expr.loc, + .type = .{ .print = .{ .dest = dest, .arg = arg } }, + }); }, .identifier => return error.CantCompileIdentifierExpr, } -- cgit v1.2.3