From f820cc7867b0bfefb22f74f5ccb488347e028af5 Mon Sep 17 00:00:00 2001 From: Jeff Date: Sat, 21 Oct 2023 14:11:07 -0400 Subject: [PATCH] Implement tools --- src/abstract_tree/tool.rs | 97 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 7 deletions(-) diff --git a/src/abstract_tree/tool.rs b/src/abstract_tree/tool.rs index 0bffcc0..20e6755 100644 --- a/src/abstract_tree/tool.rs +++ b/src/abstract_tree/tool.rs @@ -6,25 +6,60 @@ use crate::{AbstractTree, Error, Expression, Result, Value, VariableMap}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub enum Tool { Output(Vec), + OutputError(Vec), + + Assert(Vec), + AssertEqual(Vec), + + Length(Expression), } impl AbstractTree for Tool { fn from_syntax_node(source: &str, node: Node) -> Result { - let mut expressions = Vec::new(); + fn parse_expressions(source: &str, node: Node) -> Result> { + let mut expressions = Vec::new(); - for index in 2..node.child_count() - 1 { - let expression_node = node.child(index).unwrap(); - let expression = Expression::from_syntax_node(source, expression_node)?; + for index in 2..node.child_count() - 1 { + let expression_node = node.child(index).unwrap(); + let expression = Expression::from_syntax_node(source, expression_node)?; - expressions.push(expression); + expressions.push(expression); + } + + Ok(expressions) } let tool_node = node.child(1).unwrap(); let tool = match tool_node.kind() { - "output" => Tool::Output(expressions), + "output" => { + let expressions = parse_expressions(source, node)?; + + Tool::Output(expressions) + } + "output_error" => { + let expressions = parse_expressions(source, node)?; + + Tool::OutputError(expressions) + } + "assert" => { + let expressions = parse_expressions(source, node)?; + + Tool::Assert(expressions) + } + "assert_equal" => { + let expressions = parse_expressions(source, node)?; + + Tool::AssertEqual(expressions) + } + "length" => { + let expression_node = node.child(2).unwrap(); + let expression = Expression::from_syntax_node(source, expression_node)?; + + Tool::Length(expression) + } _ => { return Err(Error::UnexpectedSyntaxNode { - expected: "output", + expected: "output, output_error, assert, assert_equal or length", actual: tool_node.kind(), location: tool_node.start_position(), relevant_source: source[tool_node.byte_range()].to_string(), @@ -46,6 +81,54 @@ impl AbstractTree for Tool { Ok(Value::Empty) } + Tool::OutputError(expressions) => { + for expression in expressions { + let value = expression.run(source, context)?; + + eprintln!("{value}"); + } + + Ok(Value::Empty) + } + Tool::Assert(expressions) => { + for expression in expressions { + let value = expression.run(source, context)?; + + if value.as_boolean()? { + continue; + } else { + return Err(Error::AssertFailed); + } + } + + Ok(Value::Empty) + } + Tool::AssertEqual(expressions) => { + let mut prev_value = None; + for expression in expressions { + let value = expression.run(source, context)?; + + if let Some(prev_value) = &prev_value { + if &value == prev_value { + continue; + } else { + return Err(Error::AssertEqualFailed { + expected: prev_value.clone(), + actual: value, + }); + } + } + + prev_value = Some(value); + } + + Ok(Value::Empty) + } + Tool::Length(expression) => { + let length = expression.run(source, context)?.as_list()?.len(); + + Ok(Value::Integer(length as i64)) + } } } }