Fix function context bug
This commit is contained in:
parent
1794f7559c
commit
f3fe03a95f
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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)))
|
||||||
|
Loading…
Reference in New Issue
Block a user