1
0
dust/src/abstract_tree/logic.rs

91 lines
3.1 KiB
Rust
Raw Normal View History

2023-10-06 17:32:58 +00:00
use serde::{Deserialize, Serialize};
2024-01-10 20:03:52 +00:00
use crate::{
2024-01-31 18:51:48 +00:00
error::{RuntimeError, SyntaxError, ValidationError},
2024-02-01 00:35:27 +00:00
AbstractTree, Expression, Format, LogicOperator, Map, SyntaxNode, Type, Value,
2024-01-10 20:03:52 +00:00
};
2023-10-06 17:32:58 +00:00
2023-12-06 19:13:22 +00:00
/// Abstract representation of a logic expression.
2023-10-06 17:32:58 +00:00
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Logic {
left: Expression,
operator: LogicOperator,
right: Expression,
}
impl AbstractTree for Logic {
2024-01-31 18:51:48 +00:00
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
2024-02-01 00:35:27 +00:00
SyntaxError::expect_syntax_node(source, "logic", node)?;
2023-12-30 02:15:03 +00:00
2023-12-02 03:16:50 +00:00
let first_node = node.child(0).unwrap();
let (left_node, operator_node, right_node) = {
if first_node.is_named() {
2024-01-06 13:11:09 +00:00
(first_node, node.child(1).unwrap(), node.child(2).unwrap())
2023-12-02 03:16:50 +00:00
} else {
(
node.child(1).unwrap(),
2024-01-06 13:11:09 +00:00
node.child(2).unwrap(),
2023-12-02 03:16:50 +00:00
node.child(3).unwrap(),
)
}
};
2024-01-10 20:03:52 +00:00
let left = Expression::from_syntax(left_node, source, context)?;
let operator = LogicOperator::from_syntax(operator_node, source, context)?;
let right = Expression::from_syntax(right_node, source, context)?;
2023-10-06 17:32:58 +00:00
Ok(Logic {
left,
operator,
right,
})
}
2024-01-31 18:51:48 +00:00
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
Ok(Type::Boolean)
}
2024-02-01 01:52:34 +00:00
fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> {
self.left.validate(_source, _context)?;
self.right.validate(_source, _context)
2024-01-31 18:51:48 +00:00
}
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
2023-10-10 17:29:11 +00:00
let left = self.left.run(source, context)?;
let right = self.right.run(source, context)?;
2023-10-09 19:54:47 +00:00
let result = match self.operator {
LogicOperator::Equal => {
if let (Ok(left_num), Ok(right_num)) = (left.as_number(), right.as_number()) {
left_num == right_num
} else {
left == right
}
}
2023-10-28 14:28:43 +00:00
LogicOperator::NotEqual => {
if let (Ok(left_num), Ok(right_num)) = (left.as_number(), right.as_number()) {
left_num != right_num
} else {
left != right
}
}
2023-10-09 19:54:47 +00:00
LogicOperator::And => left.as_boolean()? && right.as_boolean()?,
LogicOperator::Or => left.as_boolean()? || right.as_boolean()?,
LogicOperator::Greater => left > right,
LogicOperator::Less => left < right,
LogicOperator::GreaterOrEqual => left >= right,
2024-01-06 10:00:36 +00:00
LogicOperator::LessOrEqual => left <= right,
2023-10-06 17:32:58 +00:00
};
2023-10-09 19:54:47 +00:00
Ok(Value::Boolean(result))
2023-10-06 17:32:58 +00:00
}
}
2024-01-06 13:11:09 +00:00
impl Format for Logic {
fn format(&self, output: &mut String, indent_level: u8) {
self.left.format(output, indent_level);
output.push(' ');
self.operator.format(output, indent_level);
output.push(' ');
self.right.format(output, indent_level);
2024-01-06 10:00:36 +00:00
}
2023-10-06 17:32:58 +00:00
}