diff --git a/README.md b/README.md index a16555e..6b39279 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ - [x] Logical boolean operators - [x] Variables - [x] Declaration - - [ ] Assignment + - [x] Assignment - [ ] While loop `while X { ... }` - [ ] If else statement `if X { ... } else { ... }` - [ ] If Statement diff --git a/src/interpreter.rs b/src/interpreter.rs index a997b30..4ca6132 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -48,6 +48,19 @@ impl Interpreter { } fn resolve_binop(&mut self, bo: BinOpType, lhs: Expr, rhs: Expr) -> Value { + // Treat assignment separate from the other expressions + if matches!(bo, BinOpType::Assign) { + match lhs { + Expr::Ident(name) => { + let rhs = self.resolve_expr(rhs); + self.vartable.insert(name, rhs.clone()); + return rhs; + } + _ => panic!("Runtime error: Left hand side of assignment must be an identifier"), + } + } + + let lhs = self.resolve_expr(lhs); let rhs = self.resolve_expr(rhs); @@ -69,6 +82,7 @@ impl Interpreter { 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 }), + BinOpType::Assign => unreachable!(), }, // _ => panic!("Value types are not compatible"), } diff --git a/src/lexer.rs b/src/lexer.rs index 42a1429..e281f9a 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -228,6 +228,8 @@ impl Token { Token::Lt => BinOpType::Lt, Token::Le => BinOpType::Le, + Token::Assign => BinOpType::Assign, + _ => return None, }) } diff --git a/src/parser.rs b/src/parser.rs index d9fde80..87a03fe 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -52,6 +52,9 @@ pub enum BinOpType { /// Check less or equal Le, + + /// Assign to a variable + Assign, } /// Types for unary operators @@ -239,14 +242,15 @@ impl BinOpType { /// See: https://en.cppreference.com/w/c/language/operator_precedence fn precedence(&self) -> u8 { match self { - BinOpType::BOr => 0, - BinOpType::BXor => 1, - BinOpType::BAnd => 2, - BinOpType::Equ | BinOpType::Neq => 3, - 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, + BinOpType::Assign => 0, + BinOpType::BOr => 1, + BinOpType::BXor => 2, + BinOpType::BAnd => 3, + BinOpType::Equ | BinOpType::Neq => 4, + BinOpType::Gt | BinOpType::Ge | BinOpType::Lt | BinOpType::Le => 5, + BinOpType::Shl | BinOpType::Shr => 6, + BinOpType::Add | BinOpType::Sub => 7, + BinOpType::Mul | BinOpType::Div | BinOpType::Mod => 8, } } }