Skip to content

Commit

Permalink
Replace all usages of "term" with "expr"
Browse files Browse the repository at this point in the history
  • Loading branch information
Gawdl3y committed Mar 18, 2024
1 parent 1421b3a commit 1ce2186
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 248 deletions.
2 changes: 1 addition & 1 deletion benches/dice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use test::Bencher;

use dicey::{
dice::{Dice, DieRoll, Rolled},
term::Describe,
expr::Describe,
};

#[bench]
Expand Down
10 changes: 5 additions & 5 deletions src/dice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

//! All functionality for directly creating dice, rolling them, and working with their resulting rolls.
//!
//! This is the home of the dice "primitives". For using as part of a larger expression, see [`Term::dice`].
//! This is the home of the dice "primitives". For using as part of a larger expression, see [`Expr::dice`].
//!
//! [`Term::dice`]: ../term/enum.Term.html#variant.Dice
//! [`Expr::dice`]: ../expr/enum.Expr.html#variant.Dice

use std::{cmp, fmt};

use fastrand::Rng;

use crate::term::Describe;
use crate::expr::Describe;

/// A set of one or more rollable dice with a specific number of sides, along with a collection of modifiers to apply to
/// any resulting rolls from them.
Expand Down Expand Up @@ -550,7 +550,7 @@ impl Rolled<'_> {
}

impl Describe for Rolled<'_> {
/// Builds a string of the dice expression the roll is from and a list of all of the individual rolled dice
/// Builds a string of the dice the roll is from and a list of all of the individual rolled dice
/// (see [`DieRoll::fmt()`]).
///
/// If `list_limit` is specified and there are more rolls than it, the output will be truncated and appended with
Expand All @@ -559,7 +559,7 @@ impl Describe for Rolled<'_> {
/// # Examples
///
/// ```
/// use dicey::{dice::{Dice, DieRoll, Rolled}, term::Describe};
/// use dicey::{dice::{Dice, DieRoll, Rolled}, expr::Describe};
///
/// let dice = Dice::builder().count(4).sides(6).keep_high(2).build();
/// let kh_mod = dice.modifiers.first().expect("no first modifier");
Expand Down
186 changes: 93 additions & 93 deletions src/term.rs → src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

use crate::dice::{Dice, Error as DiceError, Rolled};

