Implement recursion using the "self" variable

This commit is contained in:
Jeff 2024-01-24 21:40:46 -05:00
parent 52c6c3a507
commit 12f82f7bfd
4 changed files with 41 additions and 13 deletions

View File

@ -32,6 +32,10 @@ impl FunctionNode {
}
}
pub fn set(&self, key: String, value: Value) -> Result<Option<(Value, Type)>> {
self.context.set(key, value)
}
pub fn parameters(&self) -> &Vec<Identifier> {
&self.parameters
}
@ -44,6 +48,10 @@ impl FunctionNode {
&self.r#type
}
pub fn syntax_position(&self) -> &SyntaxPosition {
&self.syntax_position
}
pub fn return_type(&self) -> &Type {
match &self.r#type {
Type::Function {

View File

@ -16,8 +16,18 @@ impl Function {
Function::BuiltIn(built_in_function) => {
built_in_function.call(arguments, source, outer_context)
}
Function::ContextDefined(context_defined_function) => {
context_defined_function.call(arguments, source, outer_context)
Function::ContextDefined(function_node) => {
function_node.set(
"self".to_string(),
Value::Function(Function::ContextDefined(FunctionNode::new(
function_node.parameters().clone(),
function_node.body().clone(),
function_node.r#type().clone(),
*function_node.syntax_position(),
))),
)?;
function_node.call(arguments, source, outer_context)
}
}
}

View File

@ -81,17 +81,6 @@ fn function_context_captures_functions() {
),
Ok(Value::Integer(2))
);
assert_eq!(
interpret(
"
foo = () <int> { bar() }
foo()
bar = () <int> { 2 }
"
),
Ok(Value::Integer(2))
);
}
#[test]
@ -138,3 +127,23 @@ fn function_context_captures_structure_definitions() {
Ok(Value::Map(map))
);
}
#[test]
fn recursion() {
assert_eq!(
interpret(
"
fib = (i <int>) <int> {
if i <= 1 {
1
} else {
self(i - 1) + self(i - 2)
}
}
fib(3)
"
),
Ok(Value::Integer(3))
);
}

View File

@ -45,6 +45,7 @@
"if"
"in"
"match"
"self"
"true"
"while"
"->"