[rlox] Add boolean literals

This commit is contained in:
ctsk
2023-10-08 20:44:11 +02:00
parent ef7c53a55c
commit 8ace98a215
3 changed files with 36 additions and 4 deletions

View File

@@ -7,6 +7,8 @@ pub enum Op {
Return, Return,
Constant { offset: usize }, Constant { offset: usize },
Nil, Nil,
True,
False,
Negate, Negate,
Add, Add,
Subtract, Subtract,
@@ -17,6 +19,7 @@ pub enum Op {
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
pub enum Value { pub enum Value {
Nil, Nil,
Bool(bool),
Number(f64), Number(f64),
} }
@@ -134,7 +137,9 @@ impl fmt::Debug for TraceInfo<'_> {
}?; }?;
match op { match op {
Op::Return | Op::Nil | Op::Negate | Op::Add | Op::Subtract | Op::Multiply | Op::Divide => { Op::Return | Op::Nil | Op::True
| Op::False | Op::Negate | Op::Add
| Op::Subtract | Op::Multiply | Op::Divide => {
write!(f, "{:?}", op) write!(f, "{:?}", op)
} }
Op::Constant { offset } => { Op::Constant { offset } => {

View File

@@ -349,10 +349,16 @@ impl<'src> Parser<'src> {
}; };
} }
Token { Token {
ttype: TokenType::Nil, ttype: ttype@(TokenType::Nil | TokenType::True | TokenType::False),
span: _, span: _,
} => { } => {
chunk.add_op(Op::Nil, 0); let op = match ttype {
TokenType::Nil => Op::Nil,
TokenType::True => Op::True,
TokenType::False => Op::False,
_ => unreachable!()
};
chunk.add_op(op, 0);
} }
Token { Token {
ttype: TokenType::LeftParen, ttype: TokenType::LeftParen,
@@ -504,4 +510,23 @@ mod tests {
assert!(chunk.instr_eq(&expected)); assert!(chunk.instr_eq(&expected));
} }
#[test]
fn parse_bool_literals() {
let source = "true * false";
let scanner = Scanner::new(source);
let mut parser = Parser::new(scanner);
let mut chunk = Chunk::new();
parser.expression(&mut chunk);
use crate::bc::Op::*;
let expected = Chunk::new_with(
vec![True, False, Multiply],
vec![],
vec![],
);
assert!(chunk.instr_eq(&expected));
}
} }

View File

@@ -77,6 +77,8 @@ impl VM {
Op::Return => print!("{:?}", self.pop()?), Op::Return => print!("{:?}", self.pop()?),
Op::Constant { offset } => self.push(chunk.constants[offset]), Op::Constant { offset } => self.push(chunk.constants[offset]),
Op::Nil => self.push(Value::Nil), Op::Nil => self.push(Value::Nil),
Op::True => self.push(Value::Bool(true)),
Op::False => self.push(Value::Bool(false)),
Op::Negate => { Op::Negate => {
let new_val = -self.pop_num()?; let new_val = -self.pop_num()?;
self.push(new_val.into()); self.push(new_val.into());
@@ -143,7 +145,7 @@ mod tests {
} }
#[test] #[test]
fn runtime_type_error() { fn nil_error() {
let chunk = Chunk::new_with( let chunk = Chunk::new_with(
vec![Op::Nil, Op::Negate], vec![Op::Nil, Op::Negate],
vec![], vec![],