Refine type constructor
This commit is contained in:
parent
e448c9dd4c
commit
9e0c0b4db3
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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())?;
|
||||||
|
@ -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)?;
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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)?;
|
||||||
|
|
||||||
|
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user