refactor: modify numbers inplace
this should improve performance I also happened to fix the lack of detail in the explicit panics
This commit is contained in:
parent
af9e9c9797
commit
23d49fbb6a
1 changed files with 36 additions and 51 deletions
87
src/parse.rs
87
src/parse.rs
|
|
@ -4,7 +4,7 @@ use std::str::FromStr;
|
||||||
use rug::{
|
use rug::{
|
||||||
Float,
|
Float,
|
||||||
float::ParseFloatError,
|
float::ParseFloatError,
|
||||||
ops::{CompleteRound, Pow},
|
ops::{AddFrom, CompleteRound, DivFrom, MulFrom, PowFrom, SubFrom},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, thiserror::Error)]
|
#[derive(Clone, Debug, thiserror::Error)]
|
||||||
|
|
@ -190,105 +190,90 @@ fn collapse_toplevel(nodes: &mut Vec<Node>, mut end: usize) {
|
||||||
.iter()
|
.iter()
|
||||||
.position(|n| *n == Node::Operator(Operator::Exp))
|
.position(|n| *n == Node::Operator(Operator::Exp))
|
||||||
{
|
{
|
||||||
let lhs = match &nodes[start..end][operator - 1] {
|
let lhs = match nodes.remove(start + operator - 1) {
|
||||||
Node::Number(n) => n,
|
Node::Number(n) => n,
|
||||||
_ => panic!("operator is missing an operand"),
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
};
|
};
|
||||||
let rhs = match &nodes[start..end][operator + 1] {
|
end -= 1;
|
||||||
Node::Number(n) => n,
|
match &mut nodes[start..end][operator] {
|
||||||
_ => panic!("operator is missing an operand"),
|
Node::Number(n) => n.pow_from(lhs),
|
||||||
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let number = lhs.pow(rhs).complete(PREC);
|
|
||||||
|
|
||||||
nodes.remove(start + operator - 1);
|
nodes.remove(start + operator - 1);
|
||||||
nodes.remove(start + operator - 1);
|
end -= 1;
|
||||||
end -= 2;
|
|
||||||
nodes[start + operator - 1] = Node::Number(number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(operator) = nodes[start..end]
|
while let Some(operator) = nodes[start..end]
|
||||||
.iter()
|
.iter()
|
||||||
.position(|n| *n == Node::Operator(Operator::Div))
|
.position(|n| *n == Node::Operator(Operator::Div))
|
||||||
{
|
{
|
||||||
let lhs = match &nodes[start..end][operator - 1] {
|
let lhs = match nodes.remove(start + operator - 1) {
|
||||||
Node::Number(n) => n,
|
Node::Number(n) => n,
|
||||||
_ => panic!("operator is missing an operand"),
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
};
|
};
|
||||||
let rhs = match &nodes[start..end][operator + 1] {
|
end -= 1;
|
||||||
Node::Number(n) => n,
|
match &mut nodes[start..end][operator] {
|
||||||
_ => panic!("operator is missing an operand"),
|
Node::Number(n) => n.div_from(lhs),
|
||||||
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let number = (lhs / rhs).complete(PREC);
|
|
||||||
|
|
||||||
nodes.remove(start + operator - 1);
|
nodes.remove(start + operator - 1);
|
||||||
nodes.remove(start + operator - 1);
|
end -= 1;
|
||||||
end -= 2;
|
|
||||||
nodes[start + operator - 1] = Node::Number(number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(operator) = nodes[start..end]
|
while let Some(operator) = nodes[start..end]
|
||||||
.iter()
|
.iter()
|
||||||
.position(|n| *n == Node::Operator(Operator::Mult))
|
.position(|n| *n == Node::Operator(Operator::Mult))
|
||||||
{
|
{
|
||||||
let lhs = match &nodes[start..end][operator - 1] {
|
let lhs = match nodes.remove(start + operator - 1) {
|
||||||
Node::Number(n) => n,
|
Node::Number(n) => n,
|
||||||
_ => panic!("operator is missing an operand"),
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
};
|
};
|
||||||
let rhs = match &nodes[start..end][operator + 1] {
|
end -= 1;
|
||||||
Node::Number(n) => n,
|
match &mut nodes[start..end][operator] {
|
||||||
_ => panic!("operator is missing an operand"),
|
Node::Number(n) => n.mul_from(lhs),
|
||||||
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let number = (lhs * rhs).complete(PREC);
|
|
||||||
|
|
||||||
nodes.remove(start + operator - 1);
|
nodes.remove(start + operator - 1);
|
||||||
nodes.remove(start + operator - 1);
|
end -= 1;
|
||||||
end -= 2;
|
|
||||||
nodes[start + operator - 1] = Node::Number(number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(operator) = nodes[start..end]
|
while let Some(operator) = nodes[start..end]
|
||||||
.iter()
|
.iter()
|
||||||
.position(|n| *n == Node::Operator(Operator::Plus))
|
.position(|n| *n == Node::Operator(Operator::Plus))
|
||||||
{
|
{
|
||||||
let lhs = match &nodes[start..end][operator - 1] {
|
let lhs = match nodes.remove(start + operator - 1) {
|
||||||
Node::Number(n) => n,
|
Node::Number(n) => n,
|
||||||
_ => panic!("operator is missing an operand"),
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
};
|
};
|
||||||
let rhs = match &nodes[start..end][operator + 1] {
|
end -= 1;
|
||||||
Node::Number(n) => n,
|
match &mut nodes[start..end][operator] {
|
||||||
_ => panic!("operator is missing an operand"),
|
Node::Number(n) => n.add_from(lhs),
|
||||||
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let number = (lhs + rhs).complete(PREC);
|
|
||||||
|
|
||||||
nodes.remove(start + operator - 1);
|
nodes.remove(start + operator - 1);
|
||||||
nodes.remove(start + operator - 1);
|
end -= 1;
|
||||||
end -= 2;
|
|
||||||
nodes[start + operator - 1] = Node::Number(number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(operator) = nodes[start..end]
|
while let Some(operator) = nodes[start..end]
|
||||||
.iter()
|
.iter()
|
||||||
.position(|n| *n == Node::Operator(Operator::Minus))
|
.position(|n| *n == Node::Operator(Operator::Minus))
|
||||||
{
|
{
|
||||||
let lhs = match &nodes[start..end][operator - 1] {
|
let lhs = match nodes.remove(start + operator - 1) {
|
||||||
Node::Number(n) => n,
|
Node::Number(n) => n,
|
||||||
_ => panic!("operator is missing an operand"),
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
};
|
};
|
||||||
let rhs = match &nodes[start..end][operator + 1] {
|
end -= 1;
|
||||||
Node::Number(n) => n,
|
match &mut nodes[start..end][operator] {
|
||||||
_ => panic!("operator is missing an operand"),
|
Node::Number(n) => n.sub_from(lhs),
|
||||||
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let number = (lhs - rhs).complete(PREC);
|
|
||||||
|
|
||||||
nodes.remove(start + operator - 1);
|
nodes.remove(start + operator - 1);
|
||||||
nodes.remove(start + operator - 1);
|
end -= 1;
|
||||||
end -= 2;
|
|
||||||
nodes[start + operator - 1] = Node::Number(number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if nodes.len() > 1 {
|
if nodes.len() > 1 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue