aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.rs
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2024-05-27 19:51:22 -0700
committerRose Hogenson <rosehogenson@posteo.net>2024-05-27 19:51:22 -0700
commitfbe36c4248ad9863de5cdd47956327b991e4e64b (patch)
treec910fee68e6da27b6d540eb983912cbee6b47962 /src/parser.rs
parent17a76d59cfac2a19f22e28a6582008b667b5106c (diff)
downloadqc-fbe36c4248ad9863de5cdd47956327b991e4e64b.tar.zst
Fix order of operations.
PEMDAS
Diffstat (limited to 'src/parser.rs')
-rw-r--r--src/parser.rs86
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)
}