Add flattening of operator chains when building operator tree
Relates to #44
This commit is contained in:
parent
1721e163b0
commit
eb5c6e99bd
@ -7,6 +7,10 @@ use crate::{context::Context, error::*, value::Value};
|
|||||||
mod display;
|
mod display;
|
||||||
|
|
||||||
pub trait Operator: Debug + Display {
|
pub trait Operator: Debug + Display {
|
||||||
|
/// A numeric id to compare operator types.
|
||||||
|
// Make this a const fn once #57563 is resolved
|
||||||
|
fn id(&self) -> i32;
|
||||||
|
|
||||||
/// Returns the precedence of the operator.
|
/// Returns the precedence of the operator.
|
||||||
/// A high precedence means that the operator has priority to be deeper in the tree.
|
/// A high precedence means that the operator has priority to be deeper in the tree.
|
||||||
// Make this a const fn once #57563 is resolved
|
// Make this a const fn once #57563 is resolved
|
||||||
@ -20,6 +24,12 @@ pub trait Operator: Debug + Display {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if chains of this operator should be flattened into one operator with many arguments.
|
||||||
|
// Make this a const fn once #57563 is resolved
|
||||||
|
fn is_flatten_chains(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// True if this operator is a leaf, meaning it accepts no arguments.
|
/// True if this operator is a leaf, meaning it accepts no arguments.
|
||||||
// Make this a const fn once #57563 is resolved
|
// Make this a const fn once #57563 is resolved
|
||||||
fn is_leaf(&self) -> bool {
|
fn is_leaf(&self) -> bool {
|
||||||
@ -123,6 +133,10 @@ impl FunctionIdentifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for RootNode {
|
impl Operator for RootNode {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
200
|
200
|
||||||
}
|
}
|
||||||
@ -141,6 +155,10 @@ impl Operator for RootNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Add {
|
impl Operator for Add {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
2
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
95
|
95
|
||||||
}
|
}
|
||||||
@ -178,6 +196,10 @@ impl Operator for Add {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Sub {
|
impl Operator for Sub {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
3
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
95
|
95
|
||||||
}
|
}
|
||||||
@ -210,6 +232,10 @@ impl Operator for Sub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Neg {
|
impl Operator for Neg {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
4
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
110
|
110
|
||||||
}
|
}
|
||||||
@ -236,6 +262,10 @@ impl Operator for Neg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Mul {
|
impl Operator for Mul {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
5
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
100
|
100
|
||||||
}
|
}
|
||||||
@ -268,6 +298,10 @@ impl Operator for Mul {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Div {
|
impl Operator for Div {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
6
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
100
|
100
|
||||||
}
|
}
|
||||||
@ -300,6 +334,10 @@ impl Operator for Div {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Mod {
|
impl Operator for Mod {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
7
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
100
|
100
|
||||||
}
|
}
|
||||||
@ -332,6 +370,10 @@ impl Operator for Mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Exp {
|
impl Operator for Exp {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
8
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
120
|
120
|
||||||
}
|
}
|
||||||
@ -355,6 +397,10 @@ impl Operator for Exp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Eq {
|
impl Operator for Eq {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
9
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
80
|
80
|
||||||
}
|
}
|
||||||
@ -375,6 +421,10 @@ impl Operator for Eq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Neq {
|
impl Operator for Neq {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
10
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
80
|
80
|
||||||
}
|
}
|
||||||
@ -395,6 +445,10 @@ impl Operator for Neq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Gt {
|
impl Operator for Gt {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
11
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
80
|
80
|
||||||
}
|
}
|
||||||
@ -431,6 +485,10 @@ impl Operator for Gt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Lt {
|
impl Operator for Lt {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
12
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
80
|
80
|
||||||
}
|
}
|
||||||
@ -467,6 +525,10 @@ impl Operator for Lt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Geq {
|
impl Operator for Geq {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
13
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
80
|
80
|
||||||
}
|
}
|
||||||
@ -503,6 +565,10 @@ impl Operator for Geq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Leq {
|
impl Operator for Leq {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
14
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
80
|
80
|
||||||
}
|
}
|
||||||
@ -539,6 +605,10 @@ impl Operator for Leq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for And {
|
impl Operator for And {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
15
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
75
|
75
|
||||||
}
|
}
|
||||||
@ -561,6 +631,10 @@ impl Operator for And {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Or {
|
impl Operator for Or {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
16
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
70
|
70
|
||||||
}
|
}
|
||||||
@ -583,6 +657,10 @@ impl Operator for Or {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Not {
|
impl Operator for Not {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
17
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
110
|
110
|
||||||
}
|
}
|
||||||
@ -604,17 +682,26 @@ impl Operator for Not {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Tuple {
|
impl Operator for Tuple {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
18
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
40
|
40
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max_argument_amount(&self) -> Option<usize> {
|
fn max_argument_amount(&self) -> Option<usize> {
|
||||||
Some(2)
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval(&self, arguments: &[Value], _context: &Context) -> EvalexprResult<Value> {
|
fn eval(&self, arguments: &[Value], _context: &Context) -> EvalexprResult<Value> {
|
||||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
if arguments.len() < 2 {
|
||||||
if let Value::Tuple(tuple) = &arguments[0] {
|
return Err(EvalexprError::wrong_operator_argument_amount(arguments.len(), 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::Tuple(arguments.iter().cloned().collect()))
|
||||||
|
|
||||||
|
/*if let Value::Tuple(tuple) = &arguments[0] {
|
||||||
let mut tuple = tuple.clone();
|
let mut tuple = tuple.clone();
|
||||||
if let Value::Tuple(tuple2) = &arguments[1] {
|
if let Value::Tuple(tuple2) = &arguments[1] {
|
||||||
tuple.extend(tuple2.iter().cloned());
|
tuple.extend(tuple2.iter().cloned());
|
||||||
@ -633,11 +720,15 @@ impl Operator for Tuple {
|
|||||||
arguments[1].clone(),
|
arguments[1].clone(),
|
||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Assign {
|
impl Operator for Assign {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
19
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
50
|
50
|
||||||
}
|
}
|
||||||
@ -664,10 +755,18 @@ impl Operator for Assign {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Chain {
|
impl Operator for Chain {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
20
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_flatten_chains(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn max_argument_amount(&self) -> Option<usize> {
|
fn max_argument_amount(&self) -> Option<usize> {
|
||||||
Some(2)
|
Some(2)
|
||||||
}
|
}
|
||||||
@ -682,6 +781,10 @@ impl Operator for Chain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Const {
|
impl Operator for Const {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
21
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
200
|
200
|
||||||
}
|
}
|
||||||
@ -698,6 +801,10 @@ impl Operator for Const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for VariableIdentifier {
|
impl Operator for VariableIdentifier {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
22
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
200
|
200
|
||||||
}
|
}
|
||||||
@ -722,6 +829,10 @@ impl Operator for VariableIdentifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for FunctionIdentifier {
|
impl Operator for FunctionIdentifier {
|
||||||
|
fn id(&self) -> i32 {
|
||||||
|
23
|
||||||
|
}
|
||||||
|
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
190
|
190
|
||||||
}
|
}
|
||||||
|
@ -337,6 +337,9 @@ impl Node {
|
|||||||
.last_mut()
|
.last_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert_back_prioritized(node, false)
|
.insert_back_prioritized(node, false)
|
||||||
|
} else if self.children.last().unwrap().operator().id() == node.operator().id() && node.operator().is_flatten_chains() && !self.children.last().unwrap().has_enough_children() {
|
||||||
|
// The operators will be chained together, and the next value will be added to this nodes last child.
|
||||||
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
if node.operator().is_leaf() {
|
if node.operator().is_leaf() {
|
||||||
return Err(EvalexprError::AppendedToLeafNode);
|
return Err(EvalexprError::AppendedToLeafNode);
|
||||||
|
@ -194,6 +194,10 @@ impl From<Value> for EvalexprResult<Value> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<()> for Value {
|
||||||
|
fn from(_: ()) -> Self { Value::Empty }
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use value::{TupleType, Value};
|
use value::{TupleType, Value};
|
||||||
|
@ -614,3 +614,17 @@ fn test_serde() {
|
|||||||
assert_eq!(manual_tree.eval(), serde_tree.eval());
|
assert_eq!(manual_tree.eval(), serde_tree.eval());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tuple_definitions() {
|
||||||
|
assert_eq!(eval_empty("()"), Ok(()));
|
||||||
|
assert_eq!(eval_int("(3)"), Ok(3));
|
||||||
|
assert_eq!(eval_tuple("(3, 4)"), Ok(vec![Value::from(3), Value::from(4)]));
|
||||||
|
assert_eq!(eval_tuple("2, (5, 6)"), Ok(vec![Value::from(2), Value::from(vec![Value::from(5), Value::from(6)])]));
|
||||||
|
assert_eq!(eval_tuple("1, 2"), Ok(vec![Value::from(1), Value::from(2)]));
|
||||||
|
assert_eq!(eval_tuple("1, 2, 3, 4"), Ok(vec![Value::from(1), Value::from(2), Value::from(3), Value::from(4)]));
|
||||||
|
assert_eq!(eval_tuple("(1, 2, 3), 5, 6, (true, false, 0)"), Ok(vec![Value::from(vec![Value::from(1), Value::from(2), Value::from(3)]), Value::from(5), Value::from(6), Value::from(vec![Value::from(true), Value::from(false), Value::from(0)])]));
|
||||||
|
assert_eq!(eval_tuple("1, (2)"), Ok(vec![Value::from(1), Value::from(2)]));
|
||||||
|
assert_eq!(eval_tuple("1, ()"), Ok(vec![Value::from(1), Value::from(())]));
|
||||||
|
assert_eq!(eval_tuple("1, ((2))"), Ok(vec![Value::from(1), Value::from(2)]));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user