diff --git a/src/dice.rs b/src/dice.rs index 9c1b21e..522f3f6 100644 --- a/src/dice.rs +++ b/src/dice.rs @@ -17,7 +17,6 @@ pub enum Expression { Mul(ExpBox, ExpBox), Div(ExpBox, ExpBox), IntDiv(ExpBox, ExpBox), - Pow(ExpBox, ExpBox), } #[derive(Debug, PartialEq, Clone)] @@ -122,6 +121,9 @@ impl Expression { // Exploding dice are early, they add rolls if let Some(fragments) = x { write!(w, "x")?; + if size < 2 { + bail!("Infinite explosion.") + } let mut comparers = Vec::with_capacity(fragments.len()); for fragment in fragments { comparers.push(fragment.comparer(rng, w)?); @@ -263,12 +265,6 @@ impl Expression { let rhs = rhs_node.evaluate(rng, w, precedence)?; lhs.div_euclid(rhs) } - Pow(lhs_node, rhs_node) => { - let lhs = lhs_node.evaluate(rng, w, precedence)?; - write!(w, " ^ ")?; - let rhs = rhs_node.evaluate(rng, w, precedence)?; - lhs.powf(rhs) - } }; if needs_parens { write!(w, ")")?; @@ -298,7 +294,7 @@ impl Expression { } else { 1 }; - if count > DICE_POOL_LIMIT { + if count > 1_000_000 { bail!("Too many dice.") }; let size = size.avg()? as i64; @@ -330,7 +326,6 @@ impl Expression { Expression::Mul(lhs, rhs) => lhs.avg()? * rhs.avg()?, Expression::Div(lhs, rhs) => lhs.avg()? / rhs.avg()?, Expression::IntDiv(lhs, rhs) => lhs.avg()?.div_euclid(rhs.avg()?), - Expression::Pow(lhs, rhs) => lhs.avg()?.powf(rhs.avg()?), }; Ok(result) } @@ -382,7 +377,6 @@ impl Expression { match self { Const(_) => 1, Dice { .. } => 2, - Pow(_, _) => 4, Neg(_) => 5, Mul(_, _) | Div(_, _) | IntDiv(_, _) => 7, Add(_, _) | Sub(_, _) => 8, @@ -486,7 +480,7 @@ impl<'a> WitnessSet for DiscordMdWitnessSet<'a> { type Error = DiscordMdWitnessError; fn witness_roll(&mut self, dice: DiceRoll) -> Result { - if self.parent.dice_written >= 50 { + if self.parent.dice_written >= 100 { if !self.dice_elided { write!(self.parent.buffer, "…")?; self.dice_elided = true; diff --git a/src/parsing.rs b/src/parsing.rs index 81dc420..1a74101 100644 --- a/src/parsing.rs +++ b/src/parsing.rs @@ -1,10 +1,5 @@ -use crate::dice::{ - CompareFragment, DiceFormula, - Expression::{self, Const}, -}; +use crate::dice::{CompareFragment, DiceFormula, Expression::{self, Const}}; use Assoc::Left; -use nom::character::complete::digit0; -use nom::combinator::recognize; use nom::{ Parser, branch::alt, @@ -94,7 +89,6 @@ fn expr<'c, 'i>( complete(unary_op(5, tag("-"))), fail(), complete(alt(( - binary_op(4, Left, spaced_op("^")), binary_op(7, Left, spaced_op("*")), binary_op(7, Left, spaced_op("//")), binary_op(7, Left, spaced_op("/")), @@ -107,7 +101,6 @@ fn expr<'c, 'i>( Ok(match op { Prefix("-", x) => Neg(Box::new(x)), - Binary(lhs, "^", rhs) => Pow(Box::new(lhs), Box::new(rhs)), Binary(lhs, "*", rhs) => Mul(Box::new(lhs), Box::new(rhs)), Binary(lhs, "//", rhs) => IntDiv(Box::new(lhs), Box::new(rhs)), Binary(lhs, "/", rhs) => Div(Box::new(lhs), Box::new(rhs)), @@ -122,12 +115,9 @@ fn expr<'c, 'i>( } fn number(i: &str) -> IResult<&str, Expression> { - map_res( - alt((recognize((digit0, tag("."), digit1())), digit1())), - |s: &str| s.parse::(), - ) - .map(Const) - .parse_complete(i) + map_res(digit1(), |s: &str| s.parse::()) + .map(Const) + .parse_complete(i) } fn basic_operand<'c, 'i>( @@ -138,7 +128,7 @@ fn basic_operand<'c, 'i>( fn compare_fragment<'c, 'i>( ctx: &'c Context, -) -> impl Parser<&'i str, Output = CompareFragment, Error = InternalError<&'i str>> + use<'c, 'i> { +) -> impl Parser<&'i str, Output = CompareFragment, Error = InternalError<&'i str>> + use<'c, 'i> { use CompareFragment::*; alt(( preceded(tag("="), basic_operand(ctx)).map(|x| Eq(Box::new(x))), @@ -164,18 +154,6 @@ mod test { assert_matches!(expression, Expression::Dice { .. }); } - #[test] - pub fn parse_decimal() { - let expression = parse("2.5+2.5").unwrap(); - assert_matches!(expression, Expression::Add { .. }); - } - - #[test] - pub fn parse_decimal2() { - let expression = parse(".4*.8").unwrap(); - assert_matches!(expression, Expression::Mul { .. }); - } - #[test] pub fn parse_bare_dice() { let expression = parse("d8").unwrap(); @@ -184,7 +162,7 @@ mod test { #[test] pub fn parse_math() { - let expression = parse("8 * 2 + 2 * 5 ^ 4").unwrap(); + let expression = parse("8 * 2 + 2 * 5").unwrap(); assert_matches!(expression, Expression::Add { .. }); }