Implement assignment as binop
This commit is contained in:
parent
7646177030
commit
788c4a8e82
@ -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
|
||||||
|
|||||||
@ -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"),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user