feat(argus): add Display trait for Expr
This commit is contained in:
parent
4f33300d1c
commit
3880356c66
5 changed files with 72 additions and 29 deletions
|
|
@ -16,6 +16,7 @@ derive_more = "0.99.17"
|
||||||
enum_dispatch = "0.3.12"
|
enum_dispatch = "0.3.12"
|
||||||
hashbrown = "0.14.1"
|
hashbrown = "0.14.1"
|
||||||
itertools = "0.11"
|
itertools = "0.11"
|
||||||
|
log = "0.4.20"
|
||||||
num-traits = "0.2.16"
|
num-traits = "0.2.16"
|
||||||
paste = "1.0.14"
|
paste = "1.0.14"
|
||||||
proptest = { version = "1.2", optional = true }
|
proptest = { version = "1.2", optional = true }
|
||||||
|
|
@ -24,6 +25,7 @@ thiserror = "1.0.47"
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
proptest = "1.2"
|
proptest = "1.2"
|
||||||
argus = { path = ".", features = ["arbitrary"] }
|
argus = { path = ".", features = ["arbitrary"] }
|
||||||
|
env_logger = "0.10.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,11 @@ use argus::parse_str;
|
||||||
use ariadne::{sources, Color, Label, Report, ReportKind};
|
use ariadne::{sources, Color, Label, Report, ReportKind};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
env_logger::init();
|
||||||
let src = env::args().nth(1).expect("Expected expression");
|
let src = env::args().nth(1).expect("Expected expression");
|
||||||
|
|
||||||
match parse_str(&src) {
|
match parse_str(&src) {
|
||||||
Ok(expr) => println!("{:#?}", expr),
|
Ok(expr) => println!("{}", expr),
|
||||||
Err(errs) => {
|
Err(errs) => {
|
||||||
errs.into_iter().for_each(|e| {
|
errs.into_iter().for_each(|e| {
|
||||||
Report::build(ReportKind::Error, src.clone(), e.span().start)
|
Report::build(ReportKind::Error, src.clone(), e.span().start)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ pub trait IsNumExpr: AnyExpr + Into<NumExpr> {}
|
||||||
pub trait IsBoolExpr: AnyExpr + Into<BoolExpr> {}
|
pub trait IsBoolExpr: AnyExpr + Into<BoolExpr> {}
|
||||||
|
|
||||||
/// All expressions that are numeric
|
/// All expressions that are numeric
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
#[enum_dispatch(AnyExpr)]
|
#[enum_dispatch(AnyExpr)]
|
||||||
pub enum NumExpr {
|
pub enum NumExpr {
|
||||||
/// A signed integer literal
|
/// A signed integer literal
|
||||||
|
|
@ -73,7 +73,7 @@ impl NumExpr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// All expressions that are evaluated to be of type `bool`
|
/// All expressions that are evaluated to be of type `bool`
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
#[enum_dispatch(AnyExpr)]
|
#[enum_dispatch(AnyExpr)]
|
||||||
pub enum BoolExpr {
|
pub enum BoolExpr {
|
||||||
/// A `bool` literal
|
/// A `bool` literal
|
||||||
|
|
@ -139,7 +139,7 @@ pub enum ExprRef<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An expression (either [`BoolExpr`] or [`NumExpr`])
|
/// An expression (either [`BoolExpr`] or [`NumExpr`])
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, derive_more::Display)]
|
||||||
#[enum_dispatch(AnyExpr)]
|
#[enum_dispatch(AnyExpr)]
|
||||||
pub enum Expr {
|
pub enum Expr {
|
||||||
/// A reference to a [`BoolExpr`]
|
/// A reference to a [`BoolExpr`]
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,28 @@
|
||||||
//! Boolean expression types
|
//! Boolean expression types
|
||||||
|
|
||||||
use std::ops::{Bound, RangeBounds};
|
use std::ops::{Bound, RangeBounds};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
use super::{AnyExpr, BoolExpr, NumExpr};
|
use super::{AnyExpr, BoolExpr, NumExpr};
|
||||||
|
|
||||||
/// Types of comparison operations
|
/// Types of comparison operations
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq, derive_more::Display)]
|
||||||
pub enum Ordering {
|
pub enum Ordering {
|
||||||
/// Equality check for two expressions
|
/// Equality check for two expressions
|
||||||
|
#[display(fmt = "==")]
|
||||||
Eq,
|
Eq,
|
||||||
/// Non-equality check for two expressions
|
/// Non-equality check for two expressions
|
||||||
|
#[display(fmt = "!=")]
|
||||||
NotEq,
|
NotEq,
|
||||||
/// Less than check
|
/// Less than check
|
||||||
|
#[display(fmt = "{}", r#"if *strict { "<".to_string() } else { "<=".to_string() } "#r)]
|
||||||
Less {
|
Less {
|
||||||
/// Denotes `lhs < rhs` if `strict`, and `lhs <= rhs` otherwise.
|
/// Denotes `lhs < rhs` if `strict`, and `lhs <= rhs` otherwise.
|
||||||
strict: bool,
|
strict: bool,
|
||||||
},
|
},
|
||||||
/// Greater than check
|
/// Greater than check
|
||||||
|
#[display(fmt = "{}", r#"if *strict { ">".to_string() } else { ">=".to_string() } "#r)]
|
||||||
Greater {
|
Greater {
|
||||||
/// Denotes `lhs > rhs` if `strict`, and `lhs >= rhs` otherwise.
|
/// Denotes `lhs > rhs` if `strict`, and `lhs >= rhs` otherwise.
|
||||||
strict: bool,
|
strict: bool,
|
||||||
|
|
@ -66,6 +71,21 @@ pub struct Interval {
|
||||||
pub end: Bound<Duration>,
|
pub end: Bound<Duration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl core::fmt::Display for Interval {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let start_str = match self.start {
|
||||||
|
Bound::Included(b) | Bound::Excluded(b) => b.as_secs_f64().to_string(),
|
||||||
|
Bound::Unbounded => "".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let end_str = match self.end {
|
||||||
|
Bound::Included(b) | Bound::Excluded(b) => b.as_secs_f64().to_string(),
|
||||||
|
Bound::Unbounded => "".to_string(),
|
||||||
|
};
|
||||||
|
write!(f, "[{}, {}]", start_str, end_str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Interval {
|
impl Interval {
|
||||||
/// Create a new interval
|
/// Create a new interval
|
||||||
///
|
///
|
||||||
|
|
@ -174,13 +194,14 @@ macro_rules! impl_bool_expr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `bool` literal
|
/// A `bool` literal
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
pub struct BoolLit(pub bool);
|
pub struct BoolLit(pub bool);
|
||||||
|
|
||||||
impl_bool_expr!(BoolLit);
|
impl_bool_expr!(BoolLit);
|
||||||
|
|
||||||
/// A `bool` variable
|
/// A `bool` variable
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "{}", name)]
|
||||||
pub struct BoolVar {
|
pub struct BoolVar {
|
||||||
/// Variable name
|
/// Variable name
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
@ -189,7 +210,8 @@ pub struct BoolVar {
|
||||||
impl_bool_expr!(BoolVar);
|
impl_bool_expr!(BoolVar);
|
||||||
|
|
||||||
/// A comparison expression
|
/// A comparison expression
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "{} {} {}", lhs, op, rhs)]
|
||||||
pub struct Cmp {
|
pub struct Cmp {
|
||||||
/// The type of comparison
|
/// The type of comparison
|
||||||
pub op: Ordering,
|
pub op: Ordering,
|
||||||
|
|
@ -202,7 +224,8 @@ pub struct Cmp {
|
||||||
impl_bool_expr!(Cmp, lhs, rhs);
|
impl_bool_expr!(Cmp, lhs, rhs);
|
||||||
|
|
||||||
/// Logical negation of an expression
|
/// Logical negation of an expression
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "!({})", arg)]
|
||||||
pub struct Not {
|
pub struct Not {
|
||||||
/// Expression to be negated
|
/// Expression to be negated
|
||||||
pub arg: Box<BoolExpr>,
|
pub arg: Box<BoolExpr>,
|
||||||
|
|
@ -211,7 +234,8 @@ pub struct Not {
|
||||||
impl_bool_expr!(Not, arg);
|
impl_bool_expr!(Not, arg);
|
||||||
|
|
||||||
/// Logical conjunction of a list of expressions
|
/// Logical conjunction of a list of expressions
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "({})", r#"args.iter().map(ToString::to_string).join(") && (")"#r)]
|
||||||
pub struct And {
|
pub struct And {
|
||||||
/// Expressions to be "and"-ed
|
/// Expressions to be "and"-ed
|
||||||
pub args: Vec<BoolExpr>,
|
pub args: Vec<BoolExpr>,
|
||||||
|
|
@ -220,7 +244,8 @@ pub struct And {
|
||||||
impl_bool_expr!(And, [args]);
|
impl_bool_expr!(And, [args]);
|
||||||
|
|
||||||
/// Logical disjunction of a list of expressions
|
/// Logical disjunction of a list of expressions
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "({})", r#"args.iter().map(ToString::to_string).join(") || (")"#r)]
|
||||||
pub struct Or {
|
pub struct Or {
|
||||||
/// Expressions to be "or"-ed
|
/// Expressions to be "or"-ed
|
||||||
pub args: Vec<BoolExpr>,
|
pub args: Vec<BoolExpr>,
|
||||||
|
|
@ -231,7 +256,8 @@ impl_bool_expr!(Or, [args]);
|
||||||
/// A temporal next expression
|
/// A temporal next expression
|
||||||
///
|
///
|
||||||
/// Checks if the next time point in a signal is `true` or not.
|
/// Checks if the next time point in a signal is `true` or not.
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "X ({})", arg)]
|
||||||
pub struct Next {
|
pub struct Next {
|
||||||
/// Argument for `Next`
|
/// Argument for `Next`
|
||||||
pub arg: Box<BoolExpr>,
|
pub arg: Box<BoolExpr>,
|
||||||
|
|
@ -242,7 +268,8 @@ impl_bool_expr!(Next, arg);
|
||||||
///
|
///
|
||||||
/// This is equivalent to `steps` number of nested [`Next`](BoolExpr::Next)
|
/// This is equivalent to `steps` number of nested [`Next`](BoolExpr::Next)
|
||||||
/// expressions.
|
/// expressions.
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "X[0,{}]({})", steps, arg)]
|
||||||
pub struct Oracle {
|
pub struct Oracle {
|
||||||
/// Number of steps to look ahead
|
/// Number of steps to look ahead
|
||||||
pub steps: usize,
|
pub steps: usize,
|
||||||
|
|
@ -256,7 +283,8 @@ impl_bool_expr!(Oracle, arg);
|
||||||
/// - If the `interval` is `(Unbounded, Unbounded)` or equivalent to `(0, Unbounded)`:
|
/// - If the `interval` is `(Unbounded, Unbounded)` or equivalent to `(0, Unbounded)`:
|
||||||
/// checks if the signal is `true` for all points in a signal.
|
/// checks if the signal is `true` for all points in a signal.
|
||||||
/// - Otherwise: checks if the signal is `true` for all points within the `interval`.
|
/// - Otherwise: checks if the signal is `true` for all points within the `interval`.
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "G{}({})", interval, arg)]
|
||||||
pub struct Always {
|
pub struct Always {
|
||||||
/// Argument for `Always`
|
/// Argument for `Always`
|
||||||
pub arg: Box<BoolExpr>,
|
pub arg: Box<BoolExpr>,
|
||||||
|
|
@ -270,7 +298,8 @@ impl_bool_expr!(Always, arg);
|
||||||
/// - If the `interval` is `(Unbounded, Unbounded)` or equivalent to `(0, Unbounded)`:
|
/// - If the `interval` is `(Unbounded, Unbounded)` or equivalent to `(0, Unbounded)`:
|
||||||
/// checks if the signal is `true` for some point in a signal.
|
/// checks if the signal is `true` for some point in a signal.
|
||||||
/// - Otherwise: checks if the signal is `true` for some point within the `interval`.
|
/// - Otherwise: checks if the signal is `true` for some point within the `interval`.
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "F{}({})", interval, arg)]
|
||||||
pub struct Eventually {
|
pub struct Eventually {
|
||||||
/// Argument for `Eventually`
|
/// Argument for `Eventually`
|
||||||
pub arg: Box<BoolExpr>,
|
pub arg: Box<BoolExpr>,
|
||||||
|
|
@ -282,7 +311,8 @@ impl_bool_expr!(Eventually, arg);
|
||||||
/// A temporal until expression
|
/// A temporal until expression
|
||||||
///
|
///
|
||||||
/// Checks if the `lhs` is always `true` for a signal until `rhs` becomes `true`.
|
/// Checks if the `lhs` is always `true` for a signal until `rhs` becomes `true`.
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "({}) U{} ({})", lhs, interval, rhs)]
|
||||||
pub struct Until {
|
pub struct Until {
|
||||||
/// LHS to `lhs Until rhs`
|
/// LHS to `lhs Until rhs`
|
||||||
pub lhs: Box<BoolExpr>,
|
pub lhs: Box<BoolExpr>,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
//! Numeric expression types
|
//! Numeric expression types
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
use super::{AnyExpr, NumExpr};
|
use super::{AnyExpr, NumExpr};
|
||||||
|
|
||||||
|
|
@ -37,22 +38,23 @@ macro_rules! impl_num_expr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A signed integer literal
|
/// A signed integer literal
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
pub struct IntLit(pub i64);
|
pub struct IntLit(pub i64);
|
||||||
impl_num_expr!(IntLit);
|
impl_num_expr!(IntLit);
|
||||||
|
|
||||||
/// An unsigned integer literal
|
/// An unsigned integer literal
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
pub struct UIntLit(pub u64);
|
pub struct UIntLit(pub u64);
|
||||||
impl_num_expr!(UIntLit);
|
impl_num_expr!(UIntLit);
|
||||||
|
|
||||||
/// A floating point literal
|
/// A floating point literal
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
pub struct FloatLit(pub f64);
|
pub struct FloatLit(pub f64);
|
||||||
impl_num_expr!(FloatLit);
|
impl_num_expr!(FloatLit);
|
||||||
|
|
||||||
/// A signed integer variable
|
/// A signed integer variable
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "{}", name)]
|
||||||
pub struct IntVar {
|
pub struct IntVar {
|
||||||
/// Name of the variable
|
/// Name of the variable
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
@ -60,7 +62,8 @@ pub struct IntVar {
|
||||||
impl_num_expr!(IntVar);
|
impl_num_expr!(IntVar);
|
||||||
|
|
||||||
/// A unsigned integer variable
|
/// A unsigned integer variable
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "{}", name)]
|
||||||
pub struct UIntVar {
|
pub struct UIntVar {
|
||||||
/// Name of the variable
|
/// Name of the variable
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
@ -68,7 +71,8 @@ pub struct UIntVar {
|
||||||
impl_num_expr!(UIntVar);
|
impl_num_expr!(UIntVar);
|
||||||
|
|
||||||
/// A floating point number variable
|
/// A floating point number variable
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "{}", name)]
|
||||||
pub struct FloatVar {
|
pub struct FloatVar {
|
||||||
/// Name of the variable
|
/// Name of the variable
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
@ -76,7 +80,8 @@ pub struct FloatVar {
|
||||||
impl_num_expr!(FloatVar);
|
impl_num_expr!(FloatVar);
|
||||||
|
|
||||||
/// Numeric negation of a numeric expression
|
/// Numeric negation of a numeric expression
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "-({})", arg)]
|
||||||
pub struct Neg {
|
pub struct Neg {
|
||||||
/// Numeric expression being negated
|
/// Numeric expression being negated
|
||||||
pub arg: Box<NumExpr>,
|
pub arg: Box<NumExpr>,
|
||||||
|
|
@ -84,7 +89,8 @@ pub struct Neg {
|
||||||
impl_num_expr!(Neg, arg);
|
impl_num_expr!(Neg, arg);
|
||||||
|
|
||||||
/// Arithmetic addition of a list of numeric expressions
|
/// Arithmetic addition of a list of numeric expressions
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "({})", r#"args.iter().map(ToString::to_string).join(" + ")"#r)]
|
||||||
pub struct Add {
|
pub struct Add {
|
||||||
/// List of expressions being added
|
/// List of expressions being added
|
||||||
pub args: Vec<NumExpr>,
|
pub args: Vec<NumExpr>,
|
||||||
|
|
@ -92,7 +98,8 @@ pub struct Add {
|
||||||
impl_num_expr!(Add, [args]);
|
impl_num_expr!(Add, [args]);
|
||||||
|
|
||||||
/// Subtraction of two numbers
|
/// Subtraction of two numbers
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "({} - {})", lhs, rhs)]
|
||||||
pub struct Sub {
|
pub struct Sub {
|
||||||
/// LHS to the expression `lhs - rhs`
|
/// LHS to the expression `lhs - rhs`
|
||||||
pub lhs: Box<NumExpr>,
|
pub lhs: Box<NumExpr>,
|
||||||
|
|
@ -102,7 +109,8 @@ pub struct Sub {
|
||||||
impl_num_expr!(Sub, lhs, rhs);
|
impl_num_expr!(Sub, lhs, rhs);
|
||||||
|
|
||||||
/// Arithmetic multiplication of a list of numeric expressions
|
/// Arithmetic multiplication of a list of numeric expressions
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "({})", r#"args.iter().map(ToString::to_string).join(" * ")"#r)]
|
||||||
pub struct Mul {
|
pub struct Mul {
|
||||||
/// List of expressions being multiplied
|
/// List of expressions being multiplied
|
||||||
pub args: Vec<NumExpr>,
|
pub args: Vec<NumExpr>,
|
||||||
|
|
@ -110,7 +118,8 @@ pub struct Mul {
|
||||||
impl_num_expr!(Mul, [args]);
|
impl_num_expr!(Mul, [args]);
|
||||||
|
|
||||||
/// Divide two expressions `dividend / divisor`
|
/// Divide two expressions `dividend / divisor`
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "({} / {})", dividend, divisor)]
|
||||||
pub struct Div {
|
pub struct Div {
|
||||||
/// The dividend
|
/// The dividend
|
||||||
pub dividend: Box<NumExpr>,
|
pub dividend: Box<NumExpr>,
|
||||||
|
|
@ -120,7 +129,8 @@ pub struct Div {
|
||||||
impl_num_expr!(Div, dividend, divisor);
|
impl_num_expr!(Div, dividend, divisor);
|
||||||
|
|
||||||
/// The absolute value of an expression
|
/// The absolute value of an expression
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr, derive_more::Display)]
|
||||||
|
#[display(fmt = "abs({})", arg)]
|
||||||
pub struct Abs {
|
pub struct Abs {
|
||||||
/// Argument to `abs`
|
/// Argument to `abs`
|
||||||
pub arg: Box<NumExpr>,
|
pub arg: Box<NumExpr>,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue