From 1079eb1671a4d418900a41d8664fa8b1a0d1c6b2 Mon Sep 17 00:00:00 2001 From: Daniel M Date: Sat, 29 Jan 2022 21:26:14 +0100 Subject: [PATCH] Implement bitwise not --- README.md | 2 +- src/interpreter.rs | 1 + src/lexer.rs | 4 ++++ src/parser.rs | 10 +++++++++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ccc2d84..39f48ab 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ - [x] Bitwise AND `X&Y` - [x] Bitwise OR `X|Y` - [x] Bitwise XOR `X^Y` - - [ ] Bitwise NOT `~X` + - [x] Bitwise NOT `~X` - [x] Bitwise left shift `X<>Y` - [ ] Variables diff --git a/src/interpreter.rs b/src/interpreter.rs index 3899908..64f4498 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -33,6 +33,7 @@ impl Interpreter { match (operand, uo) { (Value::I64(val), UnOpType::Negate) => Value::I64(-val), + (Value::I64(val), UnOpType::BNot) => Value::I64(!val), // _ => panic!("Value type is not compatible with unary operation"), } } diff --git a/src/lexer.rs b/src/lexer.rs index 042ea8b..f28bf6c 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -43,6 +43,9 @@ pub enum Token { /// Shift Right (>>) Shr, + /// Tilde (~) + Tilde, + /// End of file EoF, } @@ -107,6 +110,7 @@ impl<'a> Lexer<'a> { '^' => tokens.push(Token::BXor), '(' => tokens.push(Token::LParen), ')' => tokens.push(Token::RParen), + '~' => tokens.push(Token::Tilde), //TODO: Don't panic, keep calm _ => panic!("Lexer encountered unexpected char: '{}'", ch), diff --git a/src/parser.rs b/src/parser.rs index 54debc9..11f9e96 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -40,6 +40,9 @@ pub enum BinOpType { pub enum UnOpType { /// Unary Negate Negate, + + /// Bitwise Not + BNot, } #[derive(Debug, PartialEq, Eq, Clone)] @@ -55,7 +58,7 @@ pub enum Ast { /* ## Grammar ### Expressions -expr_primary = LITERAL | "(" expr p | "-" expr_primary +expr_primary = LITERAL | "(" expr p | "-" expr_primary | "~" expr_primary expr_mul = expr_primary (("*" | "/" | "%") expr_primary)* expr_add = expr_mul (("+" | "-") expr_mul)* expr_shift = expr_add ((">>" | "<<") expr_add)* @@ -137,6 +140,11 @@ impl> Parser { Ast::UnOp(UnOpType::Negate, operand.into()) } + Token::Tilde => { + let operand = self.parse_primary(); + Ast::UnOp(UnOpType::BNot, operand.into()) + } + tok => panic!("Error parsing primary expr: Unexpected Token '{:?}'", tok), } }