diff --git a/dust-lang/src/abstract_tree/type.rs b/dust-lang/src/abstract_tree/type.rs index 7301b6d..3ec4b66 100644 --- a/dust-lang/src/abstract_tree/type.rs +++ b/dust-lang/src/abstract_tree/type.rs @@ -18,7 +18,7 @@ pub enum Type { Float, Function { type_parameters: Option>, - value_parameters: Vec<(Identifier, Type)>, + value_parameters: Vec, return_type: Box, }, Generic(Option>), @@ -236,8 +236,8 @@ impl Display for Type { write!(f, ")(")?; } - for (identifier, r#type) in value_parameters { - write!(f, "{identifier}: {type}")?; + for r#type in value_parameters { + write!(f, "{type}")?; } write!(f, ") : {}", return_type) diff --git a/dust-lang/src/abstract_tree/type_constructor.rs b/dust-lang/src/abstract_tree/type_constructor.rs index 013c2ff..fde1174 100644 --- a/dust-lang/src/abstract_tree/type_constructor.rs +++ b/dust-lang/src/abstract_tree/type_constructor.rs @@ -49,7 +49,35 @@ impl TypeConstructor { pub fn construct(self, context: &Context) -> Result { let r#type = match self { - TypeConstructor::Function(_) => todo!(), + TypeConstructor::Function(function_type_constructor) => { + let FunctionTypeConstructor { + type_parameters: declared_type_parameters, + value_parameters: declared_value_parameters, + return_type, + } = function_type_constructor.node; + + let type_parameters = declared_type_parameters.map(|identifiers| { + identifiers + .into_iter() + .map(|identifier| identifier.node) + .collect() + }); + let mut value_parameters = Vec::with_capacity(declared_value_parameters.len()); + + for parameter in declared_value_parameters { + let r#type = parameter.construct(&context)?; + + value_parameters.push(r#type); + } + + let return_type = Box::new(return_type.construct(&context)?); + + Type::Function { + type_parameters, + value_parameters, + return_type, + } + } TypeConstructor::Identifier(WithPosition { node: identifier, .. }) => { diff --git a/dust-lang/src/abstract_tree/value_node.rs b/dust-lang/src/abstract_tree/value_node.rs index 949c73e..ad8d64a 100644 --- a/dust-lang/src/abstract_tree/value_node.rs +++ b/dust-lang/src/abstract_tree/value_node.rs @@ -347,10 +347,10 @@ impl ExpectedType for ValueNode { } => { let mut value_parameter_types = Vec::with_capacity(value_parameters.len()); - for (identifier, type_constructor) in value_parameters { + for (_, type_constructor) in value_parameters { let r#type = type_constructor.clone().construct(&context)?; - value_parameter_types.push((identifier.clone(), r#type)); + value_parameter_types.push(r#type); } let type_parameters = type_parameters.clone().map(|parameters| { diff --git a/dust-lang/src/value.rs b/dust-lang/src/value.rs index 5bb713f..55703ef 100644 --- a/dust-lang/src/value.rs +++ b/dust-lang/src/value.rs @@ -234,11 +234,20 @@ impl ValueInner { ValueInner::Map(_) => Type::Map, ValueInner::Range(_) => Type::Range, ValueInner::String(_) => Type::String, - ValueInner::Function(function) => Type::Function { - type_parameters: None, - value_parameters: function.value_parameters.clone(), - return_type: Box::new(function.return_type.clone()), - }, + ValueInner::Function(function) => { + let value_parameters = function + .value_parameters() + .into_iter() + .map(|(_, r#type)| r#type) + .cloned() + .collect(); + + Type::Function { + type_parameters: function.type_parameters().clone(), + value_parameters, + return_type: Box::new(function.return_type.clone()), + } + } ValueInner::Structure { name, .. } => { if let Some(r#type) = context.get_type(&name.node)? { r#type @@ -328,6 +337,10 @@ impl Function { &self.type_parameters } + pub fn value_parameters(&self) -> &Vec<(Identifier, Type)> { + &self.value_parameters + } + pub fn call( self, arguments: Vec,