From 005981fbbdffe5be773b10a17690a7938b17daa1 Mon Sep 17 00:00:00 2001 From: Luna Date: Sun, 2 Jun 2019 23:57:28 -0300 Subject: [PATCH] vm: add getglobal support --- src/chunk.zig | 4 ++++ src/compiler.zig | 2 +- src/vm.zig | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/chunk.zig b/src/chunk.zig index 1c0f58e..abc54af 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -223,6 +223,10 @@ pub const Chunk = struct { return try simpleInstruction(stdout, "OP_DEFGLOBAL", index); } else if (instruction == OpCode.DefineGlobalLong) { return try simpleInstruction(stdout, "OP_DEFGLOBAL_LONG", index); + } else if (instruction == OpCode.GetGlobal) { + return try simpleInstruction(stdout, "OP_GETGLOBAL", index); + } else if (instruction == OpCode.GetGlobalLong) { + return try simpleInstruction(stdout, "OP_GETGLOBAL_LONG", index); } else { try stdout.print("Unknown opcode: {}\n", instruction); return index + 1; diff --git a/src/compiler.zig b/src/compiler.zig index 3a8df90..de0f25a 100644 --- a/src/compiler.zig +++ b/src/compiler.zig @@ -262,7 +262,7 @@ pub const Compiler = struct { } fn variable(self: *Compiler) !void { - try self.namedVariable(self.parser.previous); + try self.namedVariable(&self.parser.previous); } /// Emits bytecode for a given unary. diff --git a/src/vm.zig b/src/vm.zig index 7482f71..646dfbe 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -230,6 +230,25 @@ pub const VM = struct { _ = self.pop(); } + fn readString(self: *VM) []u8 { + return self.readConst().as.Object.value.String; + } + + fn readStringLong(self: *VM) []u8 { + return self.readConstLong().as.Object.value.String; + } + + fn doGetGlobal(self: *VM, name: []u8) !void { + var kv_opt = self.globals.get(name); + + if (kv_opt) |kv| { + try self.push(kv.value); + } else { + self.runtimeError("Undefined variable '{}'.", name); + return InterpretResult.RuntimeError; + } + } + fn run(self: *VM) !void { while (true) { if (self.debug_flag) { @@ -271,15 +290,24 @@ pub const VM = struct { break :blk; }, + chunk.OpCode.GetGlobal => blk: { + try self.doGetGlobal(self.readString()); + break :blk; + }, + chunk.OpCode.GetGlobalLong => blk: { + try self.doGetGlobal(self.readStringLong()); + break :blk; + }, + // extracting the name is different depending of the // op code since one just uses a single byte, the other // uses three bytes since its a u24. chunk.OpCode.DefineGlobal => blk: { - try self.defGlobal(self.readConst().as.Object.value.String); + try self.defGlobal(self.readString()); break :blk; }, chunk.OpCode.DefineGlobalLong => blk: { - try self.defGlobal(self.readConstLong().as.Object.value.String); + try self.defGlobal(self.readStringLong()); break :blk; },