From ba78b39300821d0367aa6abdc0b4b86226231bfe Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 1 Jun 2019 01:46:01 -0300 Subject: [PATCH] add constant values to the virtual machine --- src/chunk.zig | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- src/main.zig | 7 ++++++- src/value.zig | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 src/value.zig diff --git a/src/chunk.zig b/src/chunk.zig index 5553975..cbb5317 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -1,10 +1,12 @@ const std = @import("std"); +const value = @import("value.zig"); const Allocator = std.mem.Allocator; // hack. ugly hack. zig has compiler crash. const AllOpcodes = struct { - pub Return: u8 = 0, + pub Constant: u8 = 0, + pub Return: u8 = 1, }; pub const OpCode = AllOpcodes{}; @@ -18,31 +20,63 @@ fn simpleInstruction( return offset + 1; } +fn constantInstruction( + stdout: var, + comptime name: []const u8, + chunk: *Chunk, + offset: usize, +) !usize { + // get the constant's index in constants slice + var idx = chunk.code[offset + 1]; + + 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, code: []u8, + allocator: *Allocator, + constants: value.ValueList, pub fn init(allocator: *Allocator) !Chunk { return Chunk{ .count = 0, .allocator = allocator, .code = try allocator.alloc(u8, 0), + .lines = try allocator.alloc(usize, 0), + .constants = try value.ValueList.init(allocator), }; } - pub fn write(self: *Chunk, byte: u8) !void { + pub fn write(self: *Chunk, byte: u8, line: usize) !void { if (self.code.len < self.count + 1) { self.code = try self.allocator.realloc( self.code, self.count + 1, ); + + self.lines = try self.allocator.realloc( + self.lines, + self.count + 1, + ); } self.code[self.count] = byte; + self.lines[self.count] = line; self.count += 1; } + pub fn addConstant(self: *Chunk, val: value.Value) !u8 { + try self.constants.write(val); + return self.constants.count - 1; + } + pub fn disassembleInstruction( self: *Chunk, stdout: var, @@ -50,10 +84,18 @@ pub const Chunk = struct { ) !usize { try stdout.print("{} ", index); + if (index > 0 and self.lines[index] == self.lines[index - 1]) { + try stdout.print(" | "); + } else { + try stdout.print("{} ", self.lines[index]); + } + var instruction = self.code[index]; - if (instruction == 0) { + if (instruction == OpCode.Return) { return try simpleInstruction(stdout, "OP_RETURN", index); + } else if (instruction == OpCode.Constant) { + return try constantInstruction(stdout, "OP_CONSTANT", self, index); } else { try stdout.print("Unknown opcode: {}\n", instruction); return index + 1; @@ -64,7 +106,7 @@ pub const Chunk = struct { try stdout.print("== {} ==\n", name); var i: usize = 0; - while (i < self.count) : (i += 1) { + while (i < self.count) { i = try self.disassembleInstruction(stdout, i); } } diff --git a/src/main.zig b/src/main.zig index c895b02..46801f3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -113,7 +113,12 @@ pub fn main() !void { // this crashes zig??? lol //var opcode_byte: u8 = @enumToInt(chunk.OpCode.Return); - try chk.write(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); + try chk.write(chunk.OpCode.Return, 123); try chk.disassemble(stdout, "test chunk"); } diff --git a/src/value.zig b/src/value.zig new file mode 100644 index 0000000..a84a79e --- /dev/null +++ b/src/value.zig @@ -0,0 +1,36 @@ +const std = @import("std"); + +const Allocator = std.mem.Allocator; + +// NOTE: right now, only numbers. +pub const Value = f64; + +pub fn printValue(stdout: var, value: Value) !void { + try stdout.print("{}", value); +} + +pub const ValueList = struct { + count: u8, + values: []Value, + allocator: *Allocator, + + pub fn init(allocator: *Allocator) !ValueList { + return ValueList{ + .count = 0, + .allocator = allocator, + .values = try allocator.alloc(Value, 0), + }; + } + + pub fn write(self: *ValueList, value: Value) !void { + if (self.values.len < self.count + 1) { + self.values = try self.allocator.realloc( + self.values, + self.count + 1, + ); + } + + self.values[self.count] = value; + self.count += 1; + } +};