Fix function contexts

This commit is contained in:
Jeff 2024-02-11 14:18:53 -05:00
parent b5b317df95
commit b1266df835
2 changed files with 15 additions and 17 deletions

View File

@ -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)?;

View File

@ -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 {