Implement logical not

This commit is contained in:
Daniel M 2022-02-02 19:14:11 +01:00
parent 3c0e5f6b4d
commit 2946e67349
6 changed files with 18 additions and 2 deletions

View File

@ -57,6 +57,7 @@ Supported mathematical operations:
The logical operators evaluate the operands as `false` if they are equal to `0` and `true` if they are not equal to `0` The logical operators evaluate the operands as `false` if they are equal to `0` and `true` if they are not equal to `0`
- And `a && b` - And `a && b`
- Or `a || b` - Or `a || b`
- Not `!a`
### Equality & Relational Operators ### Equality & Relational Operators
The equality and relational operations result in `1` if the condition is evaluated as `true` and in `0` if the condition is evaluated as `false`. The equality and relational operations result in `1` if the condition is evaluated as `true` and in `0` if the condition is evaluated as `false`.
@ -148,8 +149,7 @@ Line comments can be initiated by using `//`
- [x] Subtraction `a - b` - [x] Subtraction `a - b`
- [x] Multiplication `a * b` - [x] Multiplication `a * b`
- [x] Division `a / b` - [x] Division `a / b`
- [x] Modulo `a % b` - [x] Modulo `a % b
- [x] Unary operators
- [x] Negate `-a` - [x] Negate `-a`
- [x] Parentheses `(a + b) * c` - [x] Parentheses `(a + b) * c`
- [x] Logical boolean operators - [x] Logical boolean operators
@ -162,6 +162,7 @@ Line comments can be initiated by using `//`
- [x] Logical operators - [x] Logical operators
- [x] And `a && b` - [x] And `a && b`
- [x] Or `a || b` - [x] Or `a || b`
- [x] Not `!a`
- [x] Bitwise operators - [x] Bitwise operators
- [x] Bitwise AND `a & b` - [x] Bitwise AND `a & b`
- [x] Bitwise OR `a | b` - [x] Bitwise OR `a | b`

View File

@ -69,6 +69,9 @@ pub enum UnOpType {
/// Bitwise Not /// Bitwise Not
BNot, BNot,
/// Logical Not
LNot,
} }
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]

View File

@ -94,6 +94,7 @@ impl Interpreter {
match (operand, uo) { match (operand, uo) {
(Value::I64(val), UnOpType::Negate) => Value::I64(-val), (Value::I64(val), UnOpType::Negate) => Value::I64(-val),
(Value::I64(val), UnOpType::BNot) => Value::I64(!val), (Value::I64(val), UnOpType::BNot) => Value::I64(!val),
(Value::I64(val), UnOpType::LNot) => Value::I64(if val == 0 { 1 } else { 0 }),
// _ => panic!("Value type is not compatible with unary operation"), // _ => panic!("Value type is not compatible with unary operation"),
} }
} }

View File

@ -80,6 +80,7 @@ impl<'a> Lexer<'a> {
'=' => tokens.push(Token::Equ), '=' => tokens.push(Token::Equ),
'{' => tokens.push(Token::LBraces), '{' => tokens.push(Token::LBraces),
'}' => tokens.push(Token::RBraces), '}' => tokens.push(Token::RBraces),
'!' => tokens.push(Token::LNot),
// Lex numbers // Lex numbers
ch @ '0'..='9' => { ch @ '0'..='9' => {

View File

@ -202,10 +202,17 @@ impl<T: Iterator<Item = Token>> Parser<T> {
Expression::UnOp(UnOpType::Negate, operand.into()) Expression::UnOp(UnOpType::Negate, operand.into())
} }
// Unary bitwise not (bitflip)
Token::Tilde => { Token::Tilde => {
let operand = self.parse_primary(); let operand = self.parse_primary();
Expression::UnOp(UnOpType::BNot, operand.into()) Expression::UnOp(UnOpType::BNot, operand.into())
} }
// Unary logical not
Token::LNot => {
let operand = self.parse_primary();
Expression::UnOp(UnOpType::LNot, operand.into())
}
tok => panic!("Error parsing primary expr: Unexpected Token '{:?}'", tok), tok => panic!("Error parsing primary expr: Unexpected Token '{:?}'", tok),
} }

View File

@ -77,6 +77,9 @@ pub enum Token {
/// Tilde (~) /// Tilde (~)
Tilde, Tilde,
/// Logical not (!)
LNot,
/// Left angle bracket (<) /// Left angle bracket (<)
LAngle, LAngle,