forked from asklyphe-public/asklyphe
*Mostly* works, apart from 4 sqrt 4
being 1.4142135623730951
for some reason (messed up unary operators or something)
This commit is contained in:
parent
25644b9d4e
commit
b7b466b774
1 changed files with 58 additions and 4 deletions
|
@ -10,9 +10,11 @@ pub struct Calculation {
|
|||
pub fn calculate(query: &str) -> Option<Calculation> {
|
||||
debug!("Got query {}", query);
|
||||
let mut parser = Parser::new(Lexer::new(query));
|
||||
debug!("Parse tree: {:?}", parser.parse());
|
||||
// debug!("final token was: {:?}", lexer.next());
|
||||
// debug!("Tokens: {:?}", lexer.lex_all());
|
||||
let res = parser.parse()?;
|
||||
|
||||
debug!("Calculation: {}", query);
|
||||
debug!("Tree: {:?}", res);
|
||||
debug!("Result: {}", res.eval());
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -43,7 +45,7 @@ impl Op {
|
|||
BinOp::Divide => 2.0,
|
||||
BinOp::Exponent => 3.0,
|
||||
},
|
||||
Op::Func(_) => 2.9, // TODO: decide if this is a good LBP
|
||||
Op::Func(_) => 0.9, // TODO: decide if this is a good LBP
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,6 +64,26 @@ impl Op {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
fn apply_to(&self, args: &Vec<Expr>) -> f64 {
|
||||
match (self) {
|
||||
Op::BinOp(op) => match op {
|
||||
BinOp::LParen => args[0].eval(),
|
||||
BinOp::RParen => args[0].eval(),
|
||||
BinOp::Add => args[0].eval() + args[1].eval(),
|
||||
BinOp::Subtract => args[0].eval() - args[1].eval(),
|
||||
BinOp::Multiply => args[0].eval() * args[1].eval(),
|
||||
BinOp::Divide => args[0].eval() / args[1].eval(),
|
||||
BinOp::Exponent => args[0].eval().powf(args[1].eval()),
|
||||
},
|
||||
Op::Func(f) => match f {
|
||||
Func::Sine => args[0].eval().sin(),
|
||||
Func::ArcSine => args[0].eval().asin(),
|
||||
Func::SquareRoot => args[0].eval().sqrt(),
|
||||
_ => todo!("{:?}", f),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
@ -185,6 +207,27 @@ impl Lexer<'_> {
|
|||
self.idx += l;
|
||||
return Ok(Token::Op(Op::Func(Func::Tangent)));
|
||||
}
|
||||
l = matches(&self.data[self.idx - 1..], "arcsin");
|
||||
if l != 0 {
|
||||
self.idx += l;
|
||||
return Ok(Token::Op(Op::Func(Func::ArcSine)));
|
||||
}
|
||||
l = matches(&self.data[self.idx - 1..], "arccos");
|
||||
if l != 0 {
|
||||
self.idx += l;
|
||||
return Ok(Token::Op(Op::Func(Func::ArcCosine)));
|
||||
}
|
||||
l = matches(&self.data[self.idx - 1..], "arctan");
|
||||
if l != 0 {
|
||||
self.idx += l;
|
||||
return Ok(Token::Op(Op::Func(Func::ArcTangent)));
|
||||
}
|
||||
l = matches(&self.data[self.idx - 1..], "sqrt");
|
||||
if l != 0 {
|
||||
self.idx += l;
|
||||
return Ok(Token::Op(Op::Func(Func::SquareRoot)));
|
||||
}
|
||||
|
||||
debug!("got invalid char '{}'", val);
|
||||
Err(ParseErr::Invalid)
|
||||
}
|
||||
|
@ -289,3 +332,14 @@ enum Expr {
|
|||
Atom(Atom),
|
||||
Node(Op, Vec<Expr>),
|
||||
}
|
||||
|
||||
impl Expr {
|
||||
fn eval(&self) -> f64 {
|
||||
let res = match (self) {
|
||||
Expr::Atom(at) => at.get_val(),
|
||||
Expr::Node(op, exprs) => op.apply_to(exprs),
|
||||
};
|
||||
// debug!("{:?} evaluated to {}", self, res);
|
||||
res
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue