From 12f82f7bfdae5f998ae40ff3dbcaefffc26d7914 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 24 Jan 2024 21:40:46 -0500 Subject: [PATCH] Implement recursion using the "self" variable --- src/abstract_tree/function_node.rs | 8 ++++++++ src/value/function.rs | 14 ++++++++++++-- tests/functions.rs | 31 +++++++++++++++++++----------- tree-sitter-dust/highlights.scm | 1 + 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/abstract_tree/function_node.rs b/src/abstract_tree/function_node.rs index af67347..6beea2b 100644 --- a/src/abstract_tree/function_node.rs +++ b/src/abstract_tree/function_node.rs @@ -32,6 +32,10 @@ impl FunctionNode { } } + pub fn set(&self, key: String, value: Value) -> Result> { + self.context.set(key, value) + } + pub fn parameters(&self) -> &Vec { &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 { diff --git a/src/value/function.rs b/src/value/function.rs index c95973b..3ba2209 100644 --- a/src/value/function.rs +++ b/src/value/function.rs @@ -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) } } } diff --git a/tests/functions.rs b/tests/functions.rs index 9feb029..e2263c3 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -81,17 +81,6 @@ fn function_context_captures_functions() { ), Ok(Value::Integer(2)) ); - - assert_eq!( - interpret( - " - foo = () { bar() } - foo() - bar = () { 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 ) { + if i <= 1 { + 1 + } else { + self(i - 1) + self(i - 2) + } + } + + fib(3) + " + ), + Ok(Value::Integer(3)) + ); +} diff --git a/tree-sitter-dust/highlights.scm b/tree-sitter-dust/highlights.scm index 8e38884..ba9a6ae 100644 --- a/tree-sitter-dust/highlights.scm +++ b/tree-sitter-dust/highlights.scm @@ -45,6 +45,7 @@ "if" "in" "match" + "self" "true" "while" "->"