aboutsummaryrefslogtreecommitdiff
path: root/src/compile.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile.zig')
-rw-r--r--src/compile.zig49
1 files changed, 31 insertions, 18 deletions
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,
}