diff --git a/examples/async.ds b/examples/async.ds index 279c4ff..0028680 100644 --- a/examples/async.ds +++ b/examples/async.ds @@ -1,5 +1,5 @@ -create_random_numbers |count| { -mnumbers = []; +create_random_numbers = |count| { + numbers = []; while (length numbers) < count { numbers += (random_integer) diff --git a/examples/clue_solver.ds b/examples/clue_solver.ds index 07b0a22..d384604 100644 --- a/examples/clue_solver.ds +++ b/examples/clue_solver.ds @@ -4,26 +4,26 @@ all_cards = { weapons = ['Rope' 'Lead_Pipe' 'Knife'] } -is_ready_to_solve bool> |cards| { +is_ready_to_solve = bool> |cards| { ((length cards:suspects) == 1) && ((length cards:rooms) == 1) && ((length cards:weapons) == 1) } -take_turn map> |opponent_card current_room cards| { +take_turn = map> |opponent_card current_room cards| { (remove_card opponent_card cards) (make_guess current_room cards) cards } -remove_card |opponent_card cards| { +remove_card = |opponent_card cards| { (output opponent_card cards) cards:rooms -= opponent_card cards:suspects -= opponent_card cards:weapons -= opponent_card } -make_guess |current_room cards| { +make_guess = |current_room cards| { if (is_ready_to_solve cards) { (output 'It was ' + cards:suspects:0 diff --git a/examples/yield.ds b/examples/yield.ds index 217e572..3b608c3 100644 --- a/examples/yield.ds +++ b/examples/yield.ds @@ -1,6 +1,6 @@ 1 -> (output) -add_one [int]> |numbers| { +add_one = [int]> |numbers| { new_numbers = [] for number in numbers { diff --git a/src/value/function.rs b/src/value/function.rs index 2751b04..48c6b78 100644 --- a/src/value/function.rs +++ b/src/value/function.rs @@ -39,8 +39,21 @@ impl Function { &self.return_type } + pub fn r#type(&self) -> TypeDefinition { + let mut parameter_types = Vec::with_capacity(self.parameters.len()); + + for (_, type_definition) in &self.parameters { + parameter_types.push(type_definition.inner().clone()); + } + + TypeDefinition::new(Type::Function { + parameter_types, + return_type: Box::new(self.return_type.inner().clone()), + }) + } + pub fn call(&self, arguments: &[Expression], source: &str, context: &Map) -> Result { - let function_context = Map::new(); + let function_context = Map::clone_from(context)?; let parameter_argument_pairs = self.parameters.iter().zip(arguments.iter()); for ((identifier, type_definition), expression) in parameter_argument_pairs { @@ -123,6 +136,7 @@ impl AbstractTree for Function { impl Display for Function { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{}", Value::Function(self.clone()))?; write!( f, "Function {{ parameters: {:?}, body: {:?} }}", diff --git a/src/value/mod.rs b/src/value/mod.rs index a197f2c..a841d9a 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -1,7 +1,7 @@ //! Types that represent runtime values. use crate::{ error::{Error, Result}, - AbstractTree, Function, List, Map, Table, Type, TypeDefinition, + Function, List, Map, Table, Type, TypeDefinition, }; use serde::{ @@ -68,17 +68,7 @@ impl Value { } Value::Map(_) => Type::Map, Value::Table(_) => Type::Table, - Value::Function(function) => { - let parameters = function.parameters(); - let parameter_types = vec![Type::Any; parameters.len()]; - let body = function.body(); - let return_type = body.expected_type(context)?.take_inner(); - - Type::Function { - parameter_types, - return_type: Box::new(return_type), - } - } + Value::Function(function) => return Ok(function.r#type()), Value::String(_) => Type::String, Value::Float(_) => Type::Float, Value::Integer(_) => Type::Integer,