Implement div & sub
This commit is contained in:
parent
ed2ae144dd
commit
0b75c30784
@ -35,6 +35,8 @@ impl Interpreter {
|
||||
(Value::I64(lhs), Value::I64(rhs)) => match bo {
|
||||
BinOpType::Add => Value::I64(lhs + rhs),
|
||||
BinOpType::Mul => Value::I64(lhs * rhs),
|
||||
BinOpType::Sub => Value::I64(lhs - rhs),
|
||||
BinOpType::Div => Value::I64(lhs / rhs),
|
||||
},
|
||||
// _ => panic!("Value types are not compatible"),
|
||||
}
|
||||
|
||||
10
src/lexer.rs
10
src/lexer.rs
@ -10,9 +10,15 @@ pub enum Token {
|
||||
/// Plus (+)
|
||||
Add,
|
||||
|
||||
/// Minus (-)
|
||||
Sub,
|
||||
|
||||
/// Asterisk (*)
|
||||
Mul,
|
||||
|
||||
/// Slash (/)
|
||||
Div,
|
||||
|
||||
/// End of file
|
||||
EoF,
|
||||
}
|
||||
@ -60,7 +66,9 @@ impl<'a> Lexer<'a> {
|
||||
}
|
||||
|
||||
'+' => tokens.push(Token::Add),
|
||||
'-' => tokens.push(Token::Sub),
|
||||
'*' => tokens.push(Token::Mul),
|
||||
'/' => tokens.push(Token::Div),
|
||||
|
||||
//TODO: Don't panic, keep calm
|
||||
_ => panic!("Lexer encountered unexpected char: '{}'", ch),
|
||||
@ -93,7 +101,9 @@ impl Token {
|
||||
pub fn try_to_binop(&self) -> Option<BinOpType> {
|
||||
Some(match self {
|
||||
Token::Add => BinOpType::Add,
|
||||
Token::Sub => BinOpType::Sub,
|
||||
Token::Mul => BinOpType::Mul,
|
||||
Token::Div => BinOpType::Div,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
@ -8,8 +8,14 @@ pub enum BinOpType {
|
||||
/// Addition
|
||||
Add,
|
||||
|
||||
/// Subtraction
|
||||
Sub,
|
||||
|
||||
/// Multiplication
|
||||
Mul,
|
||||
|
||||
/// Divide
|
||||
Div,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@ -20,6 +26,15 @@ pub enum Ast {
|
||||
BinOp(BinOpType, Box<Ast>, Box<Ast>),
|
||||
}
|
||||
|
||||
/*
|
||||
## Grammar
|
||||
### Expressions
|
||||
`expr_primary = LITERAL` \
|
||||
`expr_mul = expr_primary (("*" | "/") expr_primary)*` \
|
||||
`expr_add = expr_mul (("+" | "-") expr_mul)*` \
|
||||
`expr = expr_add` \
|
||||
*/
|
||||
|
||||
struct Parser<T: Iterator<Item = Token>> {
|
||||
tokens: Peekable<T>,
|
||||
}
|
||||
@ -40,9 +55,12 @@ impl<T: Iterator<Item = Token>> Parser<T> {
|
||||
self.parse_expr_precedence(lhs, 0)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Parse binary expressions with a precedence equal to or higher than min_prec
|
||||
fn parse_expr_precedence(&mut self, mut lhs: Ast, min_prec: u8) -> Ast {
|
||||
while let Some(binop) = &self.peek().try_to_binop() {
|
||||
// Stop if the next operator has a lower binding power
|
||||
if !(binop.precedence() >= min_prec) {
|
||||
break;
|
||||
}
|
||||
@ -97,8 +115,8 @@ impl BinOpType {
|
||||
/// For example Multiplication is stronger than addition, so Mul has higher precedence than Add.
|
||||
fn precedence(&self) -> u8 {
|
||||
match self {
|
||||
BinOpType::Add => 0,
|
||||
BinOpType::Mul => 1,
|
||||
BinOpType::Add | BinOpType::Sub => 0,
|
||||
BinOpType::Mul | BinOpType::Div => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user