simplify
This commit is contained in:
		
							parent
							
								
									9c9172d4c9
								
							
						
					
					
						commit
						199bce4f90
					
				
					 1 changed files with 47 additions and 52 deletions
				
			
		| 
						 | 
					@ -30,53 +30,61 @@ enum Token {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Copy, Clone)]
 | 
					#[derive(Debug, Copy, Clone)]
 | 
				
			||||||
enum Op {
 | 
					enum Op {
 | 
				
			||||||
	BinOp(BinOp),
 | 
						Add,
 | 
				
			||||||
 | 
						Subtract,
 | 
				
			||||||
 | 
						Multiply,
 | 
				
			||||||
 | 
						Divide,
 | 
				
			||||||
 | 
						Exponent,
 | 
				
			||||||
 | 
						LParen,
 | 
				
			||||||
 | 
						RParen,
 | 
				
			||||||
	Func(Func), // A function is an Op that takes whatever the next thing is and binds it, either the next number or whatever is in parens
 | 
						Func(Func), // A function is an Op that takes whatever the next thing is and binds it, either the next number or whatever is in parens
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Op {
 | 
					impl Op {
 | 
				
			||||||
	fn get_lbp(&self) -> f64 {
 | 
						fn get_lbp(&self) -> f64 {
 | 
				
			||||||
		match self {
 | 
							match self {
 | 
				
			||||||
			Op::BinOp(op) => match op {
 | 
								Op::LParen => 0.0,
 | 
				
			||||||
				BinOp::LParen => 0.0,
 | 
								Op::RParen => 0.0,
 | 
				
			||||||
				BinOp::RParen => 0.0,
 | 
								Op::Add => 1.0,
 | 
				
			||||||
				BinOp::Add => 1.0,
 | 
								Op::Subtract => 1.0,
 | 
				
			||||||
				BinOp::Subtract => 1.0,
 | 
								Op::Multiply => 2.0,
 | 
				
			||||||
				BinOp::Multiply => 2.0,
 | 
								Op::Divide => 2.0,
 | 
				
			||||||
				BinOp::Divide => 2.0,
 | 
								Op::Exponent => 3.1,
 | 
				
			||||||
				BinOp::Exponent => 3.1,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			Op::Func(_) => 0.0, // TODO: decide if this is a good LBP
 | 
								Op::Func(_) => 0.0, // TODO: decide if this is a good LBP
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn get_rbp(&self) -> f64 {
 | 
						fn get_rbp(&self) -> f64 {
 | 
				
			||||||
		match self {
 | 
							match self {
 | 
				
			||||||
			Op::BinOp(op) => match op {
 | 
								Op::LParen => 0.0,
 | 
				
			||||||
				BinOp::LParen => 0.0,
 | 
								Op::RParen => 0.0,
 | 
				
			||||||
				BinOp::RParen => 0.0,
 | 
								Op::Add => 1.1,
 | 
				
			||||||
				BinOp::Add => 1.1,
 | 
								Op::Subtract => 1.1,
 | 
				
			||||||
				BinOp::Subtract => 1.1,
 | 
								Op::Multiply => 2.1,
 | 
				
			||||||
				BinOp::Multiply => 2.1,
 | 
								Op::Divide => 2.1,
 | 
				
			||||||
				BinOp::Divide => 2.1,
 | 
								Op::Exponent => 3.0,
 | 
				
			||||||
				BinOp::Exponent => 3.0,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			Op::Func(_) => 4.0, // TODO: decide if this is a good RBP
 | 
								Op::Func(_) => 4.0, // TODO: decide if this is a good RBP
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Prefix binding power
 | 
				
			||||||
 | 
					// 	fn get_pbp(&self) -> Option<f64> {
 | 
				
			||||||
 | 
					// 		match self {
 | 
				
			||||||
 | 
					// 			Op::BinOp(op) => match op {
 | 
				
			||||||
 | 
					// 				BinOp::
 | 
				
			||||||
 | 
					// 			}
 | 
				
			||||||
 | 
					// 		}
 | 
				
			||||||
 | 
					// 	}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn apply_to(&self, args: &Vec<Expr>) -> f64 {
 | 
						fn apply_to(&self, args: &Vec<Expr>) -> f64 {
 | 
				
			||||||
		match (self) {
 | 
							match (self) {
 | 
				
			||||||
			Op::BinOp(op) => match op {
 | 
								Op::LParen => args[0].eval(),
 | 
				
			||||||
				BinOp::LParen => args[0].eval(),
 | 
								Op::RParen => args[0].eval(),
 | 
				
			||||||
				BinOp::RParen => args[0].eval(),
 | 
								Op::Add => args[0].eval() + args[1].eval(),
 | 
				
			||||||
				BinOp::Add => args[0].eval() + args[1].eval(),
 | 
								Op::Subtract => args[0].eval() - args[1].eval(),
 | 
				
			||||||
				BinOp::Subtract => args[0].eval() - args[1].eval(),
 | 
								Op::Multiply => args[0].eval() * args[1].eval(),
 | 
				
			||||||
				BinOp::Multiply => args[0].eval() * args[1].eval(),
 | 
								Op::Divide => args[0].eval() / args[1].eval(),
 | 
				
			||||||
				BinOp::Divide => args[0].eval() / args[1].eval(),
 | 
								Op::Exponent => args[0].eval().powf(args[1].eval()),
 | 
				
			||||||
				BinOp::Exponent => args[0].eval().powf(args[1].eval()),
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			Op::Func(f) => match f {
 | 
								Op::Func(f) => match f {
 | 
				
			||||||
				Func::Sine => args[0].eval().sin(),
 | 
									Func::Sine => args[0].eval().sin(),
 | 
				
			||||||
				Func::ArcSine => args[0].eval().asin(),
 | 
									Func::ArcSine => args[0].eval().asin(),
 | 
				
			||||||
| 
						 | 
					@ -87,17 +95,6 @@ impl Op {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Copy, Clone)]
 | 
					 | 
				
			||||||
enum BinOp {
 | 
					 | 
				
			||||||
	Add,
 | 
					 | 
				
			||||||
	Subtract,
 | 
					 | 
				
			||||||
	Multiply,
 | 
					 | 
				
			||||||
	Divide,
 | 
					 | 
				
			||||||
	Exponent,
 | 
					 | 
				
			||||||
	LParen,
 | 
					 | 
				
			||||||
	RParen,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Debug, Copy, Clone)]
 | 
					#[derive(Debug, Copy, Clone)]
 | 
				
			||||||
enum Atom {
 | 
					enum Atom {
 | 
				
			||||||
	Number(f64), // TODO: use the high precision floats library instead
 | 
						Number(f64), // TODO: use the high precision floats library instead
 | 
				
			||||||
| 
						 | 
					@ -172,13 +169,13 @@ impl Lexer<'_> {
 | 
				
			||||||
				// TODO: make more efficient
 | 
									// TODO: make more efficient
 | 
				
			||||||
				self.data_ptr = &self.data[self.idx..];
 | 
									self.data_ptr = &self.data[self.idx..];
 | 
				
			||||||
				match val {
 | 
									match val {
 | 
				
			||||||
					'+' => Ok(Token::Op(Op::BinOp(BinOp::Add))),
 | 
										'+' => Ok(Token::Op(Op::Add)),
 | 
				
			||||||
					'-' => Ok(Token::Op(Op::BinOp(BinOp::Subtract))),
 | 
										'-' => Ok(Token::Op(Op::Subtract)),
 | 
				
			||||||
					'×' | '*' => Ok(Token::Op(Op::BinOp(BinOp::Multiply))),
 | 
										'×' | '*' => Ok(Token::Op(Op::Multiply)),
 | 
				
			||||||
					'÷' | '/' => Ok(Token::Op(Op::BinOp(BinOp::Divide))),
 | 
										'÷' | '/' => Ok(Token::Op(Op::Divide)),
 | 
				
			||||||
					'^' => Ok(Token::Op(Op::BinOp(BinOp::Exponent))),
 | 
										'^' => Ok(Token::Op(Op::Exponent)),
 | 
				
			||||||
					'(' => Ok(Token::Op(Op::BinOp(BinOp::LParen))),
 | 
										'(' => Ok(Token::Op(Op::LParen)),
 | 
				
			||||||
					')' => Ok(Token::Op(Op::BinOp(BinOp::RParen))),
 | 
										')' => Ok(Token::Op(Op::RParen)),
 | 
				
			||||||
					_ if val.is_whitespace() => self._next(),
 | 
										_ if val.is_whitespace() => self._next(),
 | 
				
			||||||
					// TODO: maybe parse '-' as part of number so I can do '1 + -1' and similar
 | 
										// TODO: maybe parse '-' as part of number so I can do '1 + -1' and similar
 | 
				
			||||||
					_ if val.is_digit(10) => {
 | 
										_ if val.is_digit(10) => {
 | 
				
			||||||
| 
						 | 
					@ -293,7 +290,7 @@ impl Parser<'_> {
 | 
				
			||||||
			Ok(val) => match val {
 | 
								Ok(val) => match val {
 | 
				
			||||||
				Token::Atom(val) => Ok(Expr::Atom(val)),
 | 
									Token::Atom(val) => Ok(Expr::Atom(val)),
 | 
				
			||||||
				Token::Op(op) => match op {
 | 
									Token::Op(op) => match op {
 | 
				
			||||||
					Op::BinOp(BinOp::LParen) => self.parse_expr(op.get_lbp()),
 | 
										Op::LParen => self.parse_expr(op.get_lbp()),
 | 
				
			||||||
					Op::Func(f) => Ok(Expr::Node(Op::Func(f), vec![self.parse_expr(op.get_lbp())?])),
 | 
										Op::Func(f) => Ok(Expr::Node(Op::Func(f), vec![self.parse_expr(op.get_lbp())?])),
 | 
				
			||||||
					_ => Err(ParseErr::Invalid),
 | 
										_ => Err(ParseErr::Invalid),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
| 
						 | 
					@ -307,14 +304,12 @@ impl Parser<'_> {
 | 
				
			||||||
				Err(e) => { debug!("In expr got err {:?}", e); Err(e) },
 | 
									Err(e) => { debug!("In expr got err {:?}", e); Err(e) },
 | 
				
			||||||
				Ok(tok) => match tok {
 | 
									Ok(tok) => match tok {
 | 
				
			||||||
					Token::Op(op) => match op {
 | 
										Token::Op(op) => match op {
 | 
				
			||||||
						Op::BinOp(op) => match op {
 | 
											Op::RParen => break,
 | 
				
			||||||
							BinOp::RParen => break,
 | 
					 | 
				
			||||||
							_ => Ok(Op::BinOp(op)),
 | 
					 | 
				
			||||||
						},
 | 
					 | 
				
			||||||
						Op::Func(f) => {
 | 
											Op::Func(f) => {
 | 
				
			||||||
							lhs = Expr::Node(Op::Func(f), vec![self.parse_expr(Op::Func(f).get_lbp())?]);
 | 
												lhs = Expr::Node(Op::Func(f), vec![self.parse_expr(Op::Func(f).get_lbp())?]);
 | 
				
			||||||
							continue;
 | 
												continue;
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
 | 
											_ => Ok(op),
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					v => { debug!("Got unexpected token {:?}", v); Err(ParseErr::Invalid) },
 | 
										v => { debug!("Got unexpected token {:?}", v); Err(ParseErr::Invalid) },
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue