feat(tazjin/rlox): Implement equality operator
Change-Id: I5587a11646e228c5af4dc7ca6da026bb4a2592a6 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2574 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
This commit is contained in:
		
							parent
							
								
									93c30b339c
								
							
						
					
					
						commit
						c58fe2093e
					
				
					 4 changed files with 50 additions and 6 deletions
				
			
		|  | @ -120,6 +120,14 @@ fn rule_for<T: Iterator<Item = Token>>(token: &TokenKind) -> ParseRule<T> { | |||
|             ParseRule::new(Some(Compiler::unary), None, Precedence::None) | ||||
|         } | ||||
| 
 | ||||
|         TokenKind::BangEqual => { | ||||
|             ParseRule::new(None, Some(Compiler::binary), Precedence::Equality) | ||||
|         } | ||||
| 
 | ||||
|         TokenKind::EqualEqual => { | ||||
|             ParseRule::new(None, Some(Compiler::binary), Precedence::Equality) | ||||
|         } | ||||
| 
 | ||||
|         _ => ParseRule::new(None, None, Precedence::None), | ||||
|     } | ||||
| } | ||||
|  | @ -194,6 +202,14 @@ impl<T: Iterator<Item = Token>> Compiler<T> { | |||
|             TokenKind::Plus => self.emit_op(OpCode::OpAdd), | ||||
|             TokenKind::Star => self.emit_op(OpCode::OpMultiply), | ||||
|             TokenKind::Slash => self.emit_op(OpCode::OpDivide), | ||||
| 
 | ||||
|             TokenKind::BangEqual => { | ||||
|                 self.emit_op(OpCode::OpEqual); | ||||
|                 self.emit_op(OpCode::OpNot); | ||||
|             } | ||||
| 
 | ||||
|             TokenKind::EqualEqual => self.emit_op(OpCode::OpEqual), | ||||
| 
 | ||||
|             _ => unreachable!("only called for binary operator tokens"), | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,8 +11,9 @@ pub enum OpCode { | |||
|     /// Return from the current function.
 | ||||
|     OpReturn, | ||||
| 
 | ||||
|     // Boolean operators
 | ||||
|     // Boolean & comparison operators
 | ||||
|     OpNot, | ||||
|     OpEqual, | ||||
| 
 | ||||
|     /// Unary negation
 | ||||
|     OpNegate, | ||||
|  |  | |||
|  | @ -14,6 +14,10 @@ fn expect_num(code: &str, value: f64) { | |||
|     expect(code, Value::Number(value)) | ||||
| } | ||||
| 
 | ||||
| fn expect_bool(code: &str, value: bool) { | ||||
|     expect(code, Value::Bool(value)) | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn numbers() { | ||||
|     expect_num("1", 1.0); | ||||
|  | @ -61,9 +65,26 @@ fn trivial_literals() { | |||
| 
 | ||||
| #[test] | ||||
| fn negation() { | ||||
|     expect("!true", Value::Bool(false)); | ||||
|     expect("!false", Value::Bool(true)); | ||||
|     expect("!nil", Value::Bool(true)); | ||||
|     expect("!13.5", Value::Bool(false)); | ||||
|     expect("!-42", Value::Bool(false)); | ||||
|     expect_bool("!true", false); | ||||
|     expect_bool("!false", true); | ||||
|     expect_bool("!nil", true); | ||||
|     expect_bool("!13.5", false); | ||||
|     expect_bool("!-42", false); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn equality() { | ||||
|     expect_bool("42 == 42", true); | ||||
|     expect_bool("42 != 42", false); | ||||
|     expect_bool("42 == 42.0", true); | ||||
| 
 | ||||
|     expect_bool("true == true", true); | ||||
|     expect_bool("true == false", false); | ||||
|     expect_bool("true == !false", true); | ||||
|     expect_bool("true != true", false); | ||||
|     expect_bool("true != false", true); | ||||
| 
 | ||||
|     expect_bool("42 == false", false); | ||||
|     expect_bool("42 == true", false); | ||||
|     expect_bool("!42 == !true", true); | ||||
| } | ||||
|  |  | |||
|  | @ -85,6 +85,12 @@ impl VM { | |||
|                     self.push(Value::Bool(v.is_falsey())); | ||||
|                 } | ||||
| 
 | ||||
|                 OpCode::OpEqual => { | ||||
|                     let b = self.pop(); | ||||
|                     let a = self.pop(); | ||||
|                     self.push(Value::Bool(a == b)); | ||||
|                 } | ||||
| 
 | ||||
|                 OpCode::OpNegate => { | ||||
|                     let v = self.pop(); | ||||
|                     with_type!( | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue