2023-10-07 02:45:36 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2023-10-10 17:29:11 +00:00
|
|
|
use tree_sitter::Node;
|
2023-10-07 02:45:36 +00:00
|
|
|
|
2023-12-05 22:08:22 +00:00
|
|
|
use crate::{AbstractTree, Block, Expression, Map, Result, Type, Value};
|
2023-10-07 02:45:36 +00:00
|
|
|
|
2023-12-06 19:13:22 +00:00
|
|
|
/// Abstract representation of a while loop.
|
|
|
|
///
|
|
|
|
/// While executes its block repeatedly until its expression evaluates to true.
|
2023-10-07 02:45:36 +00:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
|
|
|
pub struct While {
|
|
|
|
expression: Expression,
|
2023-10-31 17:04:22 +00:00
|
|
|
block: Block,
|
2023-10-07 02:45:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl AbstractTree for While {
|
2023-11-30 03:54:46 +00:00
|
|
|
fn from_syntax_node(source: &str, node: Node, context: &Map) -> crate::Result<Self> {
|
2023-10-07 02:45:36 +00:00
|
|
|
debug_assert_eq!("while", node.kind());
|
|
|
|
|
|
|
|
let expression_node = node.child(1).unwrap();
|
2023-11-30 03:54:46 +00:00
|
|
|
let expression = Expression::from_syntax_node(source, expression_node, context)?;
|
2023-10-07 02:45:36 +00:00
|
|
|
|
2023-10-31 17:04:22 +00:00
|
|
|
let block_node = node.child(2).unwrap();
|
2023-11-30 03:54:46 +00:00
|
|
|
let block = Block::from_syntax_node(source, block_node, context)?;
|
2023-10-07 02:45:36 +00:00
|
|
|
|
2023-10-31 17:04:22 +00:00
|
|
|
Ok(While { expression, block })
|
2023-10-07 02:45:36 +00:00
|
|
|
}
|
|
|
|
|
2023-11-30 00:23:42 +00:00
|
|
|
fn run(&self, source: &str, context: &Map) -> Result<Value> {
|
2023-10-10 17:29:11 +00:00
|
|
|
while self.expression.run(source, context)?.as_boolean()? {
|
2023-10-31 17:04:22 +00:00
|
|
|
self.block.run(source, context)?;
|
2023-10-07 02:45:36 +00:00
|
|
|
}
|
|
|
|
|
2023-12-22 20:02:22 +00:00
|
|
|
Ok(Value::Option(None))
|
2023-10-07 02:45:36 +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 00:23:42 +00:00
|
|
|
self.block.expected_type(context)
|
|
|
|
}
|
2023-10-07 02:45:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2023-12-22 20:02:22 +00:00
|
|
|
use crate::{evaluate, Value};
|
2023-10-07 02:45:36 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn evalualate_while_loop() {
|
2023-12-22 20:02:22 +00:00
|
|
|
assert_eq!(evaluate("while false { 'foo' }"), Ok(Value::Option(None)))
|
2023-10-07 02:45:36 +00:00
|
|
|
}
|
|
|
|
}
|