Fix function contexts
This commit is contained in:
parent
b5b317df95
commit
b1266df835
@ -25,6 +25,12 @@ pub struct Block {
|
|||||||
context: Context,
|
context: Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Block {
|
||||||
|
pub fn context(&self) -> &Context {
|
||||||
|
&self.context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AbstractTree for Block {
|
impl AbstractTree for Block {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "block", node)?;
|
SyntaxError::expect_syntax_node(source, "block", node)?;
|
||||||
|
@ -63,16 +63,15 @@ impl FunctionNode {
|
|||||||
source: &str,
|
source: &str,
|
||||||
outer_context: &Context,
|
outer_context: &Context,
|
||||||
) -> Result<Value, RuntimeError> {
|
) -> Result<Value, RuntimeError> {
|
||||||
let function_context = Context::inherit_from(outer_context)?;
|
|
||||||
let parameter_argument_pairs = self.parameters.iter().zip(arguments.iter());
|
let parameter_argument_pairs = self.parameters.iter().zip(arguments.iter());
|
||||||
|
|
||||||
for (identifier, value) in parameter_argument_pairs {
|
for (identifier, value) in parameter_argument_pairs {
|
||||||
let key = identifier.inner().clone();
|
let key = identifier.inner().clone();
|
||||||
|
|
||||||
function_context.set_value(key, value.clone())?;
|
self.body.context().set_value(key, value.clone())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let return_value = self.body.run(source, &function_context)?;
|
let return_value = self.body.run(source, outer_context)?;
|
||||||
|
|
||||||
Ok(return_value)
|
Ok(return_value)
|
||||||
}
|
}
|
||||||
@ -110,15 +109,14 @@ impl AbstractTree for FunctionNode {
|
|||||||
let return_type_node = node.child(child_count - 2).unwrap();
|
let return_type_node = node.child(child_count - 2).unwrap();
|
||||||
let return_type = TypeSpecification::from_syntax(return_type_node, source, outer_context)?;
|
let return_type = TypeSpecification::from_syntax(return_type_node, source, outer_context)?;
|
||||||
|
|
||||||
let function_context = Context::inherit_from(outer_context)?;
|
let body_node = node.child(child_count - 1).unwrap();
|
||||||
|
let body = Block::from_syntax(body_node, source, &outer_context)?;
|
||||||
|
|
||||||
for (parameter, parameter_type) in parameters.iter().zip(parameter_types.iter()) {
|
for (parameter, parameter_type) in parameters.iter().zip(parameter_types.iter()) {
|
||||||
function_context.set_type(parameter.inner().clone(), parameter_type.clone())?;
|
body.context()
|
||||||
|
.set_type(parameter.inner().clone(), parameter_type.clone())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let body_node = node.child(child_count - 1).unwrap();
|
|
||||||
let body = Block::from_syntax(body_node, source, &function_context)?;
|
|
||||||
|
|
||||||
let r#type = Type::function(parameter_types, return_type.take_inner());
|
let r#type = Type::function(parameter_types, return_type.take_inner());
|
||||||
let syntax_position = node.range().into();
|
let syntax_position = node.range().into();
|
||||||
|
|
||||||
@ -135,18 +133,12 @@ impl AbstractTree for FunctionNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> {
|
fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> {
|
||||||
let function_context = Context::inherit_from(context)?;
|
|
||||||
|
|
||||||
if let Type::Function {
|
if let Type::Function {
|
||||||
parameter_types,
|
parameter_types: _,
|
||||||
return_type,
|
return_type,
|
||||||
} = &self.r#type
|
} = &self.r#type
|
||||||
{
|
{
|
||||||
for (parameter, parameter_type) in self.parameters.iter().zip(parameter_types.iter()) {
|
let actual = self.body.expected_type(context)?;
|
||||||
function_context.set_type(parameter.inner().clone(), parameter_type.clone())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let actual = self.body.expected_type(&function_context)?;
|
|
||||||
|
|
||||||
if !return_type.accepts(&actual) {
|
if !return_type.accepts(&actual) {
|
||||||
return Err(ValidationError::TypeCheck {
|
return Err(ValidationError::TypeCheck {
|
||||||
@ -156,7 +148,7 @@ impl AbstractTree for FunctionNode {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
self.body.validate(source, &function_context)?;
|
self.body.validate(source, context)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user