From 2d33e03efb9d9c0c3d40929ca3745638f9d5b99f Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 1 Jun 2019 02:06:23 -0300 Subject: [PATCH] add incomplete ConstantLong instruction - move ValueList's count to usize for ConstantLong --- src/chunk.zig | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/main.zig | 4 +--- src/value.zig | 2 +- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/chunk.zig b/src/chunk.zig index cbb5317..148b42e 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -6,7 +6,8 @@ const Allocator = std.mem.Allocator; // hack. ugly hack. zig has compiler crash. const AllOpcodes = struct { pub Constant: u8 = 0, - pub Return: u8 = 1, + pub ConstantLong: u8 = 1, + pub Return: u8 = 2, }; pub const OpCode = AllOpcodes{}; @@ -36,6 +37,32 @@ fn constantInstruction( return offset + 2; } +fn constantLongInstruction( + stdout: var, + comptime name: []const u8, + chunk: *Chunk, + offset: usize, +) !usize { + // get the constant's index in constants slice + var v0: u8 = chunk.code[offset + 3]; + var v1: u8 = chunk.code[offset + 2]; + var v2: u8 = chunk.code[offset + 1]; + + // TODO: this does not work. just decreased first term + // to fix a compile error. + + // we should also move the actual printing into its own + // function too since constantInstruction and + // constantLongInstruction share code. + var idx: u24 = (v2 << 4) | (v1 << 7) | v0; + + try stdout.print("\t{}\t{} '", name, idx); + try value.printValue(stdout, chunk.constants.values[idx]); + try stdout.print("'\n"); + + return offset + 2; +} + pub const Chunk = struct { count: usize, lines: []usize, @@ -77,6 +104,24 @@ pub const Chunk = struct { return self.constants.count - 1; } + pub fn writeConstant(self: *Chunk, val: value.Value, line: usize) !void { + try self.constants.write(val); + var constant_idx = self.constants.count - 1; + + if (constant_idx < 256) { + try self.write(OpCode.Constant, line); + try self.write(@intCast(u8, constant_idx), line); + } else { + // TODO: convert the usize to u24, and from + // u24, split it into three u8's. + + // also convert from u8 back to u24. + // i know that we can do from two u8's to go to a u16 + // with (v1 << 7) | v0. + try self.write(0, line); + } + } + pub fn disassembleInstruction( self: *Chunk, stdout: var, @@ -96,6 +141,13 @@ pub const Chunk = struct { return try simpleInstruction(stdout, "OP_RETURN", index); } else if (instruction == OpCode.Constant) { return try constantInstruction(stdout, "OP_CONSTANT", self, index); + } else if (instruction == OpCode.ConstantLong) { + return try constantLongInstruction( + stdout, + "OP_CONSTANT_LONG", + self, + index, + ); } else { try stdout.print("Unknown opcode: {}\n", instruction); return index + 1; diff --git a/src/main.zig b/src/main.zig index 46801f3..9b19dd9 100644 --- a/src/main.zig +++ b/src/main.zig @@ -115,9 +115,7 @@ pub fn main() !void { //var opcode_byte: u8 = @enumToInt(chunk.OpCode.Return); //try chk.write(chunk.OpCode.Return); - var constant = try chk.addConstant(1.2); - try chk.write(chunk.OpCode.Constant, 123); - try chk.write(constant, 123); + var constant = try chk.writeConstant(1.2, 123); try chk.write(chunk.OpCode.Return, 123); try chk.disassemble(stdout, "test chunk"); diff --git a/src/value.zig b/src/value.zig index a84a79e..b97d402 100644 --- a/src/value.zig +++ b/src/value.zig @@ -10,7 +10,7 @@ pub fn printValue(stdout: var, value: Value) !void { } pub const ValueList = struct { - count: u8, + count: usize, values: []Value, allocator: *Allocator,