Fix if/else type checking and recursion test
This commit is contained in:
parent
f544bd008e
commit
cabbf8821f
@ -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)
|
||||
}
|
||||
|
@ -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)? {
|
||||
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)?;
|
||||
}
|
||||
|
||||
fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
if let Type::Boolean = self.if_expression.expected_type(_context)? {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ValidationError::ExpectedBoolean)
|
||||
|
@ -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())?;
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user