Compare commits
3 commits
3936b4a426
...
9f45dea2c0
Author | SHA1 | Date | |
---|---|---|---|
9f45dea2c0 | |||
8bc220d2f8 | |||
922f3c530c |
3 changed files with 39 additions and 13 deletions
|
@ -134,7 +134,7 @@ pub const Chunk = struct {
|
|||
return self.constants.count - 1;
|
||||
}
|
||||
|
||||
pub fn writeConstant(
|
||||
pub fn writeConstantRaw(
|
||||
self: *Chunk,
|
||||
val: value.Value,
|
||||
line: usize,
|
||||
|
@ -143,10 +143,7 @@ pub const Chunk = struct {
|
|||
var constant_idx = self.constants.count - 1;
|
||||
|
||||
if (constant_idx < 256) {
|
||||
try self.write(OpCode.Constant, line);
|
||||
|
||||
var idx_small = @intCast(u8, constant_idx);
|
||||
try self.write(idx_small, line);
|
||||
return ConstantIndex{ .Small = idx_small };
|
||||
} else {
|
||||
var idx_u24: u24 = @intCast(u24, constant_idx);
|
||||
|
@ -157,14 +154,35 @@ pub const Chunk = struct {
|
|||
const v2: u8 = @intCast(u8, (idx_u24 >> 8) & mask);
|
||||
const v3: u8 = @intCast(u8, (idx_u24 >> 16) & mask);
|
||||
|
||||
try self.write(OpCode.ConstantLong, line);
|
||||
try self.write(v3, line);
|
||||
try self.write(v2, line);
|
||||
try self.write(v1, line);
|
||||
return ConstantIndex{ .Long = []u8{ v3, v2, v1 } };
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeConstant(
|
||||
self: *Chunk,
|
||||
val: value.Value,
|
||||
line: usize,
|
||||
) !ConstantIndex {
|
||||
var idx = try self.writeConstantRaw(val, line);
|
||||
|
||||
switch (idx) {
|
||||
.Small => |idx_small| blk: {
|
||||
try self.write(OpCode.Constant, line);
|
||||
try self.write(idx_small, line);
|
||||
break :blk;
|
||||
},
|
||||
.Long => |long_u8| blk: {
|
||||
try self.write(OpCode.ConstantLong, line);
|
||||
try self.write(long_u8[0], line);
|
||||
try self.write(long_u8[1], line);
|
||||
try self.write(long_u8[2], line);
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
pub fn disassembleInstruction(
|
||||
self: *Chunk,
|
||||
stdout: var,
|
||||
|
@ -220,13 +238,13 @@ pub const Chunk = struct {
|
|||
} else if (instruction == OpCode.Pop) {
|
||||
return try simpleInstruction(stdout, "OP_POP", index);
|
||||
} else if (instruction == OpCode.DefineGlobal) {
|
||||
return try simpleInstruction(stdout, "OP_DEFGLOBAL", index);
|
||||
return try constantInstruction(stdout, "OP_DEFGLOBAL", self, index);
|
||||
} else if (instruction == OpCode.DefineGlobalLong) {
|
||||
return try simpleInstruction(stdout, "OP_DEFGLOBAL_LONG", index);
|
||||
return try constantLongInstruction(stdout, "OP_DEFGLOBAL_LONG", self, index);
|
||||
} else if (instruction == OpCode.GetGlobal) {
|
||||
return try simpleInstruction(stdout, "OP_GETGLOBAL", index);
|
||||
return try constantInstruction(stdout, "OP_GETGLOBAL", self, index);
|
||||
} else if (instruction == OpCode.GetGlobalLong) {
|
||||
return try simpleInstruction(stdout, "OP_GETGLOBAL_LONG", index);
|
||||
return try constantLongInstruction(stdout, "OP_GETGLOBAL_LONG", self, index);
|
||||
} else {
|
||||
try stdout.print("Unknown opcode: {}\n", instruction);
|
||||
return index + 1;
|
||||
|
|
|
@ -253,7 +253,13 @@ pub const Compiler = struct {
|
|||
}
|
||||
|
||||
fn namedVariable(self: *Compiler, tok: *Token) !void {
|
||||
var idx = try self.identifierConstant(tok);
|
||||
// writeConstant always writes OP_CODE which may be not
|
||||
// what we want, so.
|
||||
var idx = try self.currentChunk().writeConstantRaw(values.ObjVal(try objects.copyString(
|
||||
self.vmach,
|
||||
tok.lexeme,
|
||||
)), tok.line);
|
||||
|
||||
try self.emitConstWithIndex(
|
||||
chunks.OpCode.GetGlobal,
|
||||
chunks.OpCode.GetGlobalLong,
|
||||
|
|
|
@ -85,6 +85,8 @@ fn runPrompt(allocator: *Allocator) !void {
|
|||
else => return err,
|
||||
}
|
||||
};
|
||||
|
||||
vmach.resetStack();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue