refactor: using current_chunk()
This commit is contained in:
parent
f7c10c13bb
commit
0850198784
@ -62,6 +62,10 @@ const Parser = struct {
|
||||
};
|
||||
}
|
||||
|
||||
inline fn current_chunk(self: *Parser) *Chunk {
|
||||
return self.chunk;
|
||||
}
|
||||
|
||||
fn advance(self: *Parser) void {
|
||||
self.previous = self.current;
|
||||
|
||||
@ -117,7 +121,7 @@ const Parser = struct {
|
||||
}
|
||||
|
||||
fn emit_byte(self: *Parser, byte: u8) ParsingError!void {
|
||||
self.chunk.write(byte, self.previous.?.line) catch |err| {
|
||||
self.current_chunk().write(byte, self.previous.?.line) catch |err| {
|
||||
switch (err) {
|
||||
error.OutOfMemory => return ParsingError.OutOfMemory,
|
||||
}
|
||||
@ -135,7 +139,7 @@ const Parser = struct {
|
||||
|
||||
fn end_parser(self: *Parser) !void {
|
||||
if (!self.had_error and self.vm.has_tracing()) {
|
||||
self.chunk.dissassemble("code");
|
||||
self.current_chunk().dissassemble("code");
|
||||
}
|
||||
try self.emit_return();
|
||||
}
|
||||
@ -162,7 +166,7 @@ const Parser = struct {
|
||||
}
|
||||
|
||||
fn make_constant(self: *Parser, value: Value) !u8 {
|
||||
const constant = try self.chunk.add_constant(value);
|
||||
const constant = try self.current_chunk().add_constant(value);
|
||||
if (constant > constants.UINT8_MAX) {
|
||||
self.error_msg("Too many constants in one chunk.");
|
||||
return 0;
|
||||
@ -585,11 +589,11 @@ const Parser = struct {
|
||||
try self.emit_byte(0xff);
|
||||
try self.emit_byte(0xff);
|
||||
|
||||
return self.chunk.count - 2;
|
||||
return self.current_chunk().count - 2;
|
||||
}
|
||||
|
||||
fn patch_jump(self: *Parser, offset: usize) void {
|
||||
const jump = self.chunk.count - offset - 2;
|
||||
const jump = self.current_chunk().count - offset - 2;
|
||||
|
||||
if (jump > constants.UINT16_MAX) {
|
||||
self.error_msg("Too much code to jump over.");
|
||||
@ -598,8 +602,8 @@ const Parser = struct {
|
||||
const b1 = (jump >> 8) & 0xff;
|
||||
const b0 = jump & 0xff;
|
||||
|
||||
self.chunk.code[offset] = @intCast(b1);
|
||||
self.chunk.code[offset + 1] = @intCast(b0);
|
||||
self.current_chunk().code[offset] = @intCast(b1);
|
||||
self.current_chunk().code[offset + 1] = @intCast(b0);
|
||||
}
|
||||
|
||||
fn and_(self: *Parser, can_assign: bool) ParsingError!void {
|
||||
@ -624,7 +628,7 @@ const Parser = struct {
|
||||
}
|
||||
|
||||
fn while_statement(self: *Parser) ParsingError!void {
|
||||
const loop_start = self.chunk.count;
|
||||
const loop_start = self.current_chunk().count;
|
||||
self.consume(TokenType.LEFT_PAREN, "Expect '(' after 'while'.");
|
||||
try self.expression();
|
||||
self.consume(TokenType.RIGHT_PAREN, "Expect ')' after condition.");
|
||||
@ -640,7 +644,7 @@ const Parser = struct {
|
||||
fn emit_loop(self: *Parser, loop_start: usize) ParsingError!void {
|
||||
try self.emit_byte(@intFromEnum(OpCode.OP_LOOP));
|
||||
|
||||
const offset = self.chunk.count - loop_start + 2;
|
||||
const offset = self.current_chunk().count - loop_start + 2;
|
||||
if (offset > constants.UINT16_MAX) {
|
||||
self.error_msg("Loop body too large.");
|
||||
}
|
||||
@ -661,7 +665,7 @@ const Parser = struct {
|
||||
try self.expression_statement();
|
||||
}
|
||||
|
||||
var loop_start = self.chunk.count;
|
||||
var loop_start = self.current_chunk().count;
|
||||
|
||||
var exit_jump: ?usize = null;
|
||||
|
||||
@ -676,7 +680,7 @@ const Parser = struct {
|
||||
|
||||
if (!self.match(TokenType.RIGHT_PAREN)) {
|
||||
const body_jump = try self.emit_jump(@intFromEnum(OpCode.OP_JUMP));
|
||||
const increment_start = self.chunk.count;
|
||||
const increment_start = self.current_chunk().count;
|
||||
try self.expression();
|
||||
try self.emit_byte(@intFromEnum(OpCode.OP_POP));
|
||||
self.consume(TokenType.RIGHT_PAREN, "Expect ')' after for clauses.");
|
||||
|
@ -2,10 +2,13 @@ const std = @import("std");
|
||||
const debug = std.debug;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const Chunk = @import("./chunk.zig").Chunk;
|
||||
|
||||
const compute_hash = @import("./utils.zig").compute_hash;
|
||||
|
||||
pub const ObjType = enum {
|
||||
String,
|
||||
Function,
|
||||
};
|
||||
|
||||
pub const Obj = struct {
|
||||
@ -13,8 +16,8 @@ pub const Obj = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
pub const String = struct {
|
||||
chars: []const u8,
|
||||
obj: Obj,
|
||||
chars: []const u8,
|
||||
hash: u32,
|
||||
|
||||
pub fn new(allocator: std.mem.Allocator, chars: []const u8) *String {
|
||||
@ -39,6 +42,33 @@ pub const Obj = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const Function = struct {
|
||||
obj: Obj,
|
||||
arity: usize,
|
||||
chunk: *Chunk,
|
||||
name: *Obj.String,
|
||||
|
||||
pub fn new(allocator: std.mem.Allocator) *Function {
|
||||
const obj = Obj{
|
||||
.kind = ObjType.Function,
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
const function_obj = allocator.create(Function) catch unreachable;
|
||||
function_obj.obj = obj;
|
||||
function_obj.arity = 0;
|
||||
function_obj.chunk = Chunk.new(allocator);
|
||||
|
||||
return function_obj;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Function) void {
|
||||
const allocator = self.obj.allocator;
|
||||
self.chunk.deinit();
|
||||
allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub fn is_type(self: *Obj, kind: ObjType) bool {
|
||||
return self.kind == kind;
|
||||
}
|
||||
@ -47,12 +77,20 @@ pub const Obj = struct {
|
||||
return self.is_type(ObjType.String);
|
||||
}
|
||||
|
||||
pub fn is_function(self: *Obj) bool {
|
||||
return self.is_function(ObjType.Function);
|
||||
}
|
||||
|
||||
pub fn print(self: *Obj) void {
|
||||
switch (self.kind) {
|
||||
ObjType.String => {
|
||||
const obj = self.as_string();
|
||||
debug.print("{s}", .{obj.chars});
|
||||
},
|
||||
ObjType.Function => {
|
||||
const obj = self.as_function();
|
||||
debug.print("<fn {s}>", .{obj.name.chars});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,6 +100,10 @@ pub const Obj = struct {
|
||||
const obj: *String = @fieldParentPtr("obj", self);
|
||||
obj.destroy();
|
||||
},
|
||||
ObjType.Function => {
|
||||
const obj: *Function = @fieldParentPtr("obj", self);
|
||||
obj.destroy();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,4 +111,9 @@ pub const Obj = struct {
|
||||
std.debug.assert(self.kind == ObjType.String);
|
||||
return @fieldParentPtr("obj", self);
|
||||
}
|
||||
|
||||
pub fn as_function(self: *Obj) *Function {
|
||||
std.debug.assert(self.kind == ObjType.Function);
|
||||
return @fieldParentPtr("obj", self);
|
||||
}
|
||||
};
|
||||
|
16
src/vm.zig
16
src/vm.zig
@ -61,6 +61,10 @@ pub const VM = struct {
|
||||
self.references.deinit();
|
||||
}
|
||||
|
||||
inline fn current_chunk(self: *VM) *Chunk {
|
||||
return self.chunk.?;
|
||||
}
|
||||
|
||||
pub fn set_trace(self: *VM, tracing: bool) void {
|
||||
self.tracing = tracing;
|
||||
}
|
||||
@ -96,7 +100,7 @@ pub const VM = struct {
|
||||
}
|
||||
debug.print("\n", .{});
|
||||
}
|
||||
_ = self.chunk.?.dissassemble_instruction(self.ip.?);
|
||||
_ = self.current_chunk().dissassemble_instruction(self.ip.?);
|
||||
}
|
||||
|
||||
const instruction = self.read_byte();
|
||||
@ -209,7 +213,7 @@ pub const VM = struct {
|
||||
// XXX In the book, we're using a ptr to data directly, to avoid dereferencing to a given offset
|
||||
// How to do that in Zig?
|
||||
pub fn read_byte(self: *VM) u8 {
|
||||
const ret = self.chunk.?.code[self.ip.?];
|
||||
const ret = self.current_chunk().code[self.ip.?];
|
||||
self.ip.? += 1;
|
||||
|
||||
return ret;
|
||||
@ -218,11 +222,11 @@ pub const VM = struct {
|
||||
pub fn read_short(self: *VM) u16 {
|
||||
self.ip.? += 2;
|
||||
|
||||
return (@as(u16, self.chunk.?.code[self.ip.? - 2]) << 8) | (@as(u16, self.chunk.?.code[self.ip.? - 1]));
|
||||
return (@as(u16, self.current_chunk().code[self.ip.? - 2]) << 8) | (@as(u16, self.current_chunk().code[self.ip.? - 1]));
|
||||
}
|
||||
|
||||
pub fn read_constant(self: *VM) Value {
|
||||
return self.chunk.?.constants.values[read_byte(self)];
|
||||
return self.current_chunk().constants.values[read_byte(self)];
|
||||
}
|
||||
|
||||
pub fn push(self: *VM, value: Value) !void {
|
||||
@ -269,7 +273,7 @@ pub const VM = struct {
|
||||
const b = self.pop().as_cstring();
|
||||
const a = self.pop().as_cstring();
|
||||
|
||||
const concat_str = try std.mem.concat(self.chunk.?.allocator, u8, &.{ a, b });
|
||||
const concat_str = try std.mem.concat(self.current_chunk().allocator, u8, &.{ a, b });
|
||||
|
||||
var string_obj = self.take_string(concat_str);
|
||||
|
||||
@ -284,7 +288,7 @@ pub const VM = struct {
|
||||
|
||||
pub fn runtime_error(self: *VM, err_msg: []const u8) void {
|
||||
const instruction = self.ip.?;
|
||||
const line = self.chunk.?.lines[instruction];
|
||||
const line = self.current_chunk().lines[instruction];
|
||||
|
||||
debug.print("err: {s}\n", .{err_msg});
|
||||
debug.print("[line {d}] in script\n", .{line});
|
||||
|
Loading…
Reference in New Issue
Block a user