dust/src/abstract_tree/if_else.rs

104 lines
2.8 KiB
Rust
Raw Normal View History

2024-03-08 19:01:05 +00:00
use crate::{
context::Context,
error::{RuntimeError, ValidationError},
};
2024-03-09 20:17:19 +00:00
use super::{AbstractTree, Action, Block, Expression, Type};
2024-03-08 19:01:05 +00:00
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
2024-03-08 21:14:47 +00:00
pub struct IfElse {
if_expression: Expression,
2024-03-09 20:17:19 +00:00
if_block: Block,
else_block: Option<Block>,
2024-03-08 19:01:05 +00:00
}
2024-03-08 21:14:47 +00:00
impl IfElse {
2024-03-09 20:17:19 +00:00
pub fn new(if_expression: Expression, if_block: Block, else_block: Option<Block>) -> Self {
2024-03-08 19:01:05 +00:00
Self {
if_expression,
2024-03-09 20:17:19 +00:00
if_block,
else_block,
2024-03-08 19:01:05 +00:00
}
}
}
2024-03-08 21:14:47 +00:00
impl AbstractTree for IfElse {
2024-03-08 19:01:05 +00:00
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
self.if_block.expected_type(_context)
2024-03-08 19:01:05 +00:00
}
fn validate(&self, context: &Context) -> Result<(), ValidationError> {
if let Type::Boolean = self.if_expression.expected_type(context)? {
if let Some(else_block) = &self.else_block {
let expected = self.if_block.expected_type(context)?;
let actual = else_block.expected_type(context)?;
expected.check(&actual)?;
}
2024-03-08 19:29:53 +00:00
Ok(())
} else {
Err(ValidationError::ExpectedBoolean)
}
2024-03-08 19:01:05 +00:00
}
fn run(self, _context: &Context) -> Result<Action, RuntimeError> {
let if_boolean = self
.if_expression
.run(_context)?
.as_return_value()?
.as_boolean()?;
if if_boolean {
2024-03-09 20:17:19 +00:00
self.if_block.run(_context)
} else if let Some(else_statement) = self.else_block {
2024-03-08 19:01:05 +00:00
else_statement.run(_context)
} else {
Ok(Action::None)
}
}
}
#[cfg(test)]
mod tests {
use crate::{
2024-03-09 20:17:19 +00:00
abstract_tree::{Action, Statement, ValueNode},
2024-03-08 19:01:05 +00:00
context::Context,
Value,
};
use super::*;
#[test]
fn simple_if() {
assert_eq!(
IfElse::new(
Expression::Value(ValueNode::Boolean(true)),
2024-03-09 20:17:19 +00:00
Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::String("foo".to_string())
)),]),
2024-03-08 19:01:05 +00:00
None
)
.run(&Context::new()),
Ok(Action::Return(Value::string("foo".to_string())))
2024-03-08 19:01:05 +00:00
)
}
#[test]
fn simple_if_else() {
assert_eq!(
IfElse::new(
Expression::Value(ValueNode::Boolean(false)),
2024-03-09 20:17:19 +00:00
Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::String("foo".to_string())
)),]),
Some(Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::String("bar".to_string())
))]))
2024-03-08 19:01:05 +00:00
)
.run(&Context::new()),
Ok(Action::Return(Value::string("bar".to_string())))
2024-03-08 19:01:05 +00:00
)
}
}