63 lines
1.8 KiB
Rust
63 lines
1.8 KiB
Rust
use std::rc::Rc;
|
|
|
|
use rug::{Float, ops::Pow};
|
|
|
|
use super::{Environment, Node, NodeEnum, Precedence, constant::Constant};
|
|
|
|
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
|
pub struct Exponent {
|
|
left: Rc<NodeEnum>,
|
|
right: Rc<NodeEnum>,
|
|
}
|
|
|
|
impl Node for Exponent {
|
|
fn evaluate(&self, env: &mut super::Environment) -> Result<Rc<super::NodeEnum>, String> {
|
|
let evaluated_left = self.left.evaluate(env)?;
|
|
let evaluated_right = self.right.evaluate(env)?;
|
|
|
|
match (evaluated_left.as_ref(), evaluated_right.as_ref()) {
|
|
(NodeEnum::Constant(a), NodeEnum::Constant(b)) => Ok(Rc::new(
|
|
Constant::new(Float::with_val_64(
|
|
env.get_float_precision(),
|
|
a.get_value().pow(b.get_value()),
|
|
))
|
|
.into(),
|
|
)),
|
|
|
|
_ => Ok(Self::new(evaluated_left, evaluated_right)),
|
|
}
|
|
}
|
|
|
|
fn as_string(&self, env: Option<&Environment>) -> String {
|
|
let left_string = if self.left.precedence() <= self.precedence() {
|
|
format!("({})", self.left.as_string(env))
|
|
} else {
|
|
self.left.as_string(env)
|
|
};
|
|
let right_string = if self.right.precedence() <= self.precedence() {
|
|
format!("({})", self.right.as_string(env))
|
|
} else {
|
|
self.right.as_string(env)
|
|
};
|
|
format!("{}^{}", left_string, right_string)
|
|
}
|
|
|
|
fn precedence(&self) -> Precedence {
|
|
Precedence::Exponent
|
|
}
|
|
}
|
|
|
|
impl Exponent {
|
|
pub fn new(left: Rc<NodeEnum>, right: Rc<NodeEnum>) -> Rc<NodeEnum> {
|
|
Rc::new(Self { left, right }.into())
|
|
}
|
|
|
|
pub fn get_left(&self) -> &Rc<NodeEnum> {
|
|
&self.left
|
|
}
|
|
|
|
pub fn get_right(&self) -> &Rc<NodeEnum> {
|
|
&self.right
|
|
}
|
|
}
|