Add assert and assert_equal tools

This commit is contained in:
Jeff 2023-10-11 12:07:30 -04:00
parent 96c6193799
commit fc92513246
5 changed files with 81 additions and 55 deletions

View File

@ -4,4 +4,4 @@ x = numbers.0
y = numbers.1
z = numbers.2
assert_equal <x + y, z>
(assert_equal x + y, z)

View File

@ -30,6 +30,8 @@ impl AbstractTree for FunctionCall {
"tool" => {
let tool_node = name_node.child(0).unwrap();
let tool = match tool_node.kind() {
"assert" => Tool::Assert,
"assert_equal" => Tool::AssertEqual,
"output" => Tool::Output,
"read" => Tool::Read,
_ => panic!(""),
@ -42,14 +44,14 @@ impl AbstractTree for FunctionCall {
let mut arguments = Vec::new();
let mut current_index = 2;
while current_index < node.child_count() - 1 {
let expression_node = node.child(current_index).unwrap();
let expression = Expression::from_syntax_node(source, expression_node)?;
for index in 2..node.child_count() - 1 {
let child = node.child(index).unwrap();
arguments.push(expression);
if child.is_named() {
let expression = Expression::from_syntax_node(source, child)?;
current_index += 1;
arguments.push(expression);
}
}
Ok(FunctionCall { name, arguments })
@ -59,13 +61,15 @@ impl AbstractTree for FunctionCall {
let identifier = match &self.name {
FunctionName::Identifier(identifier) => identifier,
FunctionName::Tool(tool) => {
let value = self
.arguments
.first()
.map(|expression| expression.run(source, context))
.unwrap_or(Ok(Value::Empty))?;
let mut values = Vec::with_capacity(self.arguments.len());
return tool.run(&value);
for expression in &self.arguments {
let value = expression.run(source, context)?;
values.push(value);
}
return tool.run(&values);
}
};
let key = identifier.inner();

View File

@ -2,24 +2,78 @@ use std::fs::read_to_string;
use serde::{Deserialize, Serialize};
use crate::{Result, Value};
use crate::{Error, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub enum Tool {
Assert,
AssertEqual,
Output,
Read,
}
impl Tool {
pub fn run(&self, value: &Value) -> Result<Value> {
pub fn run(&self, values: &[Value]) -> Result<Value> {
let value = match self {
Tool::Assert => {
if values.len() != 1 {
return Err(Error::ExpectedToolArgumentAmount {
tool_name: "assert",
expected: 1,
actual: values.len(),
});
}
if values[0].as_boolean()? {
Value::Empty
} else {
return Err(Error::AssertEqualFailed {
expected: Value::Boolean(true),
actual: values[0].clone(),
});
}
}
Tool::AssertEqual => {
if values.len() != 2 {
return Err(Error::ExpectedToolArgumentAmount {
tool_name: "assert_equal",
expected: 2,
actual: values.len(),
});
}
if values[0] == values[1] {
Value::Empty
} else {
return Err(Error::AssertEqualFailed {
expected: values[0].clone(),
actual: values[1].clone(),
});
}
}
Tool::Output => {
println!("{value}");
if values.len() != 1 {
return Err(Error::ExpectedToolArgumentAmount {
tool_name: "output",
expected: 1,
actual: values.len(),
});
}
println!("{}", values[0]);
Value::Empty
}
Tool::Read => {
let file_contents = read_to_string(value.as_string()?)?;
if values.len() != 1 {
return Err(Error::ExpectedToolArgumentAmount {
tool_name: "read",
expected: 1,
actual: values.len(),
});
}
let file_contents = read_to_string(values[0].as_string()?)?;
Value::String(file_contents)
}

View File

@ -47,8 +47,8 @@ pub enum Error {
},
/// A function was called with the wrong amount of arguments.
ExpectedFunctionArgumentAmount {
identifier: String,
ExpectedToolArgumentAmount {
tool_name: &'static str,
expected: usize,
actual: usize,
},
@ -283,38 +283,6 @@ impl From<toml::de::Error> for Error {
}
impl Error {
pub(crate) fn _expect_function_argument_amount(
identifier: &str,
actual: usize,
expected: usize,
) -> Result<()> {
if actual == expected {
Ok(())
} else {
Err(Error::ExpectedFunctionArgumentAmount {
identifier: identifier.to_string(),
expected,
actual,
})
}
}
pub(crate) fn _expected_minimum_function_argument_amount(
identifier: &str,
actual: usize,
minimum: usize,
) -> Result<()> {
if actual >= minimum {
Ok(())
} else {
Err(Error::ExpectedAtLeastFunctionArgumentAmount {
identifier: identifier.to_string(),
minimum,
actual,
})
}
}
pub fn type_error(actual: Value, expected: &'static [ValueType]) -> Self {
Error::TypeError { actual, expected }
}
@ -414,13 +382,13 @@ impl fmt::Display for Error {
"An operator expected {} arguments, but got {}.",
expected, actual
),
ExpectedFunctionArgumentAmount {
ExpectedToolArgumentAmount {
tool_name,
expected,
actual,
identifier,
} => write!(
f,
"{identifier} expected {expected} arguments, but got {actual}.",
"{tool_name} expected {expected} arguments, but got {actual}.",
),
ExpectedAtLeastFunctionArgumentAmount {
minimum,

@ -1 +1 @@
Subproject commit a207087ccafb71764b007db88580b35d5e37dae3
Subproject commit c6ec1ff6ea51ce28ee465f9c230e2580fab4c437