forked from asklyphe-public/asklyphe
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