1
0

Fix recursion

This commit is contained in:
Jeff 2024-01-28 18:07:28 -05:00
parent 6a9ce76007
commit 34173c261b
2 changed files with 27 additions and 32 deletions

View File

@ -16,7 +16,6 @@ pub struct FunctionNode {
body: Block, body: Block,
r#type: Type, r#type: Type,
syntax_position: SyntaxPosition, syntax_position: SyntaxPosition,
context: Map,
} }
impl FunctionNode { impl FunctionNode {
@ -26,21 +25,14 @@ impl FunctionNode {
r#type: Type, r#type: Type,
syntax_position: SyntaxPosition, syntax_position: SyntaxPosition,
) -> Self { ) -> Self {
let context = Map::new();
FunctionNode { FunctionNode {
parameters, parameters,
body, body,
r#type, r#type,
syntax_position, syntax_position,
context,
} }
} }
pub fn set(&self, key: String, value: Value) -> Result<Option<(Value, Type)>> {
self.context.set(key, value)
}
pub fn parameters(&self) -> &Vec<Identifier> { pub fn parameters(&self) -> &Vec<Identifier> {
&self.parameters &self.parameters
} }
@ -57,10 +49,6 @@ impl FunctionNode {
&self.syntax_position &self.syntax_position
} }
pub fn context(&self) -> &Map {
&self.context
}
pub fn return_type(&self) -> &Type { pub fn return_type(&self) -> &Type {
match &self.r#type { match &self.r#type {
Type::Function { Type::Function {
@ -72,15 +60,11 @@ impl FunctionNode {
} }
pub fn call(&self, arguments: &[Value], source: &str, outer_context: &Map) -> Result<Value> { pub fn call(&self, arguments: &[Value], source: &str, outer_context: &Map) -> Result<Value> {
for (key, (value, r#type)) in outer_context.variables()?.iter() { let function_context = Map::new();
if let Value::Function(Function::ContextDefined(function_node)) = value {
if self == function_node.as_ref() {
continue;
}
}
for (key, (value, r#type)) in outer_context.variables()?.iter() {
if r#type.is_function() { if r#type.is_function() {
self.context.set(key.clone(), value.clone())?; function_context.set(key.clone(), value.clone())?;
} }
} }
@ -89,10 +73,10 @@ impl FunctionNode {
for (identifier, value) in parameter_argument_pairs { for (identifier, value) in parameter_argument_pairs {
let key = identifier.inner().clone(); let key = identifier.inner().clone();
self.context.set(key, value.clone())?; function_context.set(key, value.clone())?;
} }
let return_value = self.body.run(source, &self.context)?; let return_value = self.body.run(source, &function_context)?;
Ok(return_value) Ok(return_value)
} }
@ -143,15 +127,33 @@ impl AbstractTree for FunctionNode {
body, body,
r#type, r#type,
syntax_position, syntax_position,
context: function_context,
}) })
} }
fn check_type(&self, source: &str, _context: &Map) -> Result<()> { fn check_type(&self, source: &str, _context: &Map) -> Result<()> {
self.return_type() let function_context = Map::new();
.check(&self.body.expected_type(&self.context)?)
if let Type::Function {
parameter_types,
return_type: _,
} = &self.r#type
{
for (parameter, parameter_type) in self.parameters.iter().zip(parameter_types.iter()) {
function_context.set_type(parameter.inner().clone(), parameter_type.clone())?;
}
self.return_type()
.check(&self.body.expected_type(&function_context)?)
.map_err(|error| error.at_source_position(source, self.syntax_position))?;
} else {
return Err(Error::TypeCheckExpectedFunction {
actual: self.r#type.clone(),
});
};
self.body
.check_type(source, &function_context)
.map_err(|error| error.at_source_position(source, self.syntax_position))?; .map_err(|error| error.at_source_position(source, self.syntax_position))?;
self.body.check_type(source, &self.context)?;
Ok(()) Ok(())
} }

View File

@ -35,13 +35,6 @@ impl Function {
} }
} }
} }
pub fn set(&self, key: String, value: Value) -> Result<Option<(Value, Type)>> {
match self {
Function::BuiltIn(_) => todo!(),
Function::ContextDefined(function_node) => function_node.set(key, value),
}
}
} }
impl Format for Function { impl Format for Function {