diff options
Diffstat (limited to 'src/parser.rs')
| -rw-r--r-- | src/parser.rs | 86 |
1 files changed, 48 insertions, 38 deletions
diff --git a/src/parser.rs b/src/parser.rs index 0b7bcd8..01f0e1b 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -116,82 +116,92 @@ impl<'a> Parser<'a> { fn parse_fun(&mut self) -> Result<Num, ParseError> { if self.symbol("sin") { - return Ok(self.atom()?.sin()); + return Ok(seq(self.fun_expr())?.sin()); } if self.symbol("cos") { - return Ok(self.atom()?.cos()); + return Ok(seq(self.fun_expr())?.cos()); } if self.symbol("tan") { - return Ok(self.atom()?.tan()); + return Ok(seq(self.fun_expr())?.tan()); } if self.symbol("sqrt") { - return Ok(self.atom()?.sqrt()); + return Ok(seq(self.fun_expr())?.sqrt()); } if self.symbol("log") || self.symbol("ln") { - return Ok(self.atom()?.log()); + return Ok(seq(self.fun_expr())?.log()); + } + if self.symbol("log10") { + return Ok(seq(self.fun_expr())?.log10()); + } + if self.symbol("log2") { + return Ok(seq(self.fun_expr())?.log2()); } if self.symbol("floor") { - return Ok(self.atom()?.floor()); + return Ok(seq(self.fun_expr())?.floor()); } if self.symbol("ceil") || self.symbol("ceiling") { - return Ok(self.atom()?.ceil()); + return Ok(seq(self.fun_expr())?.ceil()); } if self.symbol("round") { - return Ok(self.atom()?.round()); + return Ok(seq(self.fun_expr())?.round()); + } + if self.symbol("abs") { + return Ok(seq(self.fun_expr())?.abs()); } Err(ParseError::Empty) } - fn app_expr_fold(&mut self, e1: Num) -> Result<Num, ParseError> { - if let Some(e2) = or(self.parse_fun())? { - return self.app_expr_fold(e1.mul(e2)); - } - if let Some(e2) = or(self.paren_expr())? { - return self.app_expr_fold(e1.mul(e2)); - } - if let Some(e2) = or(self.parse_const())? { - return self.app_expr_fold(e1.mul(e2)); + fn fun_expr(&mut self) -> Result<Num, ParseError> { + if let Some(n) = or(self.parse_fun())? { + return Ok(n); } - Ok(e1) + self.atom() } - fn app_expr(&mut self) -> Result<Num, ParseError> { - if let Some(e1) = or(self.parse_fun())? { - return Ok(e1); + fn fun_expr_no_num(&mut self) -> Result<Num, ParseError> { + if let Some(n) = or(self.parse_fun())? { + return Ok(n); } - let e1 = self.atom()?; - self.app_expr_fold(e1) + if let Some(n) = or(self.paren_expr())? { + return Ok(n); + } + self.parse_const() } - fn expt_expr_fold(&mut self, e1: Num) -> Result<Num, ParseError> { - if !self.symbol("^") { - return Ok(e1); + fn expt_expr(&mut self) -> Result<Num, ParseError> { + let e1 = self.fun_expr()?; + if self.symbol("^") { + let e2 = seq(self.expt_expr())?; + return Ok(e1.pow(e2)); } - let e2 = seq(self.app_expr())?; - let e2 = self.expt_expr_fold(e2)?; - Ok(e1.pow(e2)) + Ok(e1) } - fn expt_expr(&mut self) -> Result<Num, ParseError> { - let n = self.app_expr()?; - self.expt_expr_fold(n) + fn expt_expr_no_num(&mut self) -> Result<Num, ParseError> { + let e1 = self.fun_expr_no_num()?; + if self.symbol("^") { + let e2 = seq(self.expt_expr())?; + return Ok(e1.pow(e2)); + } + Ok(e1) } fn mul_expr_fold(&mut self, e1: Num) -> Result<Num, ParseError> { if self.symbol("*") { let e2 = seq(self.expt_expr())?; - let e = e1.mul(e2); - return self.mul_expr_fold(e); + return self.mul_expr_fold(e1.mul(e2)); } if self.symbol("/") { let e2 = seq(self.expt_expr())?; - let e = e1.div(e2); - return self.mul_expr_fold(e); + return self.mul_expr_fold(e1.div(e2)); } if self.symbol("//") { let e2 = seq(self.expt_expr())?; - let e = e1.int_div(e2); - return self.mul_expr_fold(e); + return self.mul_expr_fold(e1.int_div(e2)); + } + // Allow implicit multiplication + if let Some(e2) = or(self.expt_expr_no_num())? { + return self.mul_expr_fold(e1.mul(e2)); } Ok(e1) } |
