2023-10-06 17:32:58 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use tree_sitter::Node;
|
|
|
|
|
2024-01-06 13:11:09 +00:00
|
|
|
use crate::{AbstractTree, Error, Expression, Format, Map, MathOperator, Result, Type, Value};
|
2023-10-06 17:32:58 +00:00
|
|
|
|
2023-12-06 19:13:22 +00:00
|
|
|
/// Abstract representation of a math operation.
|
|
|
|
///
|
|
|
|
/// Dust currently supports the four basic operations and the modulo (or
|
|
|
|
/// remainder) operator.
|
2023-10-06 17:32:58 +00:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
|
|
|
pub struct Math {
|
|
|
|
left: Expression,
|
|
|
|
operator: MathOperator,
|
|
|
|
right: Expression,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AbstractTree for Math {
|
2023-11-30 03:54:46 +00:00
|
|
|
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> {
|
2023-12-30 02:15:03 +00:00
|
|
|
Error::expect_syntax_node(source, "math", node)?;
|
|
|
|
|
2023-10-06 17:32:58 +00:00
|
|
|
let left_node = node.child(0).unwrap();
|
2023-11-30 03:54:46 +00:00
|
|
|
let left = Expression::from_syntax_node(source, left_node, context)?;
|
2023-10-06 17:32:58 +00:00
|
|
|
|
2024-01-06 13:11:09 +00:00
|
|
|
let operator_node = node.child(1).unwrap();
|
|
|
|
let operator = MathOperator::from_syntax_node(source, operator_node, context)?;
|
2023-10-06 17:32:58 +00:00
|
|
|
|
|
|
|
let right_node = node.child(2).unwrap();
|
2023-11-30 03:54:46 +00:00
|
|
|
let right = Expression::from_syntax_node(source, right_node, context)?;
|
2023-10-06 17:32:58 +00:00
|
|
|
|
|
|
|
Ok(Math {
|
|
|
|
left,
|
|
|
|
operator,
|
|
|
|
right,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-11-30 00:23:42 +00:00
|
|
|
fn run(&self, source: &str, context: &Map) -> Result<Value> {
|
2023-10-13 23:56:57 +00:00
|
|
|
let left = self.left.run(source, context)?;
|
|
|
|
let right = self.right.run(source, context)?;
|
|
|
|
let value = match self.operator {
|
|
|
|
MathOperator::Add => left + right,
|
|
|
|
MathOperator::Subtract => left - right,
|
|
|
|
MathOperator::Multiply => left * right,
|
|
|
|
MathOperator::Divide => left / right,
|
|
|
|
MathOperator::Modulo => left % right,
|
|
|
|
}?;
|
2023-10-06 17:32:58 +00:00
|
|
|
|
2023-10-13 23:56:57 +00:00
|
|
|
Ok(value)
|
2023-10-06 17:32:58 +00:00
|
|
|
}
|
2023-11-30 00:23:42 +00:00
|
|
|
|
2023-12-05 22:08:22 +00:00
|
|
|
fn expected_type(&self, context: &Map) -> Result<Type> {
|
2023-11-30 03:02:55 +00:00
|
|
|
self.left.expected_type(context)
|
2023-11-30 00:23:42 +00:00
|
|
|
}
|
2023-10-06 17:32:58 +00:00
|
|
|
}
|
|
|
|
|
2024-01-06 13:11:09 +00:00
|
|
|
impl Format for Math {
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|