finish impl for local vars

This commit is contained in:
Luna 2019-06-03 16:24:54 -03:00
parent 26d299cd23
commit d7b78e09e3
3 changed files with 39 additions and 13 deletions

View file

@ -88,6 +88,17 @@ fn constantLongInstruction(
return offset + 4;
}
fn byteInstruction(
stdout: var,
name: []const u8,
chunk: *Chunk,
index: usize,
) !usize {
var slot: u8 = chunk.code[index + 1];
try stdout.print("{} {}", name, slot);
return index + 2;
}
pub const ConstantIndexTag = enum {
Small,
Long,
@ -254,6 +265,10 @@ pub const Chunk = struct {
return try constantInstruction(stdout, "OP_SETGLOBAL", self, index);
} else if (instruction == OpCode.SetGlobalLong) {
return try constantLongInstruction(stdout, "OP_SETGLOBAL_LONG", self, index);
} else if (instruction == OpCode.GetLocal) {
return try byteInstruction(stdout, "OP_GETLOCAL", self, index);
} else if (instruction == OpCode.SetLocal) {
return try byteInstruction(stdout, "OP_GETLOCAL", self, index);
} else {
try stdout.print("Unknown opcode: {}\n", instruction);
return index + 1;

View file

@ -287,6 +287,9 @@ pub const Compiler = struct {
var idx = @intCast(usize, i);
var local = &self.locals[idx];
if (std.mem.eql(u8, name.lexeme, local.name.lexeme)) {
if (local.depth == -1) {
self.errorCurrent("Cannot read local variable in its own initializer.");
}
return i;
}
}
@ -453,7 +456,8 @@ pub const Compiler = struct {
self.localCount += 1;
var local: *Local = &self.locals[@intCast(usize, self.localCount)];
local.name = name;
local.depth = self.scopeDepth;
//local.depth = self.scopeDepth;
local.depth = -1;
}
fn declareVariable(self: *Compiler) void {
@ -502,8 +506,17 @@ pub const Compiler = struct {
}
}
fn markInitialized(self: *Compiler) void {
if (self.scopeDepth == 0) return;
var idx = @intCast(usize, self.localCount);
self.locals[idx].depth = self.scopeDepth;
}
fn defineVariable(self: *Compiler, global: chunks.ConstantIndex) !void {
if (self.scopeDepth > 0) return;
if (self.scopeDepth > 0) {
self.markInitialized();
return;
}
try self.emitConstWithIndex(
chunks.OpCode.DefineGlobal,

View file

@ -294,26 +294,24 @@ pub const VM = struct {
chunk.OpCode.Pop => blk: {
_ = self.pop();
break :blk;
},
chunk.OpCode.GetLocal => blk: {
var slot = self.readByte();
try self.push(self.stack[slot]);
},
chunk.OpCode.SetLocal => blk: {
var slot = self.readByte();
self.stack[slot] = self.peek(0);
},
chunk.OpCode.GetGlobal => blk: {
try self.doGetGlobal(self.readString());
break :blk;
},
chunk.OpCode.GetGlobalLong => blk: {
try self.doGetGlobal(self.readStringLong());
break :blk;
},
chunk.OpCode.SetGlobal => blk: {
try self.doSetGlobal(self.readString());
break :blk;
},
chunk.OpCode.SetGlobalLong => blk: {
try self.doSetGlobal(self.readStringLong());
break :blk;
},
// extracting the name is different depending of the
// op code since one just uses a single byte, the other