diff --git a/examples/async.ds b/examples/async.ds index 0028680..dda8dbe 100644 --- a/examples/async.ds +++ b/examples/async.ds @@ -1,11 +1,11 @@ create_random_numbers = |count| { - numbers = []; + numbers = [] while (length numbers) < count { numbers += (random_integer) } - (output "Made " + count + " numbers.") + (output "Made " + (length numbers) + " numbers.") } (output "This will print first.") diff --git a/src/abstract_tree/block.rs b/src/abstract_tree/block.rs index 3ab01b9..8d017d5 100644 --- a/src/abstract_tree/block.rs +++ b/src/abstract_tree/block.rs @@ -4,7 +4,7 @@ use rayon::prelude::*; use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Error, Map, Result, Statement, TypeDefinition, Value}; +use crate::{AbstractTree, Error, Map, Result, Statement, Type, TypeDefinition, Value}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct Block { @@ -83,6 +83,10 @@ impl AbstractTree for Block { } fn expected_type(&self, context: &Map) -> Result { - self.statements.last().unwrap().expected_type(context) + if self.is_async { + Ok(TypeDefinition::new(Type::Any)) + } else { + self.statements.last().unwrap().expected_type(context) + } } } diff --git a/src/abstract_tree/type_defintion.rs b/src/abstract_tree/type_defintion.rs index 0308b9f..80fac94 100644 --- a/src/abstract_tree/type_defintion.rs +++ b/src/abstract_tree/type_defintion.rs @@ -40,60 +40,62 @@ impl TypeDefinition { } pub fn runtime_check(&self, other: &TypeDefinition, context: &Map) -> Result<()> { - match (&self.r#type, &other.r#type) { - (Type::Any, _) - | (_, Type::Any) - | (Type::Boolean, Type::Boolean) - | (Type::Empty, Type::Empty) - | (Type::Float, Type::Float) - | (Type::Integer, Type::Integer) - | (Type::Map, Type::Map) - | (Type::Number, Type::Number) - | (Type::Number, Type::Integer) - | (Type::Number, Type::Float) - | (Type::Integer, Type::Number) - | (Type::Float, Type::Number) - | (Type::String, Type::String) - | (Type::Table, Type::Table) => Ok(()), - (Type::List(self_item_type), Type::List(other_item_type)) => { - let self_defintion = TypeDefinition::new(self_item_type.as_ref().clone()); - let other_definition = &TypeDefinition::new(other_item_type.as_ref().clone()); + // match (&self.r#type, &other.r#type) { + // (Type::Any, _) + // | (_, Type::Any) + // | (Type::Boolean, Type::Boolean) + // | (Type::Empty, Type::Empty) + // | (Type::Float, Type::Float) + // | (Type::Integer, Type::Integer) + // | (Type::Map, Type::Map) + // | (Type::Number, Type::Number) + // | (Type::Number, Type::Integer) + // | (Type::Number, Type::Float) + // | (Type::Integer, Type::Number) + // | (Type::Float, Type::Number) + // | (Type::String, Type::String) + // | (Type::Table, Type::Table) => Ok(()), + // (Type::List(self_item_type), Type::List(other_item_type)) => { + // let self_defintion = TypeDefinition::new(self_item_type.as_ref().clone()); + // let other_definition = &TypeDefinition::new(other_item_type.as_ref().clone()); - self_defintion.runtime_check(other_definition, context) - } - ( - Type::Function { - parameter_types: self_parameter_types, - return_type: self_return_type, - }, - Type::Function { - parameter_types: other_parameter_types, - return_type: other_return_type, - }, - ) => { - let parameter_type_pairs = self_parameter_types - .iter() - .zip(other_parameter_types.iter()); + // self_defintion.runtime_check(other_definition, context) + // } + // ( + // Type::Function { + // parameter_types: self_parameter_types, + // return_type: self_return_type, + // }, + // Type::Function { + // parameter_types: other_parameter_types, + // return_type: other_return_type, + // }, + // ) => { + // let parameter_type_pairs = self_parameter_types + // .iter() + // .zip(other_parameter_types.iter()); - for (self_parameter_type, other_parameter_type) in parameter_type_pairs { - TypeDefinition::new(self_parameter_type.clone()).runtime_check( - &TypeDefinition::new(other_parameter_type.clone()), - context, - )?; - } + // for (self_parameter_type, other_parameter_type) in parameter_type_pairs { + // TypeDefinition::new(self_parameter_type.clone()).runtime_check( + // &TypeDefinition::new(other_parameter_type.clone()), + // context, + // )?; + // } - TypeDefinition::new(self_return_type.as_ref().clone()).runtime_check( - &TypeDefinition::new(other_return_type.as_ref().clone()), - context, - )?; + // TypeDefinition::new(self_return_type.as_ref().clone()).runtime_check( + // &TypeDefinition::new(other_return_type.as_ref().clone()), + // context, + // )?; - Ok(()) - } - _ => Err(Error::RuntimeTypeCheck { - expected: self.clone(), - actual: other.clone(), - }), - } + // Ok(()) + // } + // _ => Err(Error::RuntimeTypeCheck { + // expected: self.clone(), + // actual: other.clone(), + // }), + // } + + Ok(()) } } diff --git a/src/built_in_functions/collections.rs b/src/built_in_functions/collections.rs new file mode 100644 index 0000000..dc75a9c --- /dev/null +++ b/src/built_in_functions/collections.rs @@ -0,0 +1,24 @@ +use crate::{BuiltInFunction, Error, Map, Result, Type, TypeDefinition, Value}; + +pub struct Length; + +impl BuiltInFunction for Length { + fn name(&self) -> &'static str { + "length" + } + + fn run(&self, arguments: &[Value], _context: &Map) -> Result { + Error::expect_argument_amount(self, 1, arguments.len())?; + + let length = arguments.first().unwrap().as_list()?.items().len(); + + Ok(Value::Integer(length as i64)) + } + + fn type_definition(&self) -> TypeDefinition { + TypeDefinition::new(Type::Function { + parameter_types: vec![Type::List(Box::new(Type::Any))], + return_type: Box::new(Type::Integer), + }) + } +} diff --git a/src/built_in_functions/fs.rs b/src/built_in_functions/fs.rs index 22b7e1b..d56c138 100644 --- a/src/built_in_functions/fs.rs +++ b/src/built_in_functions/fs.rs @@ -4,7 +4,7 @@ use std::{ path::PathBuf, }; -use crate::{BuiltInFunction, List, Map, Result, Value}; +use crate::{BuiltInFunction, List, Map, Result, Type, TypeDefinition, Value}; pub struct Read; @@ -47,8 +47,11 @@ impl BuiltInFunction for Read { Ok(Value::String(file_content)) } - fn type_definition(&self) -> crate::TypeDefinition { - todo!() + fn type_definition(&self) -> TypeDefinition { + TypeDefinition::new(Type::Function { + parameter_types: vec![Type::String], + return_type: Box::new(Type::String), + }) } } @@ -69,7 +72,10 @@ impl BuiltInFunction for Write { } fn type_definition(&self) -> crate::TypeDefinition { - todo!() + TypeDefinition::new(Type::Function { + parameter_types: vec![Type::String], + return_type: Box::new(Type::Empty), + }) } } @@ -94,6 +100,9 @@ impl BuiltInFunction for Append { } fn type_definition(&self) -> crate::TypeDefinition { - todo!() + TypeDefinition::new(Type::Function { + parameter_types: vec![Type::String, Type::String], + return_type: Box::new(Type::Empty), + }) } } diff --git a/src/built_in_functions/mod.rs b/src/built_in_functions/mod.rs index 3d8f8ff..08eee7c 100644 --- a/src/built_in_functions/mod.rs +++ b/src/built_in_functions/mod.rs @@ -1,15 +1,17 @@ use crate::{Map, Result, TypeDefinition, Value}; mod assert; +mod collections; mod data_formats; mod fs; mod output; mod random; mod r#type; -pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 13] = [ +pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 14] = [ &assert::Assert, &assert::AssertEqual, + &collections::Length, &data_formats::FromJson, &data_formats::ToJson, &fs::Read, diff --git a/src/built_in_functions/random.rs b/src/built_in_functions/random.rs index eb3f432..05a4c83 100644 --- a/src/built_in_functions/random.rs +++ b/src/built_in_functions/random.rs @@ -10,7 +10,7 @@ impl BuiltInFunction for Random { } fn run(&self, arguments: &[Value], _context: &Map) -> Result { - Error::expect_argument_minimum(self, 1, arguments.len())?; + Error::expect_argument_amount(self, 1, arguments.len())?; let list = arguments.first().unwrap().as_list()?; let items = list.items(); @@ -42,7 +42,10 @@ impl BuiltInFunction for RandomInteger { } fn type_definition(&self) -> crate::TypeDefinition { - todo!() + TypeDefinition::new(Type::Function { + parameter_types: Vec::with_capacity(0), + return_type: Box::new(Type::Integer), + }) } } @@ -60,7 +63,10 @@ impl BuiltInFunction for RandomFloat { } fn type_definition(&self) -> crate::TypeDefinition { - todo!() + TypeDefinition::new(Type::Function { + parameter_types: Vec::with_capacity(0), + return_type: Box::new(Type::Float), + }) } } @@ -78,6 +84,9 @@ impl BuiltInFunction for RandomBoolean { } fn type_definition(&self) -> crate::TypeDefinition { - todo!() + TypeDefinition::new(Type::Function { + parameter_types: Vec::with_capacity(0), + return_type: Box::new(Type::Boolean), + }) } }