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