comparison operators, part 1
This commit is contained in:
parent
39e28f01ac
commit
15c58a2216
3 changed files with 38 additions and 7 deletions
|
@ -20,6 +20,11 @@ const AllOpcodes = struct {
|
||||||
pub False: u8 = 10,
|
pub False: u8 = 10,
|
||||||
|
|
||||||
pub Not: u8 = 11,
|
pub Not: u8 = 11,
|
||||||
|
|
||||||
|
// comparison op codes!
|
||||||
|
pub Equal: u8 = 12,
|
||||||
|
pub Greater: u8 = 13,
|
||||||
|
pub Less: u8 = 14,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const OpCode = AllOpcodes{};
|
pub const OpCode = AllOpcodes{};
|
||||||
|
|
|
@ -77,16 +77,16 @@ var rules = []ParseRule{
|
||||||
// as the token enum says, those are 1/2 char tokens.
|
// as the token enum says, those are 1/2 char tokens.
|
||||||
ParseRule{ .prefix = Compiler.unary },
|
ParseRule{ .prefix = Compiler.unary },
|
||||||
// this is specifically for the != operator
|
// this is specifically for the != operator
|
||||||
ParseRule{ .precedence = .Equality },
|
ParseRule{ .infix = Compiler.binary, .precedence = .Equality },
|
||||||
ParseRule{},
|
ParseRule{},
|
||||||
// this is specifically for the == operator
|
// this is specifically for the == operator
|
||||||
ParseRule{ .precedence = .Equality },
|
ParseRule{ .infix = Compiler.binary, .precedence = .Equality },
|
||||||
|
|
||||||
// all the comparison ones
|
// all the comparison ones
|
||||||
ParseRule{ .precedence = .Comparison },
|
ParseRule{ .infix = Compiler.binary, .precedence = .Comparison },
|
||||||
ParseRule{ .precedence = .Comparison },
|
ParseRule{ .infix = Compiler.binary, .precedence = .Comparison },
|
||||||
ParseRule{ .precedence = .Comparison },
|
ParseRule{ .infix = Compiler.binary, .precedence = .Comparison },
|
||||||
ParseRule{ .precedence = .Comparison },
|
ParseRule{ .infix = Compiler.binary, .precedence = .Comparison },
|
||||||
|
|
||||||
ParseRule{},
|
ParseRule{},
|
||||||
ParseRule{},
|
ParseRule{},
|
||||||
|
@ -190,7 +190,7 @@ pub const Compiler = struct {
|
||||||
try self.currentChunk().write(byte, self.parser.previous.line);
|
try self.currentChunk().write(byte, self.parser.previous.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emitBytes(self: *Compiler, byte1: u8, byte2: u82) !void {
|
fn emitBytes(self: *Compiler, byte1: u8, byte2: u8) !void {
|
||||||
try self.emitByte(byte1);
|
try self.emitByte(byte1);
|
||||||
try self.emitByte(byte2);
|
try self.emitByte(byte2);
|
||||||
}
|
}
|
||||||
|
@ -251,6 +251,15 @@ pub const Compiler = struct {
|
||||||
.MINUS => try self.emitByte(OpCode.Subtract),
|
.MINUS => try self.emitByte(OpCode.Subtract),
|
||||||
.STAR => try self.emitByte(OpCode.Multiply),
|
.STAR => try self.emitByte(OpCode.Multiply),
|
||||||
.SLASH => try self.emitByte(OpCode.Divide),
|
.SLASH => try self.emitByte(OpCode.Divide),
|
||||||
|
|
||||||
|
.EQUAL_EQUAL => try self.emitByte(OpCode.Equal),
|
||||||
|
.GREATER => try self.emitByte(OpCode.Greater),
|
||||||
|
.LESS => try self.emitByte(OpCode.Less),
|
||||||
|
|
||||||
|
.BANG_EQUAL => try self.emitBytes(OpCode.Equal, OpCode.Not),
|
||||||
|
.GREATER_EQUAL => try self.emitBytes(OpCode.Less, OpCode.Not),
|
||||||
|
.LESS_EQUAL => try self.emitBytes(OpCode.Greater, OpCode.Not),
|
||||||
|
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
src/vm.zig
17
src/vm.zig
|
@ -20,6 +20,16 @@ fn isFalsey(val: value.Value) bool {
|
||||||
return val.vtype == .Nil or (val.vtype == .Bool and !val.as.Bool);
|
return val.vtype == .Nil or (val.vtype == .Bool and !val.as.Bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn valuesEqual(a: value.Value, b: value.Value) bool {
|
||||||
|
if (a.vtype != b.vtype) return false;
|
||||||
|
|
||||||
|
switch (a.vtype) {
|
||||||
|
.Nil => return true,
|
||||||
|
.Bool => return a.as.Bool == b.as.Bool,
|
||||||
|
.Number => return a.as.Number == b.as.Number,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const VM = struct {
|
pub const VM = struct {
|
||||||
chk: *Chunk = undefined,
|
chk: *Chunk = undefined,
|
||||||
src: []const u8,
|
src: []const u8,
|
||||||
|
@ -170,6 +180,12 @@ pub const VM = struct {
|
||||||
chunk.OpCode.True => try self.push(values.BoolVal(true)),
|
chunk.OpCode.True => try self.push(values.BoolVal(true)),
|
||||||
chunk.OpCode.False => try self.push(values.BoolVal(false)),
|
chunk.OpCode.False => try self.push(values.BoolVal(false)),
|
||||||
|
|
||||||
|
chunk.OpCode.Equal => blk: {
|
||||||
|
var a = self.pop();
|
||||||
|
var b = self.pop();
|
||||||
|
try self.push(values.BoolVal(valuesEqual(a, b)));
|
||||||
|
},
|
||||||
|
|
||||||
chunk.OpCode.Add => try self.doAdd(),
|
chunk.OpCode.Add => try self.doAdd(),
|
||||||
chunk.OpCode.Subtract => try self.doSub(),
|
chunk.OpCode.Subtract => try self.doSub(),
|
||||||
chunk.OpCode.Multiply => try self.doMul(),
|
chunk.OpCode.Multiply => try self.doMul(),
|
||||||
|
@ -177,6 +193,7 @@ pub const VM = struct {
|
||||||
chunk.OpCode.Not => blk: {
|
chunk.OpCode.Not => blk: {
|
||||||
try self.push(values.BoolVal(isFalsey(self.pop())));
|
try self.push(values.BoolVal(isFalsey(self.pop())));
|
||||||
},
|
},
|
||||||
|
|
||||||
chunk.OpCode.Negate => blk: {
|
chunk.OpCode.Negate => blk: {
|
||||||
var val = self.peek(0);
|
var val = self.peek(0);
|
||||||
if (val.vtype != .Bool) {
|
if (val.vtype != .Bool) {
|
||||||
|
|
Loading…
Reference in a new issue