Refine type constructor

This commit is contained in:
Jeff 2024-06-17 10:50:06 -04:00
parent e448c9dd4c
commit 9e0c0b4db3
10 changed files with 136 additions and 131 deletions

View File

@ -9,18 +9,16 @@ use crate::{
Value, Value,
}; };
use super::{ use super::{AbstractNode, Evaluation, ExpectedType, Expression, Type, TypeConstructor};
AbstractNode, Evaluation, ExpectedType, Expression, Type, TypeConstructor, WithPosition,
};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct As { pub struct As {
expression: Expression, expression: Expression,
constructor: WithPosition<TypeConstructor>, constructor: TypeConstructor,
} }
impl As { impl As {
pub fn new(expression: Expression, constructor: WithPosition<TypeConstructor>) -> Self { pub fn new(expression: Expression, constructor: TypeConstructor) -> Self {
Self { Self {
expression, expression,
constructor, constructor,
@ -34,7 +32,7 @@ impl AbstractNode for As {
_context: &mut Context, _context: &mut Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<(), ValidationError> { ) -> Result<(), ValidationError> {
match self.constructor.node { match self.constructor {
TypeConstructor::Type(_) => {} TypeConstructor::Type(_) => {}
_ => todo!("Create an error for this occurence."), _ => todo!("Create an error for this occurence."),
}; };
@ -61,7 +59,7 @@ impl AbstractNode for As {
ValidationError::InterpreterExpectedReturn(expression_position), ValidationError::InterpreterExpectedReturn(expression_position),
)); ));
}; };
let r#type = self.constructor.node.construct(&context)?; let r#type = self.constructor.construct(&context)?;
let (from_value, to_type): (&ValueInner, Type) = (value.inner().borrow(), r#type); let (from_value, to_type): (&ValueInner, Type) = (value.inner().borrow(), r#type);
let converted = match (from_value, to_type) { let converted = match (from_value, to_type) {
@ -76,6 +74,6 @@ impl AbstractNode for As {
impl ExpectedType for As { impl ExpectedType for As {
fn expected_type(&self, context: &mut Context) -> Result<Type, ValidationError> { fn expected_type(&self, context: &mut Context) -> Result<Type, ValidationError> {
self.constructor.node.clone().construct(&context) self.constructor.clone().construct(&context)
} }
} }

View File

@ -12,7 +12,7 @@ use super::{AbstractNode, Evaluation, ExpectedType, Statement, TypeConstructor,
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Assignment { pub struct Assignment {
identifier: WithPosition<Identifier>, identifier: WithPosition<Identifier>,
constructor: Option<WithPosition<TypeConstructor>>, constructor: Option<TypeConstructor>,
operator: AssignmentOperator, operator: AssignmentOperator,
statement: Box<Statement>, statement: Box<Statement>,
} }
@ -27,7 +27,7 @@ pub enum AssignmentOperator {
impl Assignment { impl Assignment {
pub fn new( pub fn new(
identifier: WithPosition<Identifier>, identifier: WithPosition<Identifier>,
constructor: Option<WithPosition<TypeConstructor>>, constructor: Option<TypeConstructor>,
operator: AssignmentOperator, operator: AssignmentOperator,
statement: Statement, statement: Statement,
) -> Self { ) -> Self {
@ -44,11 +44,7 @@ impl AbstractNode for Assignment {
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> {
let statement_type = self.statement.expected_type(context)?; let statement_type = self.statement.expected_type(context)?;
if let Some(WithPosition { if let Some(constructor) = &self.constructor {
node: constructor,
position: expected_position,
}) = &self.constructor
{
let r#type = constructor.clone().construct(&context)?; let r#type = constructor.clone().construct(&context)?;
r#type r#type
@ -56,7 +52,7 @@ impl AbstractNode for Assignment {
.map_err(|conflict| ValidationError::TypeCheck { .map_err(|conflict| ValidationError::TypeCheck {
conflict, conflict,
actual_position: self.statement.position(), actual_position: self.statement.position(),
expected_position: Some(expected_position.clone()), expected_position: Some(constructor.position()),
})?; })?;
context.set_type(self.identifier.node.clone(), r#type.clone())?; context.set_type(self.identifier.node.clone(), r#type.clone())?;

View File

@ -6,21 +6,19 @@ use crate::{
value::ValueInner, value::ValueInner,
}; };
use super::{ use super::{AbstractNode, Evaluation, ExpectedType, Expression, Type, TypeConstructor};
AbstractNode, Evaluation, ExpectedType, Expression, Type, TypeConstructor, WithPosition,
};
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct FunctionCall { pub struct FunctionCall {
function: Box<Expression>, function: Box<Expression>,
type_arguments: Option<Vec<WithPosition<TypeConstructor>>>, type_arguments: Option<Vec<TypeConstructor>>,
value_arguments: Vec<Expression>, value_arguments: Vec<Expression>,
} }
impl FunctionCall { impl FunctionCall {
pub fn new( pub fn new(
function: Expression, function: Expression,
type_arguments: Option<Vec<WithPosition<TypeConstructor>>>, type_arguments: Option<Vec<TypeConstructor>>,
value_arguments: Vec<Expression>, value_arguments: Vec<Expression>,
) -> Self { ) -> Self {
FunctionCall { FunctionCall {
@ -115,7 +113,7 @@ impl AbstractNode for FunctionCall {
for (parameter, constructor) in for (parameter, constructor) in
type_parameters.into_iter().zip(type_arguments.into_iter()) type_parameters.into_iter().zip(type_arguments.into_iter())
{ {
let r#type = constructor.node.construct(context)?; let r#type = constructor.construct(context)?;
function_context.set_type(parameter.clone(), r#type)?; function_context.set_type(parameter.clone(), r#type)?;
} }

View File

@ -104,7 +104,7 @@ impl ExpectedType for MapIndex {
for (property, constructor_option, expression) in properties { for (property, constructor_option, expression) in properties {
if property == &index.node { if property == &index.node {
return if let Some(constructor) = constructor_option { return if let Some(constructor) = constructor_option {
let r#type = constructor.node.clone().construct(&context)?; let r#type = constructor.clone().construct(&context)?;
Ok(r#type) Ok(r#type)
} else { } else {

View File

@ -42,7 +42,7 @@ pub use self::{
statement::Statement, statement::Statement,
structure_definition::StructureDefinition, structure_definition::StructureDefinition,
type_alias::TypeAssignment, type_alias::TypeAssignment,
type_constructor::TypeConstructor, type_constructor::{FunctionTypeConstructor, ListTypeConstructor, TypeConstructor},
value_expression::Expression, value_expression::Expression,
value_node::ValueNode, value_node::ValueNode,
}; };

View File

@ -6,16 +6,16 @@ use crate::{
identifier::Identifier, identifier::Identifier,
}; };
use super::{AbstractNode, Evaluation, Type, TypeConstructor, WithPosition}; use super::{AbstractNode, Evaluation, Type, TypeConstructor};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct StructureDefinition { pub struct StructureDefinition {
name: Identifier, name: Identifier,
fields: Vec<(Identifier, WithPosition<TypeConstructor>)>, fields: Vec<(Identifier, TypeConstructor)>,
} }
impl StructureDefinition { impl StructureDefinition {
pub fn new(name: Identifier, fields: Vec<(Identifier, WithPosition<TypeConstructor>)>) -> Self { pub fn new(name: Identifier, fields: Vec<(Identifier, TypeConstructor)>) -> Self {
Self { name, fields } Self { name, fields }
} }
} }
@ -37,7 +37,7 @@ impl AbstractNode for StructureDefinition {
let mut fields = Vec::with_capacity(self.fields.len()); let mut fields = Vec::with_capacity(self.fields.len());
for (identifier, constructor) in self.fields { for (identifier, constructor) in self.fields {
let r#type = constructor.node.construct(&context)?; let r#type = constructor.construct(&context)?;
fields.push((identifier, r#type)); fields.push((identifier, r#type));
} }

View File

@ -11,14 +11,11 @@ use super::{AbstractNode, Evaluation, TypeConstructor, WithPosition};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct TypeAssignment { pub struct TypeAssignment {
identifier: WithPosition<Identifier>, identifier: WithPosition<Identifier>,
constructor: WithPosition<TypeConstructor>, constructor: TypeConstructor,
} }
impl TypeAssignment { impl TypeAssignment {
pub fn new( pub fn new(identifier: WithPosition<Identifier>, constructor: TypeConstructor) -> Self {
identifier: WithPosition<Identifier>,
constructor: WithPosition<TypeConstructor>,
) -> Self {
Self { Self {
identifier, identifier,
constructor, constructor,
@ -40,7 +37,7 @@ impl AbstractNode for TypeAssignment {
context: &mut Context, context: &mut Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Evaluation, RuntimeError> { ) -> Result<Evaluation, RuntimeError> {
let r#type = self.constructor.node.construct(&context)?; let r#type = self.constructor.construct(&context)?;
context.set_type(self.identifier.node, r#type)?; context.set_type(self.identifier.node, r#type)?;

View File

@ -4,25 +4,41 @@ use serde::{Deserialize, Serialize};
use crate::{context::Context, error::ValidationError, identifier::Identifier}; use crate::{context::Context, error::ValidationError, identifier::Identifier};
use super::{ExpectedType, Type, WithPosition}; use super::{ExpectedType, SourcePosition, Type, WithPosition};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum TypeConstructor { pub enum TypeConstructor {
Function { Function(WithPosition<FunctionTypeConstructor>),
type_parameters: Option<Vec<WithPosition<Identifier>>>,
value_parameters: Vec<(WithPosition<Identifier>, Box<WithPosition<TypeConstructor>>)>,
return_type: Box<WithPosition<TypeConstructor>>,
},
Identifier(WithPosition<Identifier>), Identifier(WithPosition<Identifier>),
List { List(WithPosition<ListTypeConstructor>),
length: usize,
item_type: Box<WithPosition<TypeConstructor>>,
},
ListOf(WithPosition<Box<TypeConstructor>>), ListOf(WithPosition<Box<TypeConstructor>>),
Type(Type), Type(WithPosition<Type>),
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct FunctionTypeConstructor {
pub type_parameters: Option<Vec<WithPosition<Identifier>>>,
pub value_parameters: Vec<(WithPosition<Identifier>, Box<TypeConstructor>)>,
pub return_type: Box<TypeConstructor>,
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct ListTypeConstructor {
pub length: usize,
pub item_type: Box<TypeConstructor>,
} }
impl TypeConstructor { impl TypeConstructor {
pub fn position(&self) -> SourcePosition {
match self {
TypeConstructor::Function(WithPosition { position, .. }) => *position,
TypeConstructor::Identifier(WithPosition { position, .. }) => *position,
TypeConstructor::List(WithPosition { position, .. }) => *position,
TypeConstructor::ListOf(WithPosition { position, .. }) => *position,
TypeConstructor::Type(WithPosition { position, .. }) => *position,
}
}
pub fn validate( pub fn validate(
&self, &self,
_context: &mut Context, _context: &mut Context,
@ -33,11 +49,7 @@ impl TypeConstructor {
pub fn construct(self, context: &Context) -> Result<Type, ValidationError> { pub fn construct(self, context: &Context) -> Result<Type, ValidationError> {
match self { match self {
TypeConstructor::Function { TypeConstructor::Function(_) => todo!(),
type_parameters: _,
value_parameters: _,
return_type: _,
} => todo!(),
TypeConstructor::Identifier(WithPosition { TypeConstructor::Identifier(WithPosition {
node: identifier, node: identifier,
position, position,
@ -51,15 +63,16 @@ impl TypeConstructor {
}) })
} }
} }
TypeConstructor::List { length, item_type } => { TypeConstructor::List(positioned_constructor) => {
let constructed_type = item_type.node.construct(context)?; let ListTypeConstructor { length, item_type } = positioned_constructor.node;
let constructed_type = item_type.construct(context)?;
Ok(Type::List { Ok(Type::List {
length, length,
item_type: Box::new(constructed_type), item_type: Box::new(constructed_type),
}) })
} }
TypeConstructor::Type(r#type) => Ok(r#type), TypeConstructor::Type(r#type) => Ok(r#type.node),
TypeConstructor::ListOf(_) => todo!(), TypeConstructor::ListOf(_) => todo!(),
} }
} }

View File

@ -19,13 +19,7 @@ pub enum ValueNode {
Float(f64), Float(f64),
Integer(i64), Integer(i64),
List(Vec<Expression>), List(Vec<Expression>),
Map( Map(Vec<(Identifier, Option<TypeConstructor>, Expression)>),
Vec<(
Identifier,
Option<WithPosition<TypeConstructor>>,
Expression,
)>,
),
Range(Range<i64>), Range(Range<i64>),
String(String), String(String),
Structure { Structure {
@ -34,8 +28,8 @@ pub enum ValueNode {
}, },
ParsedFunction { ParsedFunction {
type_parameters: Option<Vec<WithPosition<Identifier>>>, type_parameters: Option<Vec<WithPosition<Identifier>>>,
value_parameters: Vec<(Identifier, WithPosition<TypeConstructor>)>, value_parameters: Vec<(Identifier, TypeConstructor)>,
return_type: WithPosition<TypeConstructor>, return_type: TypeConstructor,
body: WithPosition<Block>, body: WithPosition<Block>,
}, },
} }
@ -48,13 +42,13 @@ impl AbstractNode for ValueNode {
if let Some(constructor) = constructor_option { if let Some(constructor) = constructor_option {
let actual_type = expression.expected_type(context)?; let actual_type = expression.expected_type(context)?;
let exprected_type = constructor.node.clone().construct(&context)?; let exprected_type = constructor.clone().construct(&context)?;
exprected_type.check(&actual_type).map_err(|conflict| { exprected_type.check(&actual_type).map_err(|conflict| {
ValidationError::TypeCheck { ValidationError::TypeCheck {
conflict, conflict,
actual_position: expression.position(), actual_position: expression.position(),
expected_position: Some(constructor.position), expected_position: Some(constructor.position()),
} }
})?; })?;
} }
@ -73,7 +67,7 @@ impl AbstractNode for ValueNode {
let mut function_context = Context::new(Some(&context)); let mut function_context = Context::new(Some(&context));
for (identifier, type_constructor) in value_parameters { for (identifier, type_constructor) in value_parameters {
let r#type = type_constructor.node.clone().construct(&function_context)?; let r#type = type_constructor.clone().construct(&function_context)?;
function_context.set_type(identifier.clone(), r#type)?; function_context.set_type(identifier.clone(), r#type)?;
} }
@ -83,14 +77,13 @@ impl AbstractNode for ValueNode {
let actual_return_type = body.node.expected_type(&mut function_context)?; let actual_return_type = body.node.expected_type(&mut function_context)?;
return_type return_type
.node
.clone() .clone()
.construct(&function_context)? .construct(&function_context)?
.check(&actual_return_type) .check(&actual_return_type)
.map_err(|conflict| ValidationError::TypeCheck { .map_err(|conflict| ValidationError::TypeCheck {
conflict, conflict,
actual_position: body.position, actual_position: body.position,
expected_position: Some(return_type.position), expected_position: Some(return_type.position()),
})?; })?;
return Ok(()); return Ok(());
@ -197,12 +190,12 @@ impl AbstractNode for ValueNode {
let mut value_parameters = Vec::with_capacity(constructors.len()); let mut value_parameters = Vec::with_capacity(constructors.len());
for (identifier, constructor) in constructors { for (identifier, constructor) in constructors {
let r#type = constructor.node.construct(&context)?; let r#type = constructor.construct(&context)?;
value_parameters.push((identifier, r#type)); value_parameters.push((identifier, r#type));
} }
let return_type = return_type.node.construct(&context)?; let return_type = return_type.construct(&context)?;
Value::function(type_parameters, value_parameters, return_type, body.node) Value::function(type_parameters, value_parameters, return_type, body.node)
} }
@ -353,7 +346,7 @@ impl ExpectedType for ValueNode {
let mut value_parameter_types = Vec::with_capacity(value_parameters.len()); let mut value_parameter_types = Vec::with_capacity(value_parameters.len());
for (identifier, type_constructor) in value_parameters { for (identifier, type_constructor) in value_parameters {
let r#type = type_constructor.node.clone().construct(&context)?; let r#type = type_constructor.clone().construct(&context)?;
value_parameter_types.push((identifier.clone(), r#type)); value_parameter_types.push((identifier.clone(), r#type));
} }
@ -364,7 +357,7 @@ impl ExpectedType for ValueNode {
.map(|identifier| identifier.node.clone()) .map(|identifier| identifier.node.clone())
.collect() .collect()
}); });
let return_type = return_type.node.clone().construct(&context)?; let return_type = return_type.clone().construct(&context)?;
Type::Function { Type::Function {
type_parameters, type_parameters,

View File

@ -65,13 +65,6 @@ pub fn parser<'src>(
}; };
let type_constructor = recursive(|type_constructor| { let type_constructor = recursive(|type_constructor| {
let positioned_type_constructor =
type_constructor
.clone()
.map_with(|constructor: TypeConstructor, state| {
constructor.with_position(state.span())
});
let primitive_type = choice(( let primitive_type = choice((
just(Token::Keyword(Keyword::Any)).to(Type::Any), just(Token::Keyword(Keyword::Any)).to(Type::Any),
just(Token::Keyword(Keyword::Bool)).to(Type::Boolean), just(Token::Keyword(Keyword::Bool)).to(Type::Boolean),
@ -81,7 +74,7 @@ pub fn parser<'src>(
just(Token::Keyword(Keyword::Range)).to(Type::Range), just(Token::Keyword(Keyword::Range)).to(Type::Range),
just(Token::Keyword(Keyword::Str)).to(Type::String), just(Token::Keyword(Keyword::Str)).to(Type::String),
)) ))
.map(|r#type| TypeConstructor::Type(r#type)); .map_with(|r#type, state| TypeConstructor::Type(r#type.with_position(state.span())));
let function_type = just(Token::Keyword(Keyword::Fn)) let function_type = just(Token::Keyword(Keyword::Fn))
.ignore_then( .ignore_then(
@ -99,9 +92,11 @@ pub fn parser<'src>(
positioned_identifier positioned_identifier
.clone() .clone()
.then_ignore(just(Token::Control(Control::Colon))) .then_ignore(just(Token::Control(Control::Colon)))
.then(type_constructor.clone().map_with(|constructor, state| { .then(
Box::new(constructor.with_position(state.span())) type_constructor
})) .clone()
.map(|constructor| Box::new(constructor)),
)
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
.collect() .collect()
.delimited_by( .delimited_by(
@ -110,16 +105,21 @@ pub fn parser<'src>(
), ),
) )
.then_ignore(just(Token::Control(Control::SkinnyArrow))) .then_ignore(just(Token::Control(Control::SkinnyArrow)))
.then(positioned_type_constructor.clone()) .then(type_constructor.clone())
.map( .map_with(
|((type_parameters, value_parameters), return_type)| TypeConstructor::Function { |((type_parameters, value_parameters), return_type), state| {
type_parameters, TypeConstructor::Function(
value_parameters, FunctionTypeConstructor {
return_type: Box::new(return_type), type_parameters,
value_parameters,
return_type: Box::new(return_type),
}
.with_position(state.span()),
)
}, },
); );
let list = positioned_type_constructor let list = type_constructor
.clone() .clone()
.clone() .clone()
.then_ignore(just(Token::Control(Control::Semicolon))) .then_ignore(just(Token::Control(Control::Semicolon)))
@ -128,9 +128,14 @@ pub fn parser<'src>(
just(Token::Control(Control::SquareOpen)), just(Token::Control(Control::SquareOpen)),
just(Token::Control(Control::SquareClose)), just(Token::Control(Control::SquareClose)),
) )
.map(|(item_type, length)| TypeConstructor::List { .map_with(|(item_type, length), state| {
length: length as usize, TypeConstructor::List(
item_type: Box::new(item_type), ListTypeConstructor {
length: length as usize,
item_type: Box::new(item_type),
}
.with_position(state.span()),
)
}); });
let list_of = just(Token::Keyword(Keyword::List)) let list_of = just(Token::Keyword(Keyword::List))
@ -145,12 +150,8 @@ pub fn parser<'src>(
choice((function_type, list, list_of, primitive_type)) choice((function_type, list, list_of, primitive_type))
}); });
let positioned_type_constructor = type_constructor
.clone()
.map_with(|constructor: TypeConstructor, state| constructor.with_position(state.span()));
let type_specification = let type_specification =
just(Token::Control(Control::Colon)).ignore_then(positioned_type_constructor.clone()); just(Token::Control(Control::Colon)).ignore_then(type_constructor.clone());
let statement = recursive(|statement| { let statement = recursive(|statement| {
let allow_built_ins = allow_built_ins.clone(); let allow_built_ins = allow_built_ins.clone();
@ -209,7 +210,7 @@ pub fn parser<'src>(
.then( .then(
identifier identifier
.then_ignore(just(Token::Control(Control::Colon))) .then_ignore(just(Token::Control(Control::Colon)))
.then(positioned_type_constructor.clone()) .then(type_constructor.clone())
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
.collect() .collect()
.delimited_by( .delimited_by(
@ -218,7 +219,7 @@ pub fn parser<'src>(
), ),
) )
.then_ignore(just(Token::Control(Control::SkinnyArrow))) .then_ignore(just(Token::Control(Control::SkinnyArrow)))
.then(positioned_type_constructor.clone()) .then(type_constructor.clone())
.then(block.clone()) .then(block.clone())
.map_with( .map_with(
|(((type_parameters, value_parameters), return_type), body), state| { |(((type_parameters, value_parameters), return_type), body), state| {
@ -293,7 +294,7 @@ pub fn parser<'src>(
} }
}); });
let turbofish = positioned_type_constructor let turbofish = type_constructor
.clone() .clone()
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
.at_least(1) .at_least(1)
@ -470,8 +471,7 @@ pub fn parser<'src>(
), ),
postfix( postfix(
2, 2,
just(Token::Keyword(Keyword::As)) just(Token::Keyword(Keyword::As)).ignore_then(type_constructor.clone()),
.ignore_then(positioned_type_constructor.clone()),
|expression, constructor, span| { |expression, constructor, span| {
Expression::As( Expression::As(
Box::new(As::new(expression, constructor)).with_position(span), Box::new(As::new(expression, constructor)).with_position(span),
@ -576,7 +576,7 @@ pub fn parser<'src>(
let type_assignment = just(Token::Keyword(Keyword::Type)) let type_assignment = just(Token::Keyword(Keyword::Type))
.ignore_then(positioned_identifier.clone()) .ignore_then(positioned_identifier.clone())
.then_ignore(just(Token::Operator(Operator::Assign))) .then_ignore(just(Token::Operator(Operator::Assign)))
.then(positioned_type_constructor.clone()) .then(type_constructor.clone())
.map_with(|(identifier, constructor), state| { .map_with(|(identifier, constructor), state| {
Statement::TypeAssignment( Statement::TypeAssignment(
TypeAssignment::new(identifier, constructor).with_position(state.span()), TypeAssignment::new(identifier, constructor).with_position(state.span()),
@ -619,7 +619,7 @@ mod tests {
Statement::TypeAssignment( Statement::TypeAssignment(
TypeAssignment::new( TypeAssignment::new(
Identifier::new("MyType").with_position((5, 11)), Identifier::new("MyType").with_position((5, 11)),
TypeConstructor::Type(Type::String).with_position((14, 17)) TypeConstructor::Type(Type::String.with_position((14, 17)))
) )
.with_position((0, 17)) .with_position((0, 17))
) )
@ -633,7 +633,7 @@ mod tests {
Statement::ValueExpression(Expression::As( Statement::ValueExpression(Expression::As(
Box::new(As::new( Box::new(As::new(
Expression::Value(ValueNode::Integer(1).with_position((0, 1))), Expression::Value(ValueNode::Integer(1).with_position((0, 1))),
TypeConstructor::Type(Type::String).with_position((5, 8)) TypeConstructor::Type(Type::String.with_position((5, 8)))
)) ))
.with_position((0, 8)) .with_position((0, 8))
)) ))
@ -768,11 +768,11 @@ mod tests {
vec![ vec![
( (
Identifier::new("bar"), Identifier::new("bar"),
TypeConstructor::Type(Type::Integer).with_position((64, 67)) TypeConstructor::Type(Type::Integer.with_position((64, 67)))
), ),
( (
Identifier::new("baz"), Identifier::new("baz"),
TypeConstructor::Type(Type::String).with_position((99, 102)) TypeConstructor::Type(Type::String.with_position((99, 102)))
), ),
] ]
) )
@ -844,7 +844,7 @@ mod tests {
Statement::Assignment( Statement::Assignment(
Assignment::new( Assignment::new(
Identifier::new("foobar").with_position((0, 6)), Identifier::new("foobar").with_position((0, 6)),
Some(TypeConstructor::Type(Type::Boolean).with_position((0, 0))), Some(TypeConstructor::Type(Type::Boolean.with_position((0, 0)))),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::ValueExpression(Expression::Value( Statement::ValueExpression(Expression::Value(
ValueNode::Boolean(true).with_position((16, 20)) ValueNode::Boolean(true).with_position((16, 20))
@ -862,15 +862,15 @@ mod tests {
Statement::Assignment( Statement::Assignment(
Assignment::new( Assignment::new(
Identifier::new("foobar").with_position((0, 6)), Identifier::new("foobar").with_position((0, 6)),
Some( Some(TypeConstructor::List(
TypeConstructor::List { ListTypeConstructor {
length: 2, length: 2,
item_type: Box::new( item_type: Box::new(TypeConstructor::Type(
TypeConstructor::Type(Type::Integer).with_position((0, 0)) Type::Integer.with_position((0, 0))
) ))
} }
.with_position((8, 12)) .with_position((8, 12))
), )),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::ValueExpression(Expression::Value( Statement::ValueExpression(Expression::Value(
ValueNode::List(vec![]).with_position((15, 17)) ValueNode::List(vec![]).with_position((15, 17))
@ -888,7 +888,10 @@ mod tests {
Statement::Assignment( Statement::Assignment(
Assignment::new( Assignment::new(
Identifier::new("foobar").with_position((0, 6)), Identifier::new("foobar").with_position((0, 6)),
Some(TypeConstructor::ListOf(Box::new(Type::Boolean)).with_position((9, 19))), Some(TypeConstructor::ListOf(
Box::new(TypeConstructor::Type(Type::Boolean.with_position((9, 19))))
.with_position((0, 0))
)),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::ValueExpression(Expression::Value( Statement::ValueExpression(Expression::Value(
ValueNode::List(vec![Expression::Value( ValueNode::List(vec![Expression::Value(
@ -909,14 +912,16 @@ mod tests {
Statement::Assignment( Statement::Assignment(
Assignment::new( Assignment::new(
Identifier::new("foobar").with_position((0, 6)), Identifier::new("foobar").with_position((0, 6)),
Some( Some(TypeConstructor::Function(
TypeConstructor::Function { FunctionTypeConstructor {
type_parameters: None, type_parameters: None,
value_parameters: vec![], value_parameters: vec![],
return_type: Box::new(Type::Any), return_type: Box::new(TypeConstructor::Type(
Type::Any.with_position((0, 0))
)),
} }
.with_position((9, 20)) .with_position((9, 20))
), )),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::ValueExpression(Expression::Identifier( Statement::ValueExpression(Expression::Identifier(
Identifier::new("some_function").with_position((23, 36)) Identifier::new("some_function").with_position((23, 36))
@ -949,9 +954,9 @@ mod tests {
Statement::ValueExpression(Expression::FunctionCall( Statement::ValueExpression(Expression::FunctionCall(
FunctionCall::new( FunctionCall::new(
Expression::Identifier(Identifier::new("foobar").with_position((0, 6))), Expression::Identifier(Identifier::new("foobar").with_position((0, 6))),
Some(vec![ Some(vec![TypeConstructor::Type(
TypeConstructor::Type(Type::String).with_position((9, 12)) Type::String.with_position((9, 12))
]), )]),
vec![Expression::Value( vec![Expression::Value(
ValueNode::String("hi".to_string()).with_position((16, 20)) ValueNode::String("hi".to_string()).with_position((16, 20))
)], )],
@ -980,9 +985,9 @@ mod tests {
type_parameters: None, type_parameters: None,
value_parameters: vec![( value_parameters: vec![(
Identifier::new("x"), Identifier::new("x"),
TypeConstructor::Integer.with_position((7, 10)) TypeConstructor::Type(Type::Integer.with_position((7, 10)))
)], )],
return_type: TypeConstructor::Integer.with_position((12, 15)), return_type: TypeConstructor::Type(Type::Integer.with_position((12, 15))),
body: Block::new(vec![Statement::ValueExpression(Expression::Identifier( body: Block::new(vec![Statement::ValueExpression(Expression::Identifier(
Identifier::new("x").with_position((18, 19)) Identifier::new("x").with_position((18, 19))
))]) ))])
@ -1000,21 +1005,26 @@ mod tests {
Statement::ValueExpression(Expression::Value( Statement::ValueExpression(Expression::Value(
ValueNode::ParsedFunction { ValueNode::ParsedFunction {
type_parameters: Some(vec![ type_parameters: Some(vec![
TypeConstructor::Argument(Identifier::new("T")).with_position((4, 5)), Identifier::new("T").with_position((4, 5)),
TypeConstructor::Argument(Identifier::new("U")).with_position((7, 8)), Identifier::new("U").with_position((7, 8)),
]), ]),
value_parameters: vec![ value_parameters: vec![
( (
Identifier::new("x"), Identifier::new("x"),
TypeConstructor::Argument(Identifier::new("T")).with_position((13, 14)) TypeConstructor::Identifier(
Identifier::new("T").with_position((13, 14))
)
), ),
( (
Identifier::new("y"), Identifier::new("y"),
TypeConstructor::Argument(Identifier::new("U")).with_position((19, 20)) TypeConstructor::Identifier(
Identifier::new("U").with_position((19, 20))
)
) )
], ],
return_type: TypeConstructor::Argument(Identifier::new("T")) return_type: TypeConstructor::Identifier(
.with_position((22, 23)), Identifier::new("T").with_position((22, 23))
),
body: Block::new(vec![Statement::ValueExpression(Expression::Identifier( body: Block::new(vec![Statement::ValueExpression(Expression::Identifier(
Identifier::new("x").with_position((26, 27)) Identifier::new("x").with_position((26, 27))
))]) ))])
@ -1299,7 +1309,7 @@ mod tests {
Statement::Assignment( Statement::Assignment(
Assignment::new( Assignment::new(
Identifier::new("foobar").with_position((0, 6)), Identifier::new("foobar").with_position((0, 6)),
Some(TypeConstructor::Integer.with_position((8, 11))), Some(TypeConstructor::Type(Type::Integer.with_position((8, 11)))),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::ValueExpression(Expression::Value( Statement::ValueExpression(Expression::Value(
ValueNode::Integer(1).with_position((14, 15)) ValueNode::Integer(1).with_position((14, 15))