diff --git a/rlox/src/bc.rs b/rlox/src/bc.rs index d51385b..400bec8 100644 --- a/rlox/src/bc.rs +++ b/rlox/src/bc.rs @@ -7,6 +7,8 @@ pub enum Op { Return, Constant { offset: usize }, Nil, + True, + False, Negate, Add, Subtract, @@ -17,6 +19,7 @@ pub enum Op { #[derive(Copy, Clone, Debug, PartialEq)] pub enum Value { Nil, + Bool(bool), Number(f64), } @@ -134,7 +137,9 @@ impl fmt::Debug for TraceInfo<'_> { }?; 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) } Op::Constant { offset } => { diff --git a/rlox/src/lc.rs b/rlox/src/lc.rs index cce6ad7..ab3a5fc 100644 --- a/rlox/src/lc.rs +++ b/rlox/src/lc.rs @@ -349,10 +349,16 @@ impl<'src> Parser<'src> { }; } Token { - ttype: TokenType::Nil, + ttype: ttype@(TokenType::Nil | TokenType::True | TokenType::False), 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 { ttype: TokenType::LeftParen, @@ -504,4 +510,23 @@ mod tests { 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)); + + } } diff --git a/rlox/src/vm.rs b/rlox/src/vm.rs index a8d6082..4968847 100644 --- a/rlox/src/vm.rs +++ b/rlox/src/vm.rs @@ -77,6 +77,8 @@ impl VM { Op::Return => print!("{:?}", self.pop()?), Op::Constant { offset } => self.push(chunk.constants[offset]), Op::Nil => self.push(Value::Nil), + Op::True => self.push(Value::Bool(true)), + Op::False => self.push(Value::Bool(false)), Op::Negate => { let new_val = -self.pop_num()?; self.push(new_val.into()); @@ -143,7 +145,7 @@ mod tests { } #[test] - fn runtime_type_error() { + fn nil_error() { let chunk = Chunk::new_with( vec![Op::Nil, Op::Negate], vec![],