add support for nil, true and false literal values

This commit is contained in:
Luna 2019-06-01 23:44:59 -03:00
parent ec652b29d9
commit 1d774c6011
4 changed files with 31 additions and 3 deletions

View file

@ -13,6 +13,11 @@ const AllOpcodes = struct {
pub Multiply: u8 = 5, pub Multiply: u8 = 5,
pub Divide: u8 = 6, pub Divide: u8 = 6,
pub Negate: u8 = 7, pub Negate: u8 = 7,
// basic type op codes
pub Nil: u8 = 8,
pub True: u8 = 9,
pub False: u8 = 10,
}; };
pub const OpCode = AllOpcodes{}; pub const OpCode = AllOpcodes{};
@ -163,6 +168,12 @@ pub const Chunk = struct {
return try simpleInstruction(stdout, "OP_MULTIPLY", index); return try simpleInstruction(stdout, "OP_MULTIPLY", index);
} else if (instruction == OpCode.Divide) { } else if (instruction == OpCode.Divide) {
return try simpleInstruction(stdout, "OP_DIVIDE", index); return try simpleInstruction(stdout, "OP_DIVIDE", index);
} else if (instruction == OpCode.Nil) {
return try simpleInstruction(stdout, "OP_NIL", index);
} else if (instruction == OpCode.True) {
return try simpleInstruction(stdout, "OP_TRUE", index);
} else if (instruction == OpCode.False) {
return try simpleInstruction(stdout, "OP_FALSE", index);
} else { } else {
try stdout.print("Unknown opcode: {}\n", instruction); try stdout.print("Unknown opcode: {}\n", instruction);
return index + 1; return index + 1;

View file

@ -94,17 +94,19 @@ var rules = []ParseRule{
ParseRule{ .precedence = .And }, ParseRule{ .precedence = .And },
ParseRule{}, ParseRule{},
ParseRule{}, ParseRule{},
// false
ParseRule{ .prefix = Compiler.literal },
ParseRule{}, ParseRule{},
ParseRule{}, ParseRule{},
ParseRule{}, ParseRule{},
ParseRule{}, ParseRule{ .prefix = Compiler.literal },
ParseRule{},
ParseRule{ .precedence = .Or }, ParseRule{ .precedence = .Or },
ParseRule{}, ParseRule{},
ParseRule{}, ParseRule{},
ParseRule{}, ParseRule{},
ParseRule{}, ParseRule{},
ParseRule{}, ParseRule{ .prefix = Compiler.literal },
ParseRule{}, ParseRule{},
ParseRule{}, ParseRule{},
ParseRule{}, ParseRule{},
@ -252,6 +254,15 @@ pub const Compiler = struct {
} }
} }
fn literal(self: *Compiler) !void {
switch (self.parser.previous.ttype) {
.FALSE => try self.emitByte(OpCode.False),
.NIL => try self.emitByte(OpCode.Nil),
.TRUE => try self.emitByte(OpCode.True),
else => unreachable,
}
}
fn parsePrecedence(self: *Compiler, precedence: Precedence) !void { fn parsePrecedence(self: *Compiler, precedence: Precedence) !void {
try self.advance(); try self.advance();
var as_int = @enumToInt(precedence); var as_int = @enumToInt(precedence);

View file

@ -36,6 +36,8 @@ pub fn NumberVal(val: f64) Value {
pub fn printValue(stdout: var, value: Value) !void { pub fn printValue(stdout: var, value: Value) !void {
switch (value.as) { switch (value.as) {
.Nil => try stdout.print("nil"),
.Bool => try stdout.print("{}", value.as.Bool),
.Number => try stdout.print("{}", value.as.Number), .Number => try stdout.print("{}", value.as.Number),
else => unreachable, else => unreachable,
} }

View file

@ -162,6 +162,10 @@ pub const VM = struct {
return InterpretResult.Ok; return InterpretResult.Ok;
}, },
chunk.OpCode.Nil => try self.push(values.NilVal()),
chunk.OpCode.True => try self.push(values.BoolVal(true)),
chunk.OpCode.False => try self.push(values.BoolVal(false)),
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(),