From 4d5188d9d659af16add24e6371c51ecffee938ae Mon Sep 17 00:00:00 2001 From: Daniel M Date: Fri, 28 Jan 2022 15:07:28 +0100 Subject: [PATCH] Implement relational binops - Gt: Greater than - Ge: Greater or equal - Lt: Less than - Le: Less or equal --- README.md | 2 +- src/interpreter.rs | 4 ++++ src/lexer.rs | 30 ++++++++++++++++++++++++++++-- src/parser.rs | 19 ++++++++++++++++--- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6be08cb..2638c73 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ - [x] Unary operators - [x] Negate `-X` - [x] Parentheses `(X+Y)*Z` - - [ ] Logical boolean operators + - [x] Logical boolean operators - [ ] Variables - [ ] Declaration - [ ] Assignment diff --git a/src/interpreter.rs b/src/interpreter.rs index 89ed5f2..8fa69f8 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -46,6 +46,10 @@ impl Interpreter { BinOpType::Shl => Value::I64(lhs << rhs), BinOpType::Equ => Value::I64(if lhs == rhs { 1 } else { 0 }), BinOpType::Neq => Value::I64(if lhs != rhs { 1 } else { 0 }), + BinOpType::Gt => Value::I64(if lhs > rhs { 1 } else { 0 }), + BinOpType::Ge => Value::I64(if lhs >= rhs { 1 } else { 0 }), + BinOpType::Lt => Value::I64(if lhs < rhs { 1 } else { 0 }), + BinOpType::Le => Value::I64(if lhs <= rhs { 1 } else { 0 }), }, // _ => panic!("Value types are not compatible"), } diff --git a/src/lexer.rs b/src/lexer.rs index 22afe1b..0a35530 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -49,6 +49,18 @@ pub enum Token { /// Not Equal sign (!=) Neq, + /// Greater than (>) + Gt, + + /// Greater or equal (>=) + Ge, + + /// Less than (<) + Lt, + + /// Less or equal (<=) + Le, + /// End of file EoF, } @@ -111,6 +123,14 @@ impl<'a> Lexer<'a> { self.next(); tokens.push(Token::Neq); } + '<' if matches!(self.peek(), Some('=')) => { + self.next(); + tokens.push(Token::Le); + } + '>' if matches!(self.peek(), Some('=')) => { + self.next(); + tokens.push(Token::Ge); + } '+' => tokens.push(Token::Add), '-' => tokens.push(Token::Sub), @@ -122,6 +142,8 @@ impl<'a> Lexer<'a> { '^' => tokens.push(Token::BXor), '(' => tokens.push(Token::LParen), ')' => tokens.push(Token::RParen), + '<' => tokens.push(Token::Lt), + '>' => tokens.push(Token::Gt), 'a'..='z' | 'A'..='Z' | '_' => { let mut ident = String::from(ch); @@ -137,7 +159,6 @@ impl<'a> Lexer<'a> { "false" => tokens.push(Token::I64(0)), _ => panic!("Lexer encountered unknown ident: '{}'", ident), } - } //TODO: Don't panic, keep calm @@ -186,7 +207,12 @@ impl Token { Token::Equ => BinOpType::Equ, Token::Neq => BinOpType::Neq, - + + Token::Gt => BinOpType::Gt, + Token::Ge => BinOpType::Ge, + Token::Lt => BinOpType::Lt, + Token::Le => BinOpType::Le, + _ => return None, }) } diff --git a/src/parser.rs b/src/parser.rs index 5748da1..81b854f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -40,6 +40,18 @@ pub enum BinOpType { /// Check unequality Neq, + + /// Check greater than + Gt, + + /// Check greater or equal + Ge, + + /// Check less than + Lt, + + /// Check less or equal + Le, } /// Types for unary operators @@ -173,9 +185,10 @@ impl BinOpType { BinOpType::BXor => 1, BinOpType::BAnd => 2, BinOpType::Equ | BinOpType::Neq => 3, - BinOpType::Shl | BinOpType::Shr => 4, - BinOpType::Add | BinOpType::Sub => 5, - BinOpType::Mul | BinOpType::Div | BinOpType::Mod => 6, + BinOpType::Gt | BinOpType::Ge | BinOpType::Lt | BinOpType::Le => 4, + BinOpType::Shl | BinOpType::Shr => 5, + BinOpType::Add | BinOpType::Sub => 6, + BinOpType::Mul | BinOpType::Div | BinOpType::Mod => 7, } } }