Fix if/else type checking and recursion test

This commit is contained in:
Jeff 2024-03-10 14:48:53 -04:00
parent f544bd008e
commit cabbf8821f
4 changed files with 37 additions and 8 deletions

View File

@ -37,18 +37,18 @@ impl AbstractTree for FunctionCall {
}
}
fn run(self, _context: &Context) -> Result<Action, RuntimeError> {
let value = self.function.run(_context)?.as_value()?;
fn run(self, context: &Context) -> Result<Action, RuntimeError> {
let value = self.function.run(context)?.as_value()?;
let function = value.as_function()?;
let mut arguments = Vec::with_capacity(self.arguments.len());
for expression in self.arguments {
let value = expression.run(_context)?.as_value()?;
let value = expression.run(context)?.as_value()?;
arguments.push(value);
}
let function_context = Context::new();
let function_context = Context::with_data_from(context)?;
function.call(arguments, function_context)
}

View File

@ -24,11 +24,18 @@ impl IfElse {
impl AbstractTree for IfElse {
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
Ok(Type::None)
self.if_block.expected_type(_context)
}
fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
if let Type::Boolean = self.if_expression.expected_type(_context)? {
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)?;
}
Ok(())
} else {
Err(ValidationError::ExpectedBoolean)

View File

@ -78,7 +78,7 @@ impl AbstractTree for ValueNode {
body,
} = self
{
let function_context = Context::new();
let function_context = Context::with_types_from(context)?;
for (identifier, r#type) in parameters {
function_context.set_type(identifier.clone(), r#type.clone())?;

View File

@ -33,6 +33,28 @@ impl Context {
}
}
pub fn with_types_from(other: &Context) -> Result<Self, RwLockPoisonError> {
let mut new_data = BTreeMap::new();
for (identifier, value_data) in other.inner.read()?.iter() {
if let ValueData::Type(_) = value_data {
new_data.insert(identifier.clone(), value_data.clone());
}
}
Ok(Self::with_data(new_data))
}
pub fn with_data_from(other: &Context) -> Result<Self, RwLockPoisonError> {
let mut new_data = BTreeMap::new();
for (identifier, value_data) in other.inner.read()?.iter() {
new_data.insert(identifier.clone(), value_data.clone());
}
Ok(Self::with_data(new_data))
}
pub fn get_data(
&self,
identifier: &Identifier,