/// Generates an implementation of [TermType] and [DescribeBinaryTerm] for an enum type.
/// Generates an implementation of [`ExprType`] and [`DescribeBinaryExpr`] for an enum type.
/// This is very tightly coupled with the expected variants (Val, Dice, Neg, Add, Sub, Mul, DivDown, DivUp).
macro_rules! term_type_impl {
macro_rules! expr_type_impl {
($name:ty) => {
impl HasTermType for $name {
fn term_type(&self) -> TermType {
impl HasExprType for $name {
fn expr_type(&self) -> ExprType {
match self {
Self::Num(..) | Self::Dice(..) => TermType::Value,
Self::Neg(..) => TermType::Unary,
Self::Add(..) | Self::Sub(..) => TermType::Additive,
Self::Mul(..) | Self::DivDown(..) | Self::DivUp(..) => TermType::Multiplicative,
Self::Num(..) | Self::Dice(..) => ExprType::Value,
Self::Neg(..) => ExprType::Unary,
Self::Add(..) | Self::Sub(..) => ExprType::Additive,
Self::Mul(..) | Self::DivDown(..) | Self::DivUp(..) => ExprType::Multiplicative,
}
}

Expand All @@ -37,62 +37,62 @@ macro_rules! term_type_impl {
}
}

impl DescribeBinaryTerm for $name {}
impl DescribeBinaryExpr for $name {}
};
}

/// Individual terms usable in expressions
/// Individual elements of a full mathematical dice expression
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Term {
pub enum Expr {
/// Standalone integer
Num(i32),

/// Dice literal
Dice(Dice),

/// Negation of a term (makes it negative)
/// Negation of an expression (makes the result of it negative)
Neg(Box<Self>),

/// Sum of two terms
/// Sum of two expressions
Add(Box<Self>, Box<Self>),

/// Difference of two terms
/// Difference of two expressions
Sub(Box<Self>, Box<Self>),

/// Product of two terms
/// Product of two expressions
Mul(Box<Self>, Box<Self>),

/// Integer quotient of two terms (rounded down)
/// Integer quotient of two expressions (rounded down)
DivDown(Box<Self>, Box<Self>),

/// Integer quotient of two terms (rounded up)
/// Integer quotient of two expressions (rounded up)
DivUp(Box<Self>, Box<Self>),
}

term_type_impl!(Term);
expr_type_impl!(Expr);

impl Term {
/// Evaluates the term. For most types of terms, this will directly result in a 1:1 equivalent [`EvaledTerm`],
/// with the notable exception of [`Term::Dice`]. For dice terms, the dice they contain are rolled, resulting
/// in an [`EvaledTerm::Dice`] with the [`Rolled`] set of dice.
pub fn eval(&self) -> Result<EvaledTerm, Error> {
impl Expr {
/// Evaluates the expression. For most types of expressions, this will directly result in a 1:1 equivalent
/// [`EvaledExpr`], with the notable exception of [`Expr::Dice`]. For dice expressions, the dice they contain are
/// rolled, resulting in an [`EvaledExpr::Dice`] with the [`Rolled`] set of dice.
pub fn eval(&self) -> Result<EvaledExpr, Error> {
Ok(match self {
Self::Num(x) => EvaledTerm::Num(*x),
Self::Dice(dice) => EvaledTerm::Dice(dice.roll()?),
Self::Num(x) => EvaledExpr::Num(*x),
Self::Dice(dice) => EvaledExpr::Dice(dice.roll()?),

Self::Neg(x) => EvaledTerm::Neg(Box::new(x.eval()?)),
Self::Neg(x) => EvaledExpr::Neg(Box::new(x.eval()?)),

Self::Add(a, b) => EvaledTerm::Add(Box::new(a.eval()?), Box::new(b.eval()?)),
Self::Sub(a, b) => EvaledTerm::Sub(Box::new(a.eval()?), Box::new(b.eval()?)),
Self::Mul(a, b) => EvaledTerm::Mul(Box::new(a.eval()?), Box::new(b.eval()?)),
Self::DivDown(a, b) => EvaledTerm::DivDown(Box::new(a.eval()?), Box::new(b.eval()?)),
Self::DivUp(a, b) => EvaledTerm::DivUp(Box::new(a.eval()?), Box::new(b.eval()?)),
Self::Add(a, b) => EvaledExpr::Add(Box::new(a.eval()?), Box::new(b.eval()?)),
Self::Sub(a, b) => EvaledExpr::Sub(Box::new(a.eval()?), Box::new(b.eval()?)),
Self::Mul(a, b) => EvaledExpr::Mul(Box::new(a.eval()?), Box::new(b.eval()?)),
Self::DivDown(a, b) => EvaledExpr::DivDown(Box::new(a.eval()?), Box::new(b.eval()?)),
Self::DivUp(a, b) => EvaledExpr::DivUp(Box::new(a.eval()?), Box::new(b.eval()?)),
})
}

/// Checks whether the term is deterministic (will always yield the same value with every evaluation).
/// A [`Term::Num`] will always return `true`, a [`Term::Dice`] will always return `false` unless the dice they
/// contain only have one side, and all unary and binary terms forward the check to their children.
/// Checks whether the expression is deterministic (will always yield the same value with every evaluation).
/// A [`Expr::Num`] will always return `true`, a [`Expr::Dice`] will always return `false` unless the dice they
/// contain only have one side, and all unary and binary expressions forward the check to their children.
#[must_use]
pub fn is_deterministic(&self) -> bool {
match self {
Expand All @@ -106,10 +106,10 @@ impl Term {
}
}

impl Describe for Term {
/// Builds a full usable expression from the terms. Operations are grouped with parentheses whenever the order of
/// operations could be considered ambiguous, such as when mixing addition and multiplication together. All strings
/// output from this should result in the exact same Term layout when re-parsing them.
impl Describe for Expr {
/// Builds a full usable expression string from the expressions. Operations are grouped with parentheses whenever
/// the order of operations could be considered ambiguous, such as when mixing addition and multiplication together.
/// All strings output from this should result in the exact same expression layout when re-parsing them.
///
/// `list_limit` does not affect the output of this implementation in any way since there are no possible lists of
/// elements included, so it is always safe to pass `None`.
Expand All @@ -124,58 +124,58 @@ impl Describe for Term {
_ => format!("-({})", x.describe(None)),
},

Self::Add(a, b) => self.describe_binary_term('+', a.as_ref(), b.as_ref(), None),
Self::Sub(a, b) => self.describe_binary_term('-', a.as_ref(), b.as_ref(), None),
Self::Mul(a, b) => self.describe_binary_term('*', a.as_ref(), b.as_ref(), None),
Self::DivDown(a, b) => self.describe_binary_term('/', a.as_ref(), b.as_ref(), None),
Self::DivUp(a, b) => self.describe_binary_term('\\', a.as_ref(), b.as_ref(), None),
Self::Add(a, b) => self.describe_binary_expr('+', a.as_ref(), b.as_ref(), None),
Self::Sub(a, b) => self.describe_binary_expr('-', a.as_ref(), b.as_ref(), None),
Self::Mul(a, b) => self.describe_binary_expr('*', a.as_ref(), b.as_ref(), None),
Self::DivDown(a, b) => self.describe_binary_expr('/', a.as_ref(), b.as_ref(), None),
Self::DivUp(a, b) => self.describe_binary_expr('\\', a.as_ref(), b.as_ref(), None),
}
}
}

impl std::fmt::Display for Term {
impl std::fmt::Display for Expr {
/// Formats the value using the given formatter. [Read more][core::fmt::Debug::fmt()]
///
/// The output of this implementation is equivalent to [`Term::describe(None)`].
/// The output of this implementation is equivalent to [`Expr::describe(None)`].
///
/// [`Term::describe(None)`]: ./enum.Term.html#method.describe
/// [`Expr::describe(None)`]: ./enum.Expr.html#method.describe
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.describe(None))
}
}

/// Individual evaluated terms from expressions
/// Individual elements of an evaluated mathematical dice expression
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EvaledTerm<'r> {
pub enum EvaledExpr<'r> {
/// Standalone integer
Num(i32),

/// Rolled dice
Dice(Rolled<'r>),

/// Negation of a term (makes it negative)
/// Negation of an expression (makes the result of it negative)
Neg(Box<Self>),

/// Sum of two terms
/// Sum of two expressions
Add(Box<Self>, Box<Self>),

/// Difference of two terms
/// Difference of two expressions
Sub(Box<Self>, Box<Self>),

/// Product of two terms
/// Product of two expressions
Mul(Box<Self>, Box<Self>),

/// Integer quotient of two terms (rounded down)
/// Integer quotient of two expressions (rounded down)
DivDown(Box<Self>, Box<Self>),

/// Integer quotient of two terms (rounded up)
/// Integer quotient of two expressions (rounded up)
DivUp(Box<Self>, Box<Self>),
}

term_type_impl!(EvaledTerm<'_>);
expr_type_impl!(EvaledExpr<'_>);

impl EvaledTerm<'_> {
/// Calculates the total (sum) of the evaluated term and all of its children (if any).
impl EvaledExpr<'_> {
/// Calculates the total (sum) of the evaluated expression and all of its children (if any).
pub fn calc(&self) -> Result<i32, Error> {
match self {
Self::Num(x) => Ok(*x),
Expand All @@ -202,7 +202,7 @@ impl EvaledTerm<'_> {
}
}

impl Describe for EvaledTerm<'_> {
impl Describe for EvaledExpr<'_> {
fn describe(&self, list_limit: Option<usize>) -> String {
match self {
Self::Num(x) => x.to_string(),
Expand All @@ -213,22 +213,22 @@ impl Describe for EvaledTerm<'_> {
_ => format!("-({})", x.describe(list_limit)),
},

Self::Add(a, b) => self.describe_binary_term('+', a.as_ref(), b.as_ref(), list_limit),
Self::Sub(a, b) => self.describe_binary_term('-', a.as_ref(), b.as_ref(), list_limit),
Self::Mul(a, b) => self.describe_binary_term('*', a.as_ref(), b.as_ref(), list_limit),
Self::DivDown(a, b) => self.describe_binary_term('/', a.as_ref(), b.as_ref(), list_limit),
Self::DivUp(a, b) => self.describe_binary_term('\\', a.as_ref(), b.as_ref(), list_limit),
Self::Add(a, b) => self.describe_binary_expr('+', a.as_ref(), b.as_ref(), list_limit),
Self::Sub(a, b) => self.describe_binary_expr('-', a.as_ref(), b.as_ref(), list_limit),
Self::Mul(a, b) => self.describe_binary_expr('*', a.as_ref(), b.as_ref(), list_limit),
Self::DivDown(a, b) => self.describe_binary_expr('/', a.as_ref(), b.as_ref(), list_limit),
Self::DivUp(a, b) => self.describe_binary_expr('\\', a.as_ref(), b.as_ref(), list_limit),
}
}
}

impl std::fmt::Display for EvaledTerm<'_> {
impl std::fmt::Display for EvaledExpr<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.describe(None))
}
}

/// Error resulting from evaluating a [`Term`] or calculating an [`EvaledTerm`]
/// Error resulting from evaluating a [`Expr`] or calculating an [`EvaledExpr`]
#[derive(thiserror::Error, Debug)]
pub enum Error {
/// Dice-related error (likely during rolling)
Expand All @@ -244,9 +244,9 @@ pub enum Error {
Division,
}

/// Operation type for an individual term
/// Operation type for an individual expression
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TermType {
pub enum ExprType {
/// Single value, no operation
Value,

Expand All @@ -260,24 +260,24 @@ pub enum TermType {
Multiplicative,
}

/// Trait that offers [`TermType`]-related information
pub trait HasTermType {
/// Gets the type of this term.
fn term_type(&self) -> TermType;
/// Trait that offers [`ExprType`]-related information
pub trait HasExprType {
/// Gets the type of this expression.
fn expr_type(&self) -> ExprType;

/// Checks whether this term is a single value.
/// Checks whether this expression is a single value.
fn is_value(&self) -> bool;

/// Checks whether this term is a unary operation.
/// Checks whether this expression is a unary operation.
fn is_unary(&self) -> bool;

/// Checks whether this term is an additive operation.
/// Checks whether this expression is an additive operation.
fn is_additive(&self) -> bool;

/// Checks whether this term is a multiplicative operation.
/// Checks whether this expression is a multiplicative operation.
fn is_multiplicative(&self) -> bool;

/// Checks whether this term is a binary (additive or multiplicative) operation.
/// Checks whether this expression is a binary (additive or multiplicative) operation.
fn is_binary(&self) -> bool {
self.is_additive() || self.is_multiplicative()
}
Expand All @@ -293,34 +293,34 @@ pub trait Describe {
}

/// Trait for describing binary expressions with influence from own type.
/// Used for, e.g. wrapping parentheses around parts of expressions based on [TermType] of self and the expression.
trait DescribeBinaryTerm: HasTermType + Describe {
/// Used for, e.g. wrapping parentheses around parts of expressions based on [`ExprType`] of self and the expression.
trait DescribeBinaryExpr: HasExprType + Describe {
/// Builds a detailed description for a binary expression with parentheses added to disambiguate mixed
/// additive/multiplicative operations.
fn describe_binary_term(
fn describe_binary_expr(
&self,
op: char,
a: &impl DescribeBinaryTerm,
b: &impl DescribeBinaryTerm,
a: &impl DescribeBinaryExpr,
b: &impl DescribeBinaryExpr,
list_limit: Option<usize>,
) -> String {
format!(
"{} {} {}",
match (self.term_type(), a.term_type()) {
(TermType::Additive, TermType::Multiplicative)
| (TermType::Multiplicative, TermType::Additive)
| (TermType::Unary, TermType::Additive)
| (TermType::Unary, TermType::Multiplicative)
| (TermType::Unary, TermType::Unary) => paren_wrap(a.describe(list_limit)),
match (self.expr_type(), a.expr_type()) {
(ExprType::Additive, ExprType::Multiplicative)
| (ExprType::Multiplicative, ExprType::Additive)
| (ExprType::Unary, ExprType::Additive)
| (ExprType::Unary, ExprType::Multiplicative)
| (ExprType::Unary, ExprType::Unary) => paren_wrap(a.describe(list_limit)),
_ => a.describe(list_limit),
},
op,
match (self.term_type(), b.term_type()) {
(TermType::Additive, TermType::Multiplicative)
| (TermType::Multiplicative, TermType::Additive)
| (TermType::Unary, TermType::Additive)
| (TermType::Unary, TermType::Multiplicative)
| (TermType::Unary, TermType::Unary) => paren_wrap(b.describe(list_limit)),
match (self.expr_type(), b.expr_type()) {
(ExprType::Additive, ExprType::Multiplicative)
| (ExprType::Multiplicative, ExprType::Additive)
| (ExprType::Unary, ExprType::Additive)
| (ExprType::Unary, ExprType::Multiplicative)
| (ExprType::Unary, ExprType::Unary) => paren_wrap(b.describe(list_limit)),
_ => b.describe(list_limit),
}
)
Expand Down
Loading

0 comments on commit 1ce2186

Please sign in to comment.