Implement assignment as binop

This commit is contained in:
Daniel M 2022-01-28 18:56:16 +01:00
parent 7646177030
commit 788c4a8e82
4 changed files with 29 additions and 9 deletions

View File

@ -16,7 +16,7 @@
- [x] Logical boolean operators - [x] Logical boolean operators
- [x] Variables - [x] Variables
- [x] Declaration - [x] Declaration
- [ ] Assignment - [x] Assignment
- [ ] While loop `while X { ... }` - [ ] While loop `while X { ... }`
- [ ] If else statement `if X { ... } else { ... }` - [ ] If else statement `if X { ... } else { ... }`
- [ ] If Statement - [ ] If Statement

View File

@ -48,6 +48,19 @@ impl Interpreter {
} }
fn resolve_binop(&mut self, bo: BinOpType, lhs: Expr, rhs: Expr) -> Value { 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 lhs = self.resolve_expr(lhs);
let rhs = self.resolve_expr(rhs); let rhs = self.resolve_expr(rhs);
@ -69,6 +82,7 @@ impl Interpreter {
BinOpType::Ge => 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::Lt => Value::I64(if lhs < rhs { 1 } else { 0 }),
BinOpType::Le => 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"), // _ => panic!("Value types are not compatible"),
} }

View File

@ -228,6 +228,8 @@ impl Token {
Token::Lt => BinOpType::Lt, Token::Lt => BinOpType::Lt,
Token::Le => BinOpType::Le, Token::Le => BinOpType::Le,
Token::Assign => BinOpType::Assign,
_ => return None, _ => return None,
}) })
} }

View File

@ -52,6 +52,9 @@ pub enum BinOpType {
/// Check less or equal /// Check less or equal
Le, Le,
/// Assign to a variable
Assign,
} }
/// Types for unary operators /// Types for unary operators
@ -239,14 +242,15 @@ impl BinOpType {
/// See: https://en.cppreference.com/w/c/language/operator_precedence /// See: https://en.cppreference.com/w/c/language/operator_precedence
fn precedence(&self) -> u8 { fn precedence(&self) -> u8 {
match self { match self {
BinOpType::BOr => 0, BinOpType::Assign => 0,
BinOpType::BXor => 1, BinOpType::BOr => 1,
BinOpType::BAnd => 2, BinOpType::BXor => 2,
BinOpType::Equ | BinOpType::Neq => 3, BinOpType::BAnd => 3,
BinOpType::Gt | BinOpType::Ge | BinOpType::Lt | BinOpType::Le => 4, BinOpType::Equ | BinOpType::Neq => 4,
BinOpType::Shl | BinOpType::Shr => 5, BinOpType::Gt | BinOpType::Ge | BinOpType::Lt | BinOpType::Le => 5,
BinOpType::Add | BinOpType::Sub => 6, BinOpType::Shl | BinOpType::Shr => 6,
BinOpType::Mul | BinOpType::Div | BinOpType::Mod => 7, BinOpType::Add | BinOpType::Sub => 7,
BinOpType::Mul | BinOpType::Div | BinOpType::Mod => 8,
} }
} }
} }