Begin converting type assingment to declarations
This commit is contained in:
parent
0b8880ae55
commit
e429693364
83
dust-lang/src/abstract_tree/enum_declaration.rs
Normal file
83
dust-lang/src/abstract_tree/enum_declaration.rs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
context::Context,
|
||||||
|
error::{RuntimeError, ValidationError},
|
||||||
|
identifier::Identifier,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{Evaluate, Evaluation, Type, TypeConstructor, WithPosition};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
pub struct EnumDeclaration {
|
||||||
|
pub name: WithPosition<Identifier>,
|
||||||
|
pub type_parameters: Option<Vec<WithPosition<Identifier>>>,
|
||||||
|
pub variants: Vec<EnumVariant>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Evaluate for EnumDeclaration {
|
||||||
|
fn validate(
|
||||||
|
&self,
|
||||||
|
_context: &mut Context,
|
||||||
|
_manage_memory: bool,
|
||||||
|
) -> Result<(), ValidationError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn evaluate(
|
||||||
|
self,
|
||||||
|
context: &mut Context,
|
||||||
|
_manage_memory: bool,
|
||||||
|
) -> Result<Evaluation, RuntimeError> {
|
||||||
|
let EnumDeclaration {
|
||||||
|
name,
|
||||||
|
type_parameters,
|
||||||
|
variants,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
let type_parameters = type_parameters.as_ref().map(|parameters| {
|
||||||
|
parameters
|
||||||
|
.iter()
|
||||||
|
.map(|identifier| Type::Generic {
|
||||||
|
identifier: identifier.node.clone(),
|
||||||
|
concrete_type: None,
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
});
|
||||||
|
let mut type_variants = Vec::with_capacity(variants.len());
|
||||||
|
|
||||||
|
for EnumVariant { name, content } in variants {
|
||||||
|
let types = if let Some(content) = content {
|
||||||
|
let mut types = Vec::with_capacity(content.len());
|
||||||
|
|
||||||
|
for constructor in content {
|
||||||
|
let r#type = constructor.construct(&context)?;
|
||||||
|
|
||||||
|
types.push(r#type);
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(types)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
type_variants.push((name.node, types));
|
||||||
|
}
|
||||||
|
|
||||||
|
let r#type = Type::Enum {
|
||||||
|
name: name.node.clone(),
|
||||||
|
type_parameters,
|
||||||
|
variants: type_variants,
|
||||||
|
};
|
||||||
|
|
||||||
|
context.set_type(name.node, r#type)?;
|
||||||
|
|
||||||
|
Ok(Evaluation::None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
pub struct EnumVariant {
|
||||||
|
pub name: WithPosition<Identifier>,
|
||||||
|
pub content: Option<Vec<TypeConstructor>>,
|
||||||
|
}
|
@ -3,6 +3,7 @@ pub mod assignment;
|
|||||||
pub mod async_block;
|
pub mod async_block;
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod built_in_function_call;
|
pub mod built_in_function_call;
|
||||||
|
pub mod enum_declaration;
|
||||||
pub mod expression;
|
pub mod expression;
|
||||||
pub mod function_call;
|
pub mod function_call;
|
||||||
pub mod if_else;
|
pub mod if_else;
|
||||||
@ -14,7 +15,7 @@ pub mod math;
|
|||||||
pub mod statement;
|
pub mod statement;
|
||||||
pub mod structure_definition;
|
pub mod structure_definition;
|
||||||
pub mod r#type;
|
pub mod r#type;
|
||||||
pub mod type_assignment;
|
pub mod type_alias;
|
||||||
pub mod type_constructor;
|
pub mod type_constructor;
|
||||||
pub mod value_node;
|
pub mod value_node;
|
||||||
pub mod r#while;
|
pub mod r#while;
|
||||||
@ -29,6 +30,7 @@ pub use self::{
|
|||||||
async_block::AsyncBlock,
|
async_block::AsyncBlock,
|
||||||
block::Block,
|
block::Block,
|
||||||
built_in_function_call::BuiltInFunctionCall,
|
built_in_function_call::BuiltInFunctionCall,
|
||||||
|
enum_declaration::{EnumDeclaration, EnumVariant},
|
||||||
expression::Expression,
|
expression::Expression,
|
||||||
function_call::FunctionCall,
|
function_call::FunctionCall,
|
||||||
if_else::IfElse,
|
if_else::IfElse,
|
||||||
@ -42,7 +44,7 @@ pub use self::{
|
|||||||
r#while::While,
|
r#while::While,
|
||||||
statement::Statement,
|
statement::Statement,
|
||||||
structure_definition::StructureDefinition,
|
structure_definition::StructureDefinition,
|
||||||
type_assignment::TypeAssignment,
|
type_alias::TypeAlias,
|
||||||
type_constructor::{
|
type_constructor::{
|
||||||
EnumTypeConstructor, FunctionTypeConstructor, ListTypeConstructor, TypeConstructor,
|
EnumTypeConstructor, FunctionTypeConstructor, ListTypeConstructor, TypeConstructor,
|
||||||
},
|
},
|
||||||
|
@ -6,8 +6,8 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Assignment, AsyncBlock, Block, Evaluate, Evaluation, ExpectedType, Expression, IfElse, Loop,
|
Assignment, AsyncBlock, Block, EnumDeclaration, Evaluate, Evaluation, ExpectedType, Expression,
|
||||||
SourcePosition, StructureDefinition, Type, TypeAssignment, While, WithPosition,
|
IfElse, Loop, SourcePosition, StructureDefinition, Type, TypeAlias, While, WithPosition,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
@ -19,7 +19,8 @@ pub enum Statement {
|
|||||||
IfElse(WithPosition<IfElse>),
|
IfElse(WithPosition<IfElse>),
|
||||||
Loop(WithPosition<Loop>),
|
Loop(WithPosition<Loop>),
|
||||||
StructureDefinition(WithPosition<StructureDefinition>),
|
StructureDefinition(WithPosition<StructureDefinition>),
|
||||||
TypeAssignment(WithPosition<TypeAssignment>),
|
TypeAlias(WithPosition<TypeAlias>),
|
||||||
|
EnumDeclaration(WithPosition<EnumDeclaration>),
|
||||||
Expression(Expression),
|
Expression(Expression),
|
||||||
While(WithPosition<While>),
|
While(WithPosition<While>),
|
||||||
}
|
}
|
||||||
@ -35,7 +36,8 @@ impl Statement {
|
|||||||
Statement::IfElse(inner) => inner.position,
|
Statement::IfElse(inner) => inner.position,
|
||||||
Statement::Loop(inner) => inner.position,
|
Statement::Loop(inner) => inner.position,
|
||||||
Statement::StructureDefinition(inner) => inner.position,
|
Statement::StructureDefinition(inner) => inner.position,
|
||||||
Statement::TypeAssignment(inner) => inner.position,
|
Statement::TypeAlias(inner) => inner.position,
|
||||||
|
Statement::EnumDeclaration(inner) => inner.position,
|
||||||
Statement::While(inner) => inner.position,
|
Statement::While(inner) => inner.position,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,8 +70,9 @@ impl Evaluate for Statement {
|
|||||||
Statement::StructureDefinition(structure_definition) => {
|
Statement::StructureDefinition(structure_definition) => {
|
||||||
structure_definition.node.validate(_context, _manage_memory)
|
structure_definition.node.validate(_context, _manage_memory)
|
||||||
}
|
}
|
||||||
Statement::TypeAssignment(type_alias) => {
|
Statement::TypeAlias(type_alias) => type_alias.node.validate(_context, _manage_memory),
|
||||||
type_alias.node.validate(_context, _manage_memory)
|
Statement::EnumDeclaration(type_declaration) => {
|
||||||
|
type_declaration.node.validate(_context, _manage_memory)
|
||||||
}
|
}
|
||||||
Statement::While(r#while) => r#while.node.validate(_context, _manage_memory),
|
Statement::While(r#while) => r#while.node.validate(_context, _manage_memory),
|
||||||
}
|
}
|
||||||
@ -91,7 +94,8 @@ impl Evaluate for Statement {
|
|||||||
Statement::StructureDefinition(structure_definition) => {
|
Statement::StructureDefinition(structure_definition) => {
|
||||||
structure_definition.node.evaluate(context, manage_memory)
|
structure_definition.node.evaluate(context, manage_memory)
|
||||||
}
|
}
|
||||||
Statement::TypeAssignment(type_alias) => {
|
Statement::TypeAlias(type_alias) => type_alias.node.evaluate(context, manage_memory),
|
||||||
|
Statement::EnumDeclaration(type_alias) => {
|
||||||
type_alias.node.evaluate(context, manage_memory)
|
type_alias.node.evaluate(context, manage_memory)
|
||||||
}
|
}
|
||||||
Statement::While(r#while) => r#while.node.evaluate(context, manage_memory),
|
Statement::While(r#while) => r#while.node.evaluate(context, manage_memory),
|
||||||
|
@ -16,6 +16,7 @@ pub enum Type {
|
|||||||
Any,
|
Any,
|
||||||
Boolean,
|
Boolean,
|
||||||
Enum {
|
Enum {
|
||||||
|
name: Identifier,
|
||||||
type_parameters: Option<Vec<Type>>,
|
type_parameters: Option<Vec<Type>>,
|
||||||
variants: Vec<(Identifier, Option<Vec<Type>>)>,
|
variants: Vec<(Identifier, Option<Vec<Type>>)>,
|
||||||
},
|
},
|
||||||
|
@ -9,12 +9,12 @@ use crate::{
|
|||||||
use super::{Evaluate, Evaluation, TypeConstructor, WithPosition};
|
use super::{Evaluate, 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 TypeAlias {
|
||||||
identifier: WithPosition<Identifier>,
|
identifier: WithPosition<Identifier>,
|
||||||
constructor: TypeConstructor,
|
constructor: TypeConstructor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeAssignment {
|
impl TypeAlias {
|
||||||
pub fn new(identifier: WithPosition<Identifier>, constructor: TypeConstructor) -> Self {
|
pub fn new(identifier: WithPosition<Identifier>, constructor: TypeConstructor) -> Self {
|
||||||
Self {
|
Self {
|
||||||
identifier,
|
identifier,
|
||||||
@ -23,7 +23,7 @@ impl TypeAssignment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Evaluate for TypeAssignment {
|
impl Evaluate for TypeAlias {
|
||||||
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> {
|
||||||
let r#type = self.constructor.clone().construct(&context)?;
|
let r#type = self.constructor.clone().construct(&context)?;
|
||||||
|
|
@ -53,6 +53,7 @@ impl TypeConstructor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Type::Enum {
|
if let Type::Enum {
|
||||||
|
name,
|
||||||
type_parameters,
|
type_parameters,
|
||||||
variants,
|
variants,
|
||||||
} = invoked_type
|
} = invoked_type
|
||||||
@ -64,6 +65,7 @@ impl TypeConstructor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type::Enum {
|
Type::Enum {
|
||||||
|
name,
|
||||||
type_parameters: type_parameters.clone(),
|
type_parameters: type_parameters.clone(),
|
||||||
variants: mapped_variants,
|
variants: mapped_variants,
|
||||||
}
|
}
|
||||||
@ -73,6 +75,7 @@ impl TypeConstructor {
|
|||||||
}
|
}
|
||||||
TypeConstructor::Enum(enum_type_constructor) => {
|
TypeConstructor::Enum(enum_type_constructor) => {
|
||||||
let EnumTypeConstructor {
|
let EnumTypeConstructor {
|
||||||
|
name,
|
||||||
type_parameters,
|
type_parameters,
|
||||||
variants,
|
variants,
|
||||||
} = enum_type_constructor.node;
|
} = enum_type_constructor.node;
|
||||||
@ -95,6 +98,7 @@ impl TypeConstructor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type::Enum {
|
Type::Enum {
|
||||||
|
name: name.node,
|
||||||
type_parameters: type_parameters.map(|identifiers| {
|
type_parameters: type_parameters.map(|identifiers| {
|
||||||
identifiers
|
identifiers
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -165,6 +169,7 @@ impl Display for TypeConstructor {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct EnumTypeConstructor {
|
pub struct EnumTypeConstructor {
|
||||||
|
pub name: WithPosition<Identifier>,
|
||||||
pub type_parameters: Option<Vec<WithPosition<Identifier>>>,
|
pub type_parameters: Option<Vec<WithPosition<Identifier>>>,
|
||||||
pub variants: Vec<(WithPosition<Identifier>, Option<Vec<TypeConstructor>>)>,
|
pub variants: Vec<(WithPosition<Identifier>, Option<Vec<TypeConstructor>>)>,
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use crate::{
|
|||||||
lexer::{Control, Keyword, Operator, Token},
|
lexer::{Control, Keyword, Operator, Token},
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::type_constructor::TypeInvokationConstructor;
|
use self::{enum_declaration::EnumVariant, type_constructor::TypeInvokationConstructor};
|
||||||
|
|
||||||
pub type ParserInput<'src> =
|
pub type ParserInput<'src> =
|
||||||
SpannedInput<Token<'src>, SimpleSpan, &'src [(Token<'src>, SimpleSpan)]>;
|
SpannedInput<Token<'src>, SimpleSpan, &'src [(Token<'src>, SimpleSpan)]>;
|
||||||
@ -149,51 +149,6 @@ pub fn parser<'src>(
|
|||||||
TypeConstructor::ListOf(Box::new(item_type).with_position(state.span()))
|
TypeConstructor::ListOf(Box::new(item_type).with_position(state.span()))
|
||||||
});
|
});
|
||||||
|
|
||||||
let enum_variant = positioned_identifier.clone().then(
|
|
||||||
type_constructor
|
|
||||||
.clone()
|
|
||||||
.separated_by(just(Token::Control(Control::Comma)))
|
|
||||||
.collect()
|
|
||||||
.delimited_by(
|
|
||||||
just(Token::Control(Control::ParenOpen)),
|
|
||||||
just(Token::Control(Control::ParenClose)),
|
|
||||||
)
|
|
||||||
.or_not(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let enum_type = just(Token::Keyword(Keyword::Enum))
|
|
||||||
.ignore_then(
|
|
||||||
positioned_identifier
|
|
||||||
.clone()
|
|
||||||
.separated_by(just(Token::Control(Control::Comma)))
|
|
||||||
.collect()
|
|
||||||
.delimited_by(
|
|
||||||
just(Token::Control(Control::Pipe)),
|
|
||||||
just(Token::Control(Control::Pipe)),
|
|
||||||
)
|
|
||||||
.or_not(),
|
|
||||||
)
|
|
||||||
.then(
|
|
||||||
enum_variant
|
|
||||||
.separated_by(just(Token::Control(Control::Comma)))
|
|
||||||
.at_least(1)
|
|
||||||
.allow_trailing()
|
|
||||||
.collect()
|
|
||||||
.delimited_by(
|
|
||||||
just(Token::Control(Control::CurlyOpen)),
|
|
||||||
just(Token::Control(Control::CurlyClose)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.map_with(|(type_parameters, variants), state| {
|
|
||||||
TypeConstructor::Enum(
|
|
||||||
EnumTypeConstructor {
|
|
||||||
type_parameters,
|
|
||||||
variants,
|
|
||||||
}
|
|
||||||
.with_position(state.span()),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
let type_invokation = positioned_identifier
|
let type_invokation = positioned_identifier
|
||||||
.clone()
|
.clone()
|
||||||
.then(
|
.then(
|
||||||
@ -222,7 +177,6 @@ pub fn parser<'src>(
|
|||||||
list_type,
|
list_type,
|
||||||
list_of_type,
|
list_of_type,
|
||||||
primitive_type,
|
primitive_type,
|
||||||
enum_type,
|
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -709,13 +663,64 @@ pub fn parser<'src>(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let type_assignment = just(Token::Keyword(Keyword::Type))
|
let type_alias = 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(type_constructor.clone())
|
.then(type_constructor.clone())
|
||||||
.map_with(|(identifier, constructor), state| {
|
.map_with(|(identifier, constructor), state| {
|
||||||
Statement::TypeAssignment(
|
Statement::TypeAlias(
|
||||||
TypeAssignment::new(identifier, constructor).with_position(state.span()),
|
TypeAlias::new(identifier, constructor).with_position(state.span()),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let enum_variant = positioned_identifier
|
||||||
|
.clone()
|
||||||
|
.then(
|
||||||
|
type_constructor
|
||||||
|
.clone()
|
||||||
|
.separated_by(just(Token::Control(Control::Comma)))
|
||||||
|
.collect()
|
||||||
|
.delimited_by(
|
||||||
|
just(Token::Control(Control::ParenOpen)),
|
||||||
|
just(Token::Control(Control::ParenClose)),
|
||||||
|
)
|
||||||
|
.or_not(),
|
||||||
|
)
|
||||||
|
.map(|(identifier, constructors)| EnumVariant {
|
||||||
|
name: identifier,
|
||||||
|
content: constructors,
|
||||||
|
});
|
||||||
|
|
||||||
|
let enum_declaration = just(Token::Keyword(Keyword::Enum))
|
||||||
|
.ignore_then(positioned_identifier.clone())
|
||||||
|
.then(
|
||||||
|
positioned_identifier
|
||||||
|
.clone()
|
||||||
|
.separated_by(just(Token::Control(Control::Comma)))
|
||||||
|
.collect()
|
||||||
|
.delimited_by(
|
||||||
|
just(Token::Operator(Operator::Less)),
|
||||||
|
just(Token::Operator(Operator::Greater)),
|
||||||
|
)
|
||||||
|
.or_not(),
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
enum_variant
|
||||||
|
.separated_by(just(Token::Control(Control::Comma)))
|
||||||
|
.collect()
|
||||||
|
.delimited_by(
|
||||||
|
just(Token::Control(Control::CurlyOpen)),
|
||||||
|
just(Token::Control(Control::CurlyClose)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map_with(|((name, type_parameters), variants), state| {
|
||||||
|
Statement::EnumDeclaration(
|
||||||
|
EnumDeclaration {
|
||||||
|
name,
|
||||||
|
type_parameters,
|
||||||
|
variants,
|
||||||
|
}
|
||||||
|
.with_position((0, 0)),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -731,7 +736,8 @@ pub fn parser<'src>(
|
|||||||
block_statement,
|
block_statement,
|
||||||
r#loop,
|
r#loop,
|
||||||
r#while,
|
r#while,
|
||||||
type_assignment,
|
type_alias,
|
||||||
|
enum_declaration,
|
||||||
)))
|
)))
|
||||||
.then_ignore(just(Token::Control(Control::Semicolon)).or_not())
|
.then_ignore(just(Token::Control(Control::Semicolon)).or_not())
|
||||||
});
|
});
|
||||||
@ -741,6 +747,8 @@ pub fn parser<'src>(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use tests::enum_declaration::{EnumDeclaration, EnumVariant};
|
||||||
|
|
||||||
use crate::lexer::lex;
|
use crate::lexer::lex;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -793,103 +801,88 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn enum_type_empty() {
|
fn enum_declaration() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("type MyEnum = enum { X, Y }").unwrap()).unwrap()[0],
|
parse(&lex("enum MyEnum { X, Y }").unwrap()).unwrap()[0],
|
||||||
Statement::TypeAssignment(
|
Statement::EnumDeclaration(TypeDeclaration::Enum(
|
||||||
TypeAssignment::new(
|
EnumDeclaration {
|
||||||
Identifier::new("MyEnum").with_position((5, 11)),
|
name: Identifier::new("MyEnum").with_position((0, 0)),
|
||||||
TypeConstructor::Enum(
|
type_parameters: None,
|
||||||
EnumTypeConstructor {
|
variants: vec![
|
||||||
type_parameters: None,
|
EnumVariant {
|
||||||
variants: vec![
|
name: Identifier::new("X").with_position((0, 0)),
|
||||||
(Identifier::new("X").with_position((21, 22)), None),
|
content: None
|
||||||
(Identifier::new("Y").with_position((24, 25)), None)
|
},
|
||||||
],
|
EnumVariant {
|
||||||
|
name: Identifier::new("Y").with_position((0, 0)),
|
||||||
|
content: None
|
||||||
}
|
}
|
||||||
.with_position((14, 27))
|
],
|
||||||
)
|
}
|
||||||
)
|
.with_position((0, 0))
|
||||||
.with_position((0, 27))
|
))
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn enum_type_with_contents() {
|
fn enum_with_contents() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("type MyEnum = enum { X(str, int), Y(int) }").unwrap()).unwrap()[0],
|
parse(&lex("enum MyEnum { X(str, int), Y(int) }").unwrap()).unwrap()[0],
|
||||||
Statement::TypeAssignment(
|
Statement::EnumDeclaration(TypeDeclaration::Enum(
|
||||||
TypeAssignment::new(
|
EnumDeclaration {
|
||||||
Identifier::new("MyEnum").with_position((5, 11)),
|
name: Identifier::new("MyEnum").with_position((0, 0)),
|
||||||
TypeConstructor::Enum(
|
type_parameters: None,
|
||||||
EnumTypeConstructor {
|
variants: vec![
|
||||||
type_parameters: None,
|
EnumVariant {
|
||||||
variants: vec![
|
name: Identifier::new("X").with_position((0, 0)),
|
||||||
(
|
content: Some(vec![
|
||||||
Identifier::new("X").with_position((21, 22)),
|
TypeConstructor::Raw(Type::String.with_position((0, 0))),
|
||||||
Some(vec![
|
TypeConstructor::Raw(Type::Integer.with_position((0, 0))),
|
||||||
TypeConstructor::Raw(Type::String.with_position((23, 26))),
|
])
|
||||||
TypeConstructor::Raw(Type::Integer.with_position((28, 31)))
|
},
|
||||||
])
|
EnumVariant {
|
||||||
),
|
name: Identifier::new("Y").with_position((0, 0)),
|
||||||
(
|
content: Some(vec![TypeConstructor::Raw(
|
||||||
Identifier::new("Y").with_position((34, 35)),
|
Type::Integer.with_position((0, 0))
|
||||||
Some(vec![TypeConstructor::Raw(
|
),])
|
||||||
Type::Integer.with_position((36, 39))
|
|
||||||
)])
|
|
||||||
)
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
.with_position((14, 42))
|
]
|
||||||
)
|
}
|
||||||
)
|
.with_position((0, 0))
|
||||||
.with_position((0, 42))
|
))
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn enum_type_with_type_parameters() {
|
fn enum_with_type_parameters() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("type MyEnum = enum |T, U| { X(T), Y(U) }").unwrap()).unwrap()[0],
|
parse(&lex("enum MyEnum <T, U> { X(T), Y(U) }").unwrap()).unwrap()[0],
|
||||||
Statement::TypeAssignment(
|
Statement::EnumDeclaration(TypeDeclaration::Enum(
|
||||||
TypeAssignment::new(
|
EnumDeclaration {
|
||||||
Identifier::new("MyEnum").with_position((5, 11)),
|
name: Identifier::new("MyEnum").with_position((0, 0)),
|
||||||
TypeConstructor::Enum(
|
type_parameters: Some(vec![
|
||||||
EnumTypeConstructor {
|
Identifier::new("T").with_position((0, 0)),
|
||||||
type_parameters: Some(vec![
|
Identifier::new("U").with_position((0, 0))
|
||||||
Identifier::new("T").with_position((20, 21)),
|
]),
|
||||||
Identifier::new("U").with_position((23, 24)),
|
variants: vec![
|
||||||
]),
|
EnumVariant {
|
||||||
variants: vec![
|
name: Identifier::new("X").with_position((0, 0)),
|
||||||
(
|
content: Some(vec![TypeConstructor::Raw(
|
||||||
Identifier::new("X").with_position((28, 29)),
|
Type::Generic {
|
||||||
Some(vec![TypeConstructor::Invokation(
|
identifier: Identifier::new("T"),
|
||||||
TypeInvokationConstructor {
|
concrete_type: None
|
||||||
identifier: Identifier::new("T")
|
}
|
||||||
.with_position((30, 31)),
|
.with_position((0, 0))
|
||||||
type_arguments: None,
|
)])
|
||||||
}
|
},
|
||||||
)])
|
EnumVariant {
|
||||||
),
|
name: todo!(),
|
||||||
(
|
content: todo!()
|
||||||
Identifier::new("Y").with_position((34, 35)),
|
|
||||||
Some(vec![TypeConstructor::Invokation(
|
|
||||||
TypeInvokationConstructor {
|
|
||||||
identifier: Identifier::new("U")
|
|
||||||
.with_position((36, 37)),
|
|
||||||
type_arguments: None,
|
|
||||||
}
|
|
||||||
)])
|
|
||||||
),
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
.with_position((14, 40))
|
]
|
||||||
)
|
}
|
||||||
)
|
.with_position((0, 0))
|
||||||
.with_position((0, 40))
|
))
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -960,20 +953,6 @@ mod tests {
|
|||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn type_alias() {
|
|
||||||
assert_eq!(
|
|
||||||
parse(&lex("type MyType = str").unwrap()).unwrap()[0],
|
|
||||||
Statement::TypeAssignment(
|
|
||||||
TypeAssignment::new(
|
|
||||||
Identifier::new("MyType").with_position((5, 11)),
|
|
||||||
TypeConstructor::Raw(Type::String.with_position((14, 17)))
|
|
||||||
)
|
|
||||||
.with_position((0, 17))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn r#as() {
|
fn r#as() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -1191,28 +1170,26 @@ mod tests {
|
|||||||
fn function_type() {
|
fn function_type() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("type Foo = fn |T| (int) -> T").unwrap()).unwrap()[0],
|
parse(&lex("type Foo = fn |T| (int) -> T").unwrap()).unwrap()[0],
|
||||||
Statement::TypeAssignment(
|
Statement::TypeAlias(
|
||||||
TypeAssignment::new(
|
TypeAlias::new(
|
||||||
Identifier::new("Foo").with_position((5, 8)),
|
Identifier::new("Foo").with_position((0, 0)),
|
||||||
TypeConstructor::Function(
|
TypeConstructor::Function(
|
||||||
FunctionTypeConstructor {
|
FunctionTypeConstructor {
|
||||||
type_parameters: Some(vec![
|
type_parameters: Some(vec![Identifier::new("T").with_position((0, 0))]),
|
||||||
Identifier::new("T").with_position((15, 16))
|
|
||||||
]),
|
|
||||||
value_parameters: vec![TypeConstructor::Raw(
|
value_parameters: vec![TypeConstructor::Raw(
|
||||||
Type::Integer.with_position((19, 22))
|
Type::Integer.with_position((0, 0))
|
||||||
)],
|
)],
|
||||||
return_type: Box::new(TypeConstructor::Invokation(
|
return_type: Box::new(TypeConstructor::Invokation(
|
||||||
TypeInvokationConstructor {
|
TypeInvokationConstructor {
|
||||||
identifier: Identifier::new("T").with_position((27, 28)),
|
identifier: Identifier::new("T").with_position((0, 0)),
|
||||||
type_arguments: None,
|
type_arguments: None
|
||||||
}
|
}
|
||||||
)),
|
))
|
||||||
}
|
}
|
||||||
.with_position((11, 28))
|
.with_position((0, 0))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.with_position((0, 28))
|
.with_position((0, 0))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user