Refactor expr parsing functions

This commit is contained in:
Daniel M 2021-12-29 14:54:25 +01:00
parent 12e95ed822
commit 40ea6c1f8e

View File

@ -166,22 +166,17 @@ impl Parser {
} }
pub fn parse_expr_or(&mut self) -> PRes<Expr> { pub fn parse_expr_or(&mut self) -> PRes<Expr> {
// Parse the left hand side / the main expression if there is nothing on the right
let mut lhs = self.parse_expr_xor()?; let mut lhs = self.parse_expr_xor()?;
// Parse 0 or more expressions to the right side of the or operators while let Some(Token::Op(optok)) = self.curr() {
while matches!(self.curr(), Some(Token::Op(Op::Or))) { let op_type = match optok {
// We successfully matched curr against Some already in the while condition, so unwrap Op::Or => BinOpType::Or,
// is fine _ => break
let tok_op = self.advance().unwrap().clone(); };
self.advance();
let rhs = self.parse_expr_xor()?; let rhs = self.parse_expr_xor()?;
let op_type = match tok_op {
Token::Op(Op::Or) => BinOpType::Or,
_ => unreachable!(),
};
lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); lhs = Expr::BinOp(op_type, lhs.into(), rhs.into());
} }
@ -193,18 +188,15 @@ impl Parser {
let mut lhs = self.parse_expr_and()?; let mut lhs = self.parse_expr_and()?;
// Parse 0 or more expressions to the right side of the xor operators // Parse 0 or more expressions to the right side of the xor operators
while matches!(self.curr(), Some(Token::Op(Op::Xor))) { while let Some(Token::Op(optok)) = self.curr() {
// We successfully matched curr against Some already in the while condition, so unwrap let op_type = match optok {
// is fine Op::Xor => BinOpType::Xor,
let tok_op = self.advance().unwrap().clone(); _ => break
};
self.advance();
let rhs = self.parse_expr_and()?; let rhs = self.parse_expr_and()?;
let op_type = match tok_op {
Token::Op(Op::Xor) => BinOpType::Xor,
_ => unreachable!(),
};
lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); lhs = Expr::BinOp(op_type, lhs.into(), rhs.into());
} }
@ -216,18 +208,15 @@ impl Parser {
let mut lhs = self.parse_expr_equal()?; let mut lhs = self.parse_expr_equal()?;
// Parse 0 or more expressions to the right side of the and operators // Parse 0 or more expressions to the right side of the and operators
while matches!(self.curr(), Some(Token::Op(Op::And))) { while let Some(Token::Op(optok)) = self.curr() {
// We successfully matched curr against Some already in the while condition, so unwrap let op_type = match optok {
// is fine Op::And => BinOpType::And,
let tok_op = self.advance().unwrap().clone(); _ => break
};
self.advance();
let rhs = self.parse_expr_equal()?; let rhs = self.parse_expr_equal()?;
let op_type = match tok_op {
Token::Op(Op::And) => BinOpType::And,
_ => unreachable!(),
};
lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); lhs = Expr::BinOp(op_type, lhs.into(), rhs.into());
} }
@ -235,23 +224,18 @@ impl Parser {
} }
pub fn parse_expr_equal(&mut self) -> PRes<Expr> { pub fn parse_expr_equal(&mut self) -> PRes<Expr> {
// Parse the left hand side / the main expression if there is nothing on the right
let mut lhs = self.parse_expr_rel()?; let mut lhs = self.parse_expr_rel()?;
// Parse 0 or more expressions to the right side of the equality operators while let Some(Token::Op(optok)) = self.curr() {
while matches!(self.curr(), Some(Token::Op(Op::Eq | Op::Neq))) { let op_type = match optok {
// We successfully matched curr against Some already in the while condition, so unwrap Op::Eq => BinOpType::Eq,
// is fine Op::Neq => BinOpType::Neq,
let tok_op = self.advance().unwrap().clone(); _ => break
};
self.advance();
let rhs = self.parse_expr_rel()?; let rhs = self.parse_expr_rel()?;
let op_type = match tok_op {
Token::Op(Op::Eq) => BinOpType::Eq,
Token::Op(Op::Neq) => BinOpType::Neq,
_ => unreachable!(),
};
lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); lhs = Expr::BinOp(op_type, lhs.into(), rhs.into());
} }
@ -263,21 +247,18 @@ impl Parser {
let mut lhs = self.parse_expr_add()?; let mut lhs = self.parse_expr_add()?;
// Parse 0 or more expressions to the right side of the relational operators // Parse 0 or more expressions to the right side of the relational operators
while matches!(self.curr(), Some(Token::Op(Op::Gt | Op::Lt | Op::Ge | Op::Le))) { while let Some(Token::Op(optok)) = self.curr() {
// We successfully matched curr against Some already in the while condition, so unwrap let op_type = match optok {
// is fine Op::Gt => BinOpType::Gt,
let tok_op = self.advance().unwrap().clone(); Op::Lt => BinOpType::Lt,
Op::Ge => BinOpType::Ge,
Op::Le => BinOpType::Le,
_ => break
};
self.advance();
let rhs = self.parse_expr_add()?; let rhs = self.parse_expr_add()?;
let op_type = match tok_op {
Token::Op(Op::Gt) => BinOpType::Gt,
Token::Op(Op::Lt) => BinOpType::Lt,
Token::Op(Op::Ge) => BinOpType::Ge,
Token::Op(Op::Le) => BinOpType::Le,
_ => unreachable!(),
};
lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); lhs = Expr::BinOp(op_type, lhs.into(), rhs.into());
} }
@ -298,19 +279,16 @@ impl Parser {
let mut lhs = self.parse_expr_mul()?; let mut lhs = self.parse_expr_mul()?;
// Parse 0 or more expressions to the right side of the add operators // Parse 0 or more expressions to the right side of the add operators
while matches!(self.curr(), Some(Token::Op(Op::Add | Op::Sub))) { while let Some(Token::Op(optok)) = self.curr() {
// We successfully matched curr against Some already in the while condition, so unwrap let op_type = match optok {
// is fine Op::Add => BinOpType::Add,
let tok_op = self.advance().unwrap().clone(); Op::Sub => BinOpType::Sub,
_ => break
};
self.advance();
let rhs = self.parse_expr_mul()?; let rhs = self.parse_expr_mul()?;
let op_type = match tok_op {
Token::Op(Op::Add) => BinOpType::Add,
Token::Op(Op::Sub) => BinOpType::Sub,
_ => unreachable!(),
};
lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); lhs = Expr::BinOp(op_type, lhs.into(), rhs.into());
} }
@ -327,21 +305,18 @@ impl Parser {
// Parse the left hand side / the main expression if there is nothing on the right // Parse the left hand side / the main expression if there is nothing on the right
let mut lhs = self.parse_expr_term()?; let mut lhs = self.parse_expr_term()?;
// Parse 0 or more expressions to the right side of the mul operators while let Some(Token::Op(optok)) = self.curr() {
while matches!(self.curr(), Some(Token::Op(Op::Mul | Op::Div | Op::Mod))) { let op_type = match optok {
// We successfully matched curr against Some already in the while condition, so unwrap is fine Op::Mul => BinOpType::Mul,
let tok_op = self.advance().unwrap().clone(); Op::Div => BinOpType::Div,
Op::Mod => BinOpType::Mod,
_ => break
};
self.advance();
let b = self.parse_expr_term()?; let rhs = self.parse_expr_term()?;
let op_type = match tok_op { lhs = Expr::BinOp(op_type, lhs.into(), rhs.into());
Token::Op(Op::Mul) => BinOpType::Mul,
Token::Op(Op::Div) => BinOpType::Div,
Token::Op(Op::Mod) => BinOpType::Mod,
_ => unreachable!(),
};
lhs = Expr::BinOp(op_type, lhs.into(), b.into());
} }
Ok(lhs) Ok(lhs)