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> {
|
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)
|
||||||
}
|
}
|
||||||
|
@ -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> {
|
||||||
|
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(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ValidationError::ExpectedBoolean)
|
Err(ValidationError::ExpectedBoolean)
|
||||||
|
@ -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())?;
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user