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> { fn run(self, context: &Context) -> Result<Action, RuntimeError> {
let value = self.function.run(_context)?.as_value()?; let value = self.function.run(context)?.as_value()?;
let function = value.as_function()?; let function = value.as_function()?;
let mut arguments = Vec::with_capacity(self.arguments.len()); let mut arguments = Vec::with_capacity(self.arguments.len());
for expression in self.arguments { for expression in self.arguments {
let value = expression.run(_context)?.as_value()?; let value = expression.run(context)?.as_value()?;
arguments.push(value); arguments.push(value);
} }
let function_context = Context::new(); let function_context = Context::with_data_from(context)?;
function.call(arguments, function_context) function.call(arguments, function_context)
} }

View File

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

View File

@ -78,7 +78,7 @@ impl AbstractTree for ValueNode {
body, body,
} = self } = self
{ {
let function_context = Context::new(); let function_context = Context::with_types_from(context)?;
for (identifier, r#type) in parameters { for (identifier, r#type) in parameters {
function_context.set_type(identifier.clone(), r#type.clone())?; 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( pub fn get_data(
&self, &self,
identifier: &Identifier, identifier: &Identifier,