1
0

Fix function context bug

This commit is contained in:
Jeff 2024-07-11 17:22:30 -04:00
parent 1794f7559c
commit f3fe03a95f
3 changed files with 50 additions and 18 deletions

View File

@ -53,6 +53,7 @@ impl ValueNode {
value_parameters, value_parameters,
return_type, return_type,
body, body,
context: Context::new(),
}) })
} }
} }
@ -157,17 +158,20 @@ impl AbstractNode for ValueNode {
body, body,
type_parameters, type_parameters,
value_parameters, value_parameters,
context: function_context,
}) = self }) = self
{ {
function_context.inherit_variables_from(context)?;
if let Some(type_parameters) = type_parameters { if let Some(type_parameters) = type_parameters {
for identifier in type_parameters { for identifier in type_parameters {
context.set_type( function_context.set_type(
identifier.clone(), identifier.clone(),
Type::Generic { Type::Generic {
identifier: identifier.clone(), identifier: identifier.clone(),
concrete_type: None, concrete_type: None,
}, },
body.position, (0, usize::MAX).into(),
)?; )?;
} }
} }
@ -176,15 +180,19 @@ impl AbstractNode for ValueNode {
for (identifier, type_constructor) in value_parameters { for (identifier, type_constructor) in value_parameters {
let r#type = type_constructor.clone().construct(context)?; let r#type = type_constructor.clone().construct(context)?;
context.set_type(identifier.clone(), r#type, body.position)?; function_context.set_type(
identifier.clone(),
r#type,
(0, usize::MAX).into(),
)?;
} }
} }
body.node body.node
.define_and_validate(context, _manage_memory, scope)?; .define_and_validate(function_context, _manage_memory, scope)?;
let ((expected_return, expected_position), actual_return) = let ((expected_return, expected_position), actual_return) =
match (return_type, body.node.expected_type(context)?) { match (return_type, body.node.expected_type(function_context)?) {
(Some(constructor), Some(r#type)) => ( (Some(constructor), Some(r#type)) => (
(constructor.construct(context)?, constructor.position()), (constructor.construct(context)?, constructor.position()),
r#type, r#type,
@ -697,6 +705,7 @@ impl Display for ValueNode {
value_parameters, value_parameters,
return_type, return_type,
body, body,
..
}) => { }) => {
write!(f, "fn ")?; write!(f, "fn ")?;
@ -730,12 +739,27 @@ impl Display for ValueNode {
} }
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct FunctionNode { pub struct FunctionNode {
type_parameters: Option<Vec<Identifier>>, type_parameters: Option<Vec<Identifier>>,
value_parameters: Option<Vec<(Identifier, TypeConstructor)>>, value_parameters: Option<Vec<(Identifier, TypeConstructor)>>,
return_type: Option<TypeConstructor>, return_type: Option<TypeConstructor>,
body: WithPosition<Block>, body: WithPosition<Block>,
#[serde(skip)]
context: Context,
}
impl Clone for FunctionNode {
fn clone(&self) -> Self {
FunctionNode {
type_parameters: self.type_parameters.clone(),
value_parameters: self.value_parameters.clone(),
return_type: self.return_type.clone(),
body: self.body.clone(),
context: Context::new(),
}
}
} }
impl PartialEq for FunctionNode { impl PartialEq for FunctionNode {

View File

@ -743,7 +743,7 @@ impl Ord for ValueInner {
} }
} }
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct Function { pub struct Function {
type_parameters: Option<Vec<Identifier>>, type_parameters: Option<Vec<Identifier>>,
value_parameters: Option<Vec<(Identifier, Type)>>, value_parameters: Option<Vec<(Identifier, Type)>>,
@ -820,13 +820,23 @@ impl Function {
debug!("Calling function"); debug!("Calling function");
self.body
.define_and_validate(&self.context, false, SourcePosition(0, usize::MAX))?;
self.body self.body
.evaluate(&self.context, false, SourcePosition(0, usize::MAX)) .evaluate(&self.context, false, SourcePosition(0, usize::MAX))
} }
} }
impl Clone for Function {
fn clone(&self) -> Self {
Function {
type_parameters: self.type_parameters.clone(),
value_parameters: self.value_parameters.clone(),
return_type: self.return_type.clone(),
body: self.body.clone(),
context: Context::new(),
}
}
}
impl Eq for Function {} impl Eq for Function {}
impl PartialEq for Function { impl PartialEq for Function {

View File

@ -7,15 +7,15 @@ fn function_scope() {
"test", "test",
" "
x = 2 x = 2
foo = fn () -> int { foo = fn () -> int {
x = 42 x = 42
x x
} }
x = 1 x = 1
foo() foo()
" "
), ),
Ok(Some(Value::integer(42))) Ok(Some(Value::integer(42)))
@ -96,16 +96,14 @@ fn recursion() {
"test", "test",
" "
fib = fn (i: int) -> int { fib = fn (i: int) -> int {
if i < 0 { if i <= 1 {
0 i
} else if i <= 1 { } else {
i
} else {
fib(i - 1) + fib(i - 2) fib(i - 1) + fib(i - 2)
} }
} }
fib(8) fib(7)
" "
), ),
Ok(Some(Value::integer(13))) Ok(Some(Value::integer(13)))