vm: add getglobal support
This commit is contained in:
parent
887cb1adea
commit
005981fbbd
3 changed files with 35 additions and 3 deletions
|
@ -223,6 +223,10 @@ pub const Chunk = struct {
|
||||||
return try simpleInstruction(stdout, "OP_DEFGLOBAL", index);
|
return try simpleInstruction(stdout, "OP_DEFGLOBAL", index);
|
||||||
} else if (instruction == OpCode.DefineGlobalLong) {
|
} else if (instruction == OpCode.DefineGlobalLong) {
|
||||||
return try simpleInstruction(stdout, "OP_DEFGLOBAL_LONG", index);
|
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 {
|
} else {
|
||||||
try stdout.print("Unknown opcode: {}\n", instruction);
|
try stdout.print("Unknown opcode: {}\n", instruction);
|
||||||
return index + 1;
|
return index + 1;
|
||||||
|
|
|
@ -262,7 +262,7 @@ pub const Compiler = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn variable(self: *Compiler) !void {
|
fn variable(self: *Compiler) !void {
|
||||||
try self.namedVariable(self.parser.previous);
|
try self.namedVariable(&self.parser.previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emits bytecode for a given unary.
|
/// Emits bytecode for a given unary.
|
||||||
|
|
32
src/vm.zig
32
src/vm.zig
|
@ -230,6 +230,25 @@ pub const VM = struct {
|
||||||
_ = self.pop();
|
_ = 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 {
|
fn run(self: *VM) !void {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (self.debug_flag) {
|
if (self.debug_flag) {
|
||||||
|
@ -271,15 +290,24 @@ pub const VM = struct {
|
||||||
break :blk;
|
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
|
// extracting the name is different depending of the
|
||||||
// op code since one just uses a single byte, the other
|
// op code since one just uses a single byte, the other
|
||||||
// uses three bytes since its a u24.
|
// uses three bytes since its a u24.
|
||||||
chunk.OpCode.DefineGlobal => blk: {
|
chunk.OpCode.DefineGlobal => blk: {
|
||||||
try self.defGlobal(self.readConst().as.Object.value.String);
|
try self.defGlobal(self.readString());
|
||||||
break :blk;
|
break :blk;
|
||||||
},
|
},
|
||||||
chunk.OpCode.DefineGlobalLong => blk: {
|
chunk.OpCode.DefineGlobalLong => blk: {
|
||||||
try self.defGlobal(self.readConstLong().as.Object.value.String);
|
try self.defGlobal(self.readStringLong());
|
||||||
break :blk;
|
break :blk;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue