add emitting of GetGlobal/GetGlobalLong

This commit is contained in:
Luna 2019-06-02 23:43:12 -03:00
parent e3ac28d84e
commit 887cb1adea
2 changed files with 33 additions and 5 deletions

View file

@ -31,6 +31,8 @@ const AllOpcodes = struct {
pub DefineGlobal: u8 = 17, pub DefineGlobal: u8 = 17,
pub DefineGlobalLong: u8 = 18, pub DefineGlobalLong: u8 = 18,
pub GetGlobal: u8 = 19,
pub GetGlobalLong: u8 = 20,
}; };
pub const OpCode = AllOpcodes{}; pub const OpCode = AllOpcodes{};

View file

@ -89,7 +89,7 @@ var rules = []ParseRule{
ParseRule{ .infix = Compiler.binary, .precedence = .Comparison }, ParseRule{ .infix = Compiler.binary, .precedence = .Comparison },
ParseRule{ .infix = Compiler.binary, .precedence = .Comparison }, ParseRule{ .infix = Compiler.binary, .precedence = .Comparison },
ParseRule{}, ParseRule{ .prefix = Compiler.variable },
ParseRule{ .prefix = Compiler.string }, ParseRule{ .prefix = Compiler.string },
ParseRule{ .prefix = Compiler.number }, ParseRule{ .prefix = Compiler.number },
ParseRule{ .precedence = .And }, ParseRule{ .precedence = .And },
@ -252,6 +252,19 @@ pub const Compiler = struct {
))); )));
} }
fn namedVariable(self: *Compiler, tok: *Token) !void {
var idx = try self.identifierConstant(tok);
try self.emitConstWithIndex(
chunks.OpCode.GetGlobal,
chunks.OpCode.GetGlobalLong,
idx,
);
}
fn variable(self: *Compiler) !void {
try self.namedVariable(self.parser.previous);
}
/// Emits bytecode for a given unary. /// Emits bytecode for a given unary.
fn unary(self: *Compiler) !void { fn unary(self: *Compiler) !void {
var ttype = self.parser.previous.ttype; var ttype = self.parser.previous.ttype;
@ -368,11 +381,16 @@ pub const Compiler = struct {
return try self.identifierConstant(&self.parser.previous); return try self.identifierConstant(&self.parser.previous);
} }
fn defineVariable(self: *Compiler, global: chunks.ConstantIndex) !void { fn emitConstWithIndex(
switch (global) { self: *Compiler,
.Small => |val| try self.emitBytes(chunks.OpCode.DefineGlobal, val), op_short: u8,
op_long: u8,
idx: chunks.ConstantIndex,
) !void {
switch (idx) {
.Small => |val| try self.emitBytes(op_short, val),
.Long => |val| blk: { .Long => |val| blk: {
try self.emitByte(chunks.OpCode.DefineGlobalLong); try self.emitByte(op_long);
try self.emitByte(val[0]); try self.emitByte(val[0]);
try self.emitByte(val[1]); try self.emitByte(val[1]);
try self.emitByte(val[2]); try self.emitByte(val[2]);
@ -381,6 +399,14 @@ pub const Compiler = struct {
} }
} }
fn defineVariable(self: *Compiler, global: chunks.ConstantIndex) !void {
try self.emitConstWithIndex(
chunks.OpCode.DefineGlobal,
chunks.OpCode.DefineGlobalLong,
global,
);
}
fn varDecl(self: *Compiler) !void { fn varDecl(self: *Compiler) !void {
var global = try self.parseVariable("Expect variable name."); var global = try self.parseVariable("Expect variable name.");