Rework enums and type constructors
This commit is contained in:
parent
1593080b8d
commit
a94251e707
@ -8,8 +8,8 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
type_constructor::TypeInvokationConstructor, Evaluate, Evaluation, ExpectedType, Expression,
|
||||
Statement, Type, TypeConstructor, WithPosition,
|
||||
type_constructor::{RawTypeConstructor, TypeInvokationConstructor},
|
||||
Evaluate, Evaluation, ExpectedType, Expression, Statement, Type, TypeConstructor, WithPosition,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
@ -46,7 +46,7 @@ impl Assignment {
|
||||
impl Evaluate for Assignment {
|
||||
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> {
|
||||
if let Some(TypeConstructor::Raw(WithPosition {
|
||||
node: Type::None,
|
||||
node: RawTypeConstructor::None,
|
||||
position,
|
||||
})) = &self.constructor
|
||||
{
|
||||
|
@ -13,7 +13,19 @@ pub enum TypeConstructor {
|
||||
Invokation(TypeInvokationConstructor),
|
||||
List(WithPosition<ListTypeConstructor>),
|
||||
ListOf(WithPosition<Box<TypeConstructor>>),
|
||||
Raw(WithPosition<Type>),
|
||||
Raw(WithPosition<RawTypeConstructor>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub enum RawTypeConstructor {
|
||||
Any,
|
||||
Boolean,
|
||||
Float,
|
||||
Integer,
|
||||
Map,
|
||||
None,
|
||||
Range,
|
||||
String,
|
||||
}
|
||||
|
||||
impl TypeConstructor {
|
||||
@ -140,8 +152,8 @@ impl TypeConstructor {
|
||||
return_type,
|
||||
}
|
||||
}
|
||||
TypeConstructor::List(positioned_constructor) => {
|
||||
let ListTypeConstructor { length, item_type } = positioned_constructor.node;
|
||||
TypeConstructor::List(constructor) => {
|
||||
let ListTypeConstructor { length, item_type } = constructor.node;
|
||||
let constructed_type = item_type.construct(context)?;
|
||||
|
||||
Type::List {
|
||||
@ -154,7 +166,16 @@ impl TypeConstructor {
|
||||
|
||||
Type::ListOf(Box::new(item_type))
|
||||
}
|
||||
TypeConstructor::Raw(r#type) => r#type.node,
|
||||
TypeConstructor::Raw(raw_type) => match raw_type.node {
|
||||
RawTypeConstructor::Any => Type::Any,
|
||||
RawTypeConstructor::Boolean => Type::Boolean,
|
||||
RawTypeConstructor::Float => Type::Float,
|
||||
RawTypeConstructor::Integer => Type::Integer,
|
||||
RawTypeConstructor::Map => Type::Map,
|
||||
RawTypeConstructor::None => Type::None,
|
||||
RawTypeConstructor::Range => Type::Range,
|
||||
RawTypeConstructor::String => Type::String,
|
||||
},
|
||||
};
|
||||
|
||||
Ok(r#type)
|
||||
|
@ -12,7 +12,10 @@ use crate::{
|
||||
lexer::{Control, Keyword, Operator, Token},
|
||||
};
|
||||
|
||||
use self::{enum_declaration::EnumVariant, type_constructor::TypeInvokationConstructor};
|
||||
use self::{
|
||||
enum_declaration::EnumVariant,
|
||||
type_constructor::{RawTypeConstructor, TypeInvokationConstructor},
|
||||
};
|
||||
|
||||
pub type ParserInput<'src> =
|
||||
SpannedInput<Token<'src>, SimpleSpan, &'src [(Token<'src>, SimpleSpan)]>;
|
||||
@ -76,15 +79,18 @@ pub fn parser<'src>(
|
||||
|
||||
let type_constructor = recursive(|type_constructor| {
|
||||
let primitive_type = choice((
|
||||
just(Token::Keyword(Keyword::Any)).to(Type::Any),
|
||||
just(Token::Keyword(Keyword::Bool)).to(Type::Boolean),
|
||||
just(Token::Keyword(Keyword::Float)).to(Type::Float),
|
||||
just(Token::Keyword(Keyword::Int)).to(Type::Integer),
|
||||
just(Token::Keyword(Keyword::None)).to(Type::None),
|
||||
just(Token::Keyword(Keyword::Range)).to(Type::Range),
|
||||
just(Token::Keyword(Keyword::Str)).to(Type::String),
|
||||
just(Token::Keyword(Keyword::Any)).to(RawTypeConstructor::Any),
|
||||
just(Token::Keyword(Keyword::Bool)).to(RawTypeConstructor::Boolean),
|
||||
just(Token::Keyword(Keyword::Float)).to(RawTypeConstructor::Float),
|
||||
just(Token::Keyword(Keyword::Int)).to(RawTypeConstructor::Integer),
|
||||
just(Token::Keyword(Keyword::Map)).to(RawTypeConstructor::Map),
|
||||
just(Token::Keyword(Keyword::None)).to(RawTypeConstructor::None),
|
||||
just(Token::Keyword(Keyword::Range)).to(RawTypeConstructor::Range),
|
||||
just(Token::Keyword(Keyword::Str)).to(RawTypeConstructor::String),
|
||||
))
|
||||
.map_with(|r#type, state| TypeConstructor::Raw(r#type.with_position(state.span())));
|
||||
.map_with(|raw_constructor, state| {
|
||||
TypeConstructor::Raw(raw_constructor.with_position(state.span()))
|
||||
});
|
||||
|
||||
let function_type = just(Token::Keyword(Keyword::Fn))
|
||||
.ignore_then(
|
||||
@ -700,6 +706,7 @@ pub fn parser<'src>(
|
||||
positioned_identifier
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.allow_trailing()
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Operator(Operator::Less)),
|
||||
@ -710,6 +717,8 @@ pub fn parser<'src>(
|
||||
.then(
|
||||
enum_variant
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.allow_trailing()
|
||||
.at_least(1)
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::CurlyOpen)),
|
||||
|
@ -12,7 +12,7 @@ fn type_invokation() {
|
||||
Some(TypeConstructor::Invokation(TypeInvokationConstructor {
|
||||
identifier: Identifier::new("Foo").with_position((3, 6)),
|
||||
type_arguments: Some(vec![TypeConstructor::Raw(
|
||||
Type::Integer.with_position((7, 10))
|
||||
RawTypeConstructor::Integer.with_position((7, 10))
|
||||
)]),
|
||||
})),
|
||||
AssignmentOperator::Assign,
|
||||
@ -55,20 +55,20 @@ fn enum_declaration() {
|
||||
parse(&lex("enum MyEnum { X, Y }").unwrap()).unwrap()[0],
|
||||
Statement::EnumDeclaration(
|
||||
EnumDeclaration {
|
||||
name: Identifier::new("MyEnum").with_position((0, 0)),
|
||||
name: Identifier::new("MyEnum").with_position((5, 11)),
|
||||
type_parameters: None,
|
||||
variants: vec![
|
||||
EnumVariant {
|
||||
name: Identifier::new("X").with_position((0, 0)),
|
||||
name: Identifier::new("X").with_position((14, 15)),
|
||||
content: None
|
||||
},
|
||||
EnumVariant {
|
||||
name: Identifier::new("Y").with_position((0, 0)),
|
||||
name: Identifier::new("Y").with_position((17, 18)),
|
||||
content: None
|
||||
}
|
||||
],
|
||||
}
|
||||
.with_position((0, 0))
|
||||
.with_position((0, 20))
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -79,25 +79,29 @@ fn enum_with_contents() {
|
||||
parse(&lex("enum MyEnum { X(str, int), Y(int) }").unwrap()).unwrap()[0],
|
||||
Statement::EnumDeclaration(
|
||||
EnumDeclaration {
|
||||
name: Identifier::new("MyEnum").with_position((0, 0)),
|
||||
name: Identifier::new("MyEnum").with_position((5, 11)),
|
||||
type_parameters: None,
|
||||
variants: vec![
|
||||
EnumVariant {
|
||||
name: Identifier::new("X").with_position((0, 0)),
|
||||
name: Identifier::new("X").with_position((14, 15)),
|
||||
content: Some(vec![
|
||||
TypeConstructor::Raw(Type::String.with_position((0, 0))),
|
||||
TypeConstructor::Raw(Type::Integer.with_position((0, 0))),
|
||||
TypeConstructor::Raw(
|
||||
RawTypeConstructor::String.with_position((16, 19))
|
||||
),
|
||||
TypeConstructor::Raw(
|
||||
RawTypeConstructor::Integer.with_position((21, 24))
|
||||
),
|
||||
])
|
||||
},
|
||||
EnumVariant {
|
||||
name: Identifier::new("Y").with_position((0, 0)),
|
||||
name: Identifier::new("Y").with_position((27, 28)),
|
||||
content: Some(vec![TypeConstructor::Raw(
|
||||
Type::Integer.with_position((0, 0))
|
||||
RawTypeConstructor::Integer.with_position((29, 32))
|
||||
),])
|
||||
}
|
||||
]
|
||||
}
|
||||
.with_position((0, 0))
|
||||
.with_position((0, 35))
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -108,29 +112,33 @@ fn enum_with_type_parameters() {
|
||||
parse(&lex("enum MyEnum <T, U> { X(T), Y(U) }").unwrap()).unwrap()[0],
|
||||
Statement::EnumDeclaration(
|
||||
EnumDeclaration {
|
||||
name: Identifier::new("MyEnum").with_position((0, 0)),
|
||||
name: Identifier::new("MyEnum").with_position((5, 11)),
|
||||
type_parameters: Some(vec![
|
||||
Identifier::new("T").with_position((0, 0)),
|
||||
Identifier::new("U").with_position((0, 0))
|
||||
Identifier::new("T").with_position((13, 14)),
|
||||
Identifier::new("U").with_position((16, 17))
|
||||
]),
|
||||
variants: vec![
|
||||
EnumVariant {
|
||||
name: Identifier::new("X").with_position((0, 0)),
|
||||
content: Some(vec![TypeConstructor::Raw(
|
||||
Type::Generic {
|
||||
identifier: Identifier::new("T"),
|
||||
concrete_type: None
|
||||
name: Identifier::new("X").with_position((21, 22)),
|
||||
content: Some(vec![TypeConstructor::Invokation(
|
||||
TypeInvokationConstructor {
|
||||
identifier: Identifier::new("T").with_position((23, 24)),
|
||||
type_arguments: None
|
||||
}
|
||||
.with_position((0, 0))
|
||||
)])
|
||||
},
|
||||
EnumVariant {
|
||||
name: todo!(),
|
||||
content: todo!()
|
||||
name: Identifier::new("Y").with_position((27, 28)),
|
||||
content: Some(vec![TypeConstructor::Invokation(
|
||||
TypeInvokationConstructor {
|
||||
identifier: Identifier::new("U").with_position((29, 30)),
|
||||
type_arguments: None
|
||||
}
|
||||
)])
|
||||
},
|
||||
]
|
||||
}
|
||||
.with_position((0, 0))
|
||||
.with_position((0, 33))
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -209,7 +217,7 @@ fn r#as() {
|
||||
Statement::Expression(Expression::As(
|
||||
Box::new(As::new(
|
||||
Expression::Value(ValueNode::Integer(1).with_position((0, 1))),
|
||||
TypeConstructor::Raw(Type::String.with_position((5, 8)))
|
||||
TypeConstructor::Raw(RawTypeConstructor::String.with_position((5, 8)))
|
||||
))
|
||||
.with_position((0, 8))
|
||||
))
|
||||
@ -352,7 +360,9 @@ fn boolean_type() {
|
||||
Statement::Assignment(
|
||||
Assignment::new(
|
||||
Identifier::new("foobar").with_position((0, 6)),
|
||||
Some(TypeConstructor::Raw(Type::Boolean.with_position((9, 13)))),
|
||||
Some(TypeConstructor::Raw(
|
||||
RawTypeConstructor::Boolean.with_position((9, 13))
|
||||
)),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(
|
||||
ValueNode::Boolean(true).with_position((16, 20))
|
||||
@ -374,7 +384,7 @@ fn list_type() {
|
||||
ListTypeConstructor {
|
||||
length: 2,
|
||||
item_type: Box::new(TypeConstructor::Raw(
|
||||
Type::Integer.with_position((9, 12))
|
||||
RawTypeConstructor::Integer.with_position((9, 12))
|
||||
))
|
||||
}
|
||||
.with_position((8, 16))
|
||||
@ -397,7 +407,9 @@ fn list_of_type() {
|
||||
Assignment::new(
|
||||
Identifier::new("foobar").with_position((0, 6)),
|
||||
Some(TypeConstructor::ListOf(
|
||||
Box::new(TypeConstructor::Raw(Type::Boolean.with_position((10, 14))))
|
||||
Box::new(TypeConstructor::Raw(
|
||||
RawTypeConstructor::Boolean.with_position((10, 14))
|
||||
))
|
||||
.with_position((9, 15))
|
||||
)),
|
||||
AssignmentOperator::Assign,
|
||||
@ -419,24 +431,24 @@ fn function_type() {
|
||||
parse(&lex("type Foo = fn |T| (int) -> T").unwrap()).unwrap()[0],
|
||||
Statement::TypeAlias(
|
||||
TypeAlias::new(
|
||||
Identifier::new("Foo").with_position((0, 0)),
|
||||
Identifier::new("Foo").with_position((5, 8)),
|
||||
TypeConstructor::Function(
|
||||
FunctionTypeConstructor {
|
||||
type_parameters: Some(vec![Identifier::new("T").with_position((0, 0))]),
|
||||
type_parameters: Some(vec![Identifier::new("T").with_position((15, 16))]),
|
||||
value_parameters: vec![TypeConstructor::Raw(
|
||||
Type::Integer.with_position((0, 0))
|
||||
RawTypeConstructor::Integer.with_position((19, 22))
|
||||
)],
|
||||
return_type: Box::new(TypeConstructor::Invokation(
|
||||
TypeInvokationConstructor {
|
||||
identifier: Identifier::new("T").with_position((0, 0)),
|
||||
identifier: Identifier::new("T").with_position((27, 28)),
|
||||
type_arguments: None
|
||||
}
|
||||
))
|
||||
}
|
||||
.with_position((0, 0))
|
||||
.with_position((11, 28))
|
||||
)
|
||||
)
|
||||
.with_position((0, 0))
|
||||
.with_position((0, 28))
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -464,7 +476,7 @@ fn function_call_with_type_arguments() {
|
||||
FunctionCall::new(
|
||||
Expression::Identifier(Identifier::new("foobar").with_position((0, 6))),
|
||||
Some(vec![TypeConstructor::Raw(
|
||||
Type::String.with_position((9, 12))
|
||||
RawTypeConstructor::String.with_position((9, 12))
|
||||
)]),
|
||||
vec![Expression::Value(
|
||||
ValueNode::String("hi".to_string()).with_position((16, 20))
|
||||
@ -493,7 +505,9 @@ fn function() {
|
||||
ValueNode::Function {
|
||||
type_parameters: None,
|
||||
value_parameters: vec![],
|
||||
return_type: TypeConstructor::Raw(Type::Integer.with_position((9, 12))),
|
||||
return_type: TypeConstructor::Raw(
|
||||
RawTypeConstructor::Integer.with_position((9, 12))
|
||||
),
|
||||
body: Block::new(vec![Statement::Expression(Expression::Value(
|
||||
ValueNode::Integer(0).with_position((15, 16))
|
||||
))])
|
||||
@ -510,9 +524,11 @@ fn function() {
|
||||
type_parameters: None,
|
||||
value_parameters: vec![(
|
||||
Identifier::new("x"),
|
||||
TypeConstructor::Raw(Type::Integer.with_position((7, 10)))
|
||||
TypeConstructor::Raw(RawTypeConstructor::Integer.with_position((7, 10)))
|
||||
)],
|
||||
return_type: TypeConstructor::Raw(Type::Integer.with_position((15, 18))),
|
||||
return_type: TypeConstructor::Raw(
|
||||
RawTypeConstructor::Integer.with_position((15, 18))
|
||||
),
|
||||
body: Block::new(vec![Statement::Expression(Expression::Identifier(
|
||||
Identifier::new("x").with_position((21, 22))
|
||||
))])
|
||||
@ -832,7 +848,9 @@ fn assignment_with_type() {
|
||||
Statement::Assignment(
|
||||
Assignment::new(
|
||||
Identifier::new("foobar").with_position((0, 6)),
|
||||
Some(TypeConstructor::Raw(Type::Integer.with_position((8, 11)))),
|
||||
Some(TypeConstructor::Raw(
|
||||
RawTypeConstructor::Integer.with_position((8, 11))
|
||||
)),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(
|
||||
ValueNode::Integer(1).with_position((14, 15))
|
||||
|
@ -6,7 +6,7 @@ fn simple_enum() {
|
||||
interpret(
|
||||
"test",
|
||||
"
|
||||
type FooBar = enum {
|
||||
enum FooBar {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
@ -28,7 +28,7 @@ fn big_enum() {
|
||||
interpret(
|
||||
"test",
|
||||
"
|
||||
type FooBarBaz = enum |T, U, V| {
|
||||
enum FooBarBaz <T, U, V> {
|
||||
Foo(T),
|
||||
Bar(U),
|
||||
Baz(V),
|
||||
|
Loading…
Reference in New Issue
Block a user