diff --git a/examples/clue_solver.ds b/examples/clue_solver.ds index 256c500..57ed983 100644 --- a/examples/clue_solver.ds +++ b/examples/clue_solver.ds @@ -51,4 +51,3 @@ take_turn(cards 'Conservatory' 'Kitchen') take_turn(cards 'White' 'Kitchen') take_turn(cards 'Green' 'Kitchen') take_turn(cards 'Knife' 'Kitchen') - diff --git a/examples/fibonacci.ds b/examples/fibonacci.ds index 7d47b8f..c9aed88 100644 --- a/examples/fibonacci.ds +++ b/examples/fibonacci.ds @@ -2,7 +2,7 @@ fib = (i ) { if i <= 1 { 1 } else { - fib(i - 1) + fib(i - 2) + self(i - 1) + self(i - 2) } } diff --git a/src/abstract_tree/function_node.rs b/src/abstract_tree/function_node.rs index 6beea2b..abf82e7 100644 --- a/src/abstract_tree/function_node.rs +++ b/src/abstract_tree/function_node.rs @@ -1,4 +1,7 @@ -use std::fmt::{self, Display, Formatter}; +use std::{ + fmt::{self, Display, Formatter}, + sync::Arc, +}; use serde::{Deserialize, Serialize}; @@ -65,7 +68,7 @@ impl FunctionNode { pub fn call(&self, arguments: &[Value], source: &str, outer_context: &Map) -> Result { for (key, (value, r#type)) in outer_context.variables()?.iter() { if let Value::Function(Function::ContextDefined(function_node)) = value { - if self == function_node { + if self == function_node.as_ref() { continue; } } @@ -154,7 +157,9 @@ impl AbstractTree for FunctionNode { } fn run(&self, _source: &str, _context: &Map) -> Result { - Ok(Value::Function(Function::ContextDefined(self.clone()))) + Ok(Value::Function(Function::ContextDefined(Arc::new( + self.clone(), + )))) } fn expected_type(&self, _context: &Map) -> Result { diff --git a/src/abstract_tree/value_node.rs b/src/abstract_tree/value_node.rs index 59a3550..4b751d3 100644 --- a/src/abstract_tree/value_node.rs +++ b/src/abstract_tree/value_node.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::{collections::BTreeMap, sync::Arc}; use serde::{Deserialize, Serialize}; @@ -34,7 +34,7 @@ impl AbstractTree for ValueNode { "function" => { let function_node = FunctionNode::from_syntax(child, source, context)?; - ValueNode::Function(Function::ContextDefined(function_node)) + ValueNode::Function(Function::ContextDefined(Arc::new(function_node))) } "integer" => ValueNode::Integer(source[child.byte_range()].to_string()), "string" => { diff --git a/src/value/function.rs b/src/value/function.rs index 3ba2209..a2e4706 100644 --- a/src/value/function.rs +++ b/src/value/function.rs @@ -1,4 +1,7 @@ -use std::fmt::{self, Display, Formatter}; +use std::{ + fmt::{self, Display, Formatter}, + sync::Arc, +}; use serde::{Deserialize, Serialize}; @@ -7,7 +10,7 @@ use crate::{BuiltInFunction, Format, FunctionNode, Map, Result, Type, Value}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] pub enum Function { BuiltIn(BuiltInFunction), - ContextDefined(FunctionNode), + ContextDefined(Arc), } impl Function { @@ -19,12 +22,12 @@ impl Function { Function::ContextDefined(function_node) => { function_node.set( "self".to_string(), - Value::Function(Function::ContextDefined(FunctionNode::new( + Value::Function(Function::ContextDefined(Arc::new(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)