dust/src/abstract_tree/logic.rs

80 lines
2.6 KiB
Rust
Raw Normal View History

2023-10-06 17:32:58 +00:00
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Error, Expression, Result, Value, VariableMap};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Logic {
left: Expression,
operator: LogicOperator,
right: Expression,
}
impl AbstractTree for Logic {
2023-10-10 17:29:11 +00:00
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
2023-10-06 17:32:58 +00:00
let left_node = node.child(0).unwrap();
2023-10-10 17:29:11 +00:00
let left = Expression::from_syntax_node(source, left_node)?;
2023-10-06 17:32:58 +00:00
let operator_node = node.child(1).unwrap().child(0).unwrap();
let operator = match operator_node.kind() {
"==" => LogicOperator::Equal,
"&&" => LogicOperator::And,
"||" => LogicOperator::Or,
2023-10-09 19:54:47 +00:00
">" => LogicOperator::Greater,
"<" => LogicOperator::Less,
">=" => LogicOperator::GreaterOrEqual,
"<=" => LogicOperator::LessOrEqaul,
2023-10-06 17:32:58 +00:00
_ => {
2023-10-10 17:29:11 +00:00
return Err(Error::UnexpectedSyntaxNode {
2023-10-14 00:05:45 +00:00
expected: "==, && ||, >, <, >= or <=",
2023-10-06 17:32:58 +00:00
actual: operator_node.kind(),
location: operator_node.start_position(),
relevant_source: source[operator_node.byte_range()].to_string(),
})
}
};
let right_node = node.child(2).unwrap();
2023-10-10 17:29:11 +00:00
let right = Expression::from_syntax_node(source, right_node)?;
2023-10-06 17:32:58 +00:00
Ok(Logic {
left,
operator,
right,
})
}
2023-10-10 17:29:11 +00:00
fn run(&self, source: &str, context: &mut VariableMap) -> Result<Value> {
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
}
}
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,
LogicOperator::LessOrEqaul => 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
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub enum LogicOperator {
Equal,
And,
Or,
2023-10-09 19:54:47 +00:00
Greater,
Less,
GreaterOrEqual,
LessOrEqaul,
2023-10-06 17:32:58 +00:00
}