Rework enums and type constructors

This commit is contained in:
Jeff 2024-06-20 18:41:07 -04:00
parent 1593080b8d
commit a94251e707
5 changed files with 107 additions and 59 deletions

View File

@ -8,8 +8,8 @@ use crate::{
}; };
use super::{ use super::{
type_constructor::TypeInvokationConstructor, Evaluate, Evaluation, ExpectedType, Expression, type_constructor::{RawTypeConstructor, TypeInvokationConstructor},
Statement, Type, TypeConstructor, WithPosition, Evaluate, Evaluation, ExpectedType, Expression, Statement, Type, TypeConstructor, WithPosition,
}; };
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
@ -46,7 +46,7 @@ impl Assignment {
impl Evaluate for Assignment { impl Evaluate for Assignment {
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> {
if let Some(TypeConstructor::Raw(WithPosition { if let Some(TypeConstructor::Raw(WithPosition {
node: Type::None, node: RawTypeConstructor::None,
position, position,
})) = &self.constructor })) = &self.constructor
{ {

View File

@ -13,7 +13,19 @@ pub enum TypeConstructor {
Invokation(TypeInvokationConstructor), Invokation(TypeInvokationConstructor),
List(WithPosition<ListTypeConstructor>), List(WithPosition<ListTypeConstructor>),
ListOf(WithPosition<Box<TypeConstructor>>), 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 { impl TypeConstructor {
@ -140,8 +152,8 @@ impl TypeConstructor {
return_type, return_type,
} }
} }
TypeConstructor::List(positioned_constructor) => { TypeConstructor::List(constructor) => {
let ListTypeConstructor { length, item_type } = positioned_constructor.node; let ListTypeConstructor { length, item_type } = constructor.node;
let constructed_type = item_type.construct(context)?; let constructed_type = item_type.construct(context)?;
Type::List { Type::List {
@ -154,7 +166,16 @@ impl TypeConstructor {
Type::ListOf(Box::new(item_type)) 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) Ok(r#type)

View File

@ -12,7 +12,10 @@ use crate::{
lexer::{Control, Keyword, Operator, Token}, 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> = pub type ParserInput<'src> =
SpannedInput<Token<'src>, SimpleSpan, &'src [(Token<'src>, SimpleSpan)]>; SpannedInput<Token<'src>, SimpleSpan, &'src [(Token<'src>, SimpleSpan)]>;
@ -76,15 +79,18 @@ pub fn parser<'src>(
let type_constructor = recursive(|type_constructor| { let type_constructor = recursive(|type_constructor| {
let primitive_type = choice(( let primitive_type = choice((
just(Token::Keyword(Keyword::Any)).to(Type::Any), just(Token::Keyword(Keyword::Any)).to(RawTypeConstructor::Any),
just(Token::Keyword(Keyword::Bool)).to(Type::Boolean), just(Token::Keyword(Keyword::Bool)).to(RawTypeConstructor::Boolean),
just(Token::Keyword(Keyword::Float)).to(Type::Float), just(Token::Keyword(Keyword::Float)).to(RawTypeConstructor::Float),
just(Token::Keyword(Keyword::Int)).to(Type::Integer), just(Token::Keyword(Keyword::Int)).to(RawTypeConstructor::Integer),
just(Token::Keyword(Keyword::None)).to(Type::None), just(Token::Keyword(Keyword::Map)).to(RawTypeConstructor::Map),
just(Token::Keyword(Keyword::Range)).to(Type::Range), just(Token::Keyword(Keyword::None)).to(RawTypeConstructor::None),
just(Token::Keyword(Keyword::Str)).to(Type::String), 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)) let function_type = just(Token::Keyword(Keyword::Fn))
.ignore_then( .ignore_then(
@ -700,6 +706,7 @@ pub fn parser<'src>(
positioned_identifier positioned_identifier
.clone() .clone()
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
.allow_trailing()
.collect() .collect()
.delimited_by( .delimited_by(
just(Token::Operator(Operator::Less)), just(Token::Operator(Operator::Less)),
@ -710,6 +717,8 @@ pub fn parser<'src>(
.then( .then(
enum_variant enum_variant
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
.allow_trailing()
.at_least(1)
.collect() .collect()
.delimited_by( .delimited_by(
just(Token::Control(Control::CurlyOpen)), just(Token::Control(Control::CurlyOpen)),

View File

@ -12,7 +12,7 @@ fn type_invokation() {
Some(TypeConstructor::Invokation(TypeInvokationConstructor { Some(TypeConstructor::Invokation(TypeInvokationConstructor {
identifier: Identifier::new("Foo").with_position((3, 6)), identifier: Identifier::new("Foo").with_position((3, 6)),
type_arguments: Some(vec![TypeConstructor::Raw( type_arguments: Some(vec![TypeConstructor::Raw(
Type::Integer.with_position((7, 10)) RawTypeConstructor::Integer.with_position((7, 10))
)]), )]),
})), })),
AssignmentOperator::Assign, AssignmentOperator::Assign,
@ -55,20 +55,20 @@ fn enum_declaration() {
parse(&lex("enum MyEnum { X, Y }").unwrap()).unwrap()[0], parse(&lex("enum MyEnum { X, Y }").unwrap()).unwrap()[0],
Statement::EnumDeclaration( Statement::EnumDeclaration(
EnumDeclaration { EnumDeclaration {
name: Identifier::new("MyEnum").with_position((0, 0)), name: Identifier::new("MyEnum").with_position((5, 11)),
type_parameters: None, type_parameters: None,
variants: vec![ variants: vec![
EnumVariant { EnumVariant {
name: Identifier::new("X").with_position((0, 0)), name: Identifier::new("X").with_position((14, 15)),
content: None content: None
}, },
EnumVariant { EnumVariant {
name: Identifier::new("Y").with_position((0, 0)), name: Identifier::new("Y").with_position((17, 18)),
content: None 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], parse(&lex("enum MyEnum { X(str, int), Y(int) }").unwrap()).unwrap()[0],
Statement::EnumDeclaration( Statement::EnumDeclaration(
EnumDeclaration { EnumDeclaration {
name: Identifier::new("MyEnum").with_position((0, 0)), name: Identifier::new("MyEnum").with_position((5, 11)),
type_parameters: None, type_parameters: None,
variants: vec![ variants: vec![
EnumVariant { EnumVariant {
name: Identifier::new("X").with_position((0, 0)), name: Identifier::new("X").with_position((14, 15)),
content: Some(vec![ content: Some(vec![
TypeConstructor::Raw(Type::String.with_position((0, 0))), TypeConstructor::Raw(
TypeConstructor::Raw(Type::Integer.with_position((0, 0))), RawTypeConstructor::String.with_position((16, 19))
),
TypeConstructor::Raw(
RawTypeConstructor::Integer.with_position((21, 24))
),
]) ])
}, },
EnumVariant { EnumVariant {
name: Identifier::new("Y").with_position((0, 0)), name: Identifier::new("Y").with_position((27, 28)),
content: Some(vec![TypeConstructor::Raw( 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], parse(&lex("enum MyEnum <T, U> { X(T), Y(U) }").unwrap()).unwrap()[0],
Statement::EnumDeclaration( Statement::EnumDeclaration(
EnumDeclaration { EnumDeclaration {
name: Identifier::new("MyEnum").with_position((0, 0)), name: Identifier::new("MyEnum").with_position((5, 11)),
type_parameters: Some(vec![ type_parameters: Some(vec![
Identifier::new("T").with_position((0, 0)), Identifier::new("T").with_position((13, 14)),
Identifier::new("U").with_position((0, 0)) Identifier::new("U").with_position((16, 17))
]), ]),
variants: vec![ variants: vec![
EnumVariant { EnumVariant {
name: Identifier::new("X").with_position((0, 0)), name: Identifier::new("X").with_position((21, 22)),
content: Some(vec![TypeConstructor::Raw( content: Some(vec![TypeConstructor::Invokation(
Type::Generic { TypeInvokationConstructor {
identifier: Identifier::new("T"), identifier: Identifier::new("T").with_position((23, 24)),
concrete_type: None type_arguments: None
} }
.with_position((0, 0))
)]) )])
}, },
EnumVariant { EnumVariant {
name: todo!(), name: Identifier::new("Y").with_position((27, 28)),
content: todo!() 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( Statement::Expression(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::Raw(Type::String.with_position((5, 8))) TypeConstructor::Raw(RawTypeConstructor::String.with_position((5, 8)))
)) ))
.with_position((0, 8)) .with_position((0, 8))
)) ))
@ -352,7 +360,9 @@ fn boolean_type() {
Statement::Assignment( Statement::Assignment(
Assignment::new( Assignment::new(
Identifier::new("foobar").with_position((0, 6)), 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, AssignmentOperator::Assign,
Statement::Expression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Boolean(true).with_position((16, 20)) ValueNode::Boolean(true).with_position((16, 20))
@ -374,7 +384,7 @@ fn list_type() {
ListTypeConstructor { ListTypeConstructor {
length: 2, length: 2,
item_type: Box::new(TypeConstructor::Raw( item_type: Box::new(TypeConstructor::Raw(
Type::Integer.with_position((9, 12)) RawTypeConstructor::Integer.with_position((9, 12))
)) ))
} }
.with_position((8, 16)) .with_position((8, 16))
@ -397,8 +407,10 @@ fn list_of_type() {
Assignment::new( Assignment::new(
Identifier::new("foobar").with_position((0, 6)), Identifier::new("foobar").with_position((0, 6)),
Some(TypeConstructor::ListOf( Some(TypeConstructor::ListOf(
Box::new(TypeConstructor::Raw(Type::Boolean.with_position((10, 14)))) Box::new(TypeConstructor::Raw(
.with_position((9, 15)) RawTypeConstructor::Boolean.with_position((10, 14))
))
.with_position((9, 15))
)), )),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::Expression(Expression::Value( Statement::Expression(Expression::Value(
@ -419,24 +431,24 @@ fn function_type() {
parse(&lex("type Foo = fn |T| (int) -> T").unwrap()).unwrap()[0], parse(&lex("type Foo = fn |T| (int) -> T").unwrap()).unwrap()[0],
Statement::TypeAlias( Statement::TypeAlias(
TypeAlias::new( TypeAlias::new(
Identifier::new("Foo").with_position((0, 0)), Identifier::new("Foo").with_position((5, 8)),
TypeConstructor::Function( TypeConstructor::Function(
FunctionTypeConstructor { 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( value_parameters: vec![TypeConstructor::Raw(
Type::Integer.with_position((0, 0)) RawTypeConstructor::Integer.with_position((19, 22))
)], )],
return_type: Box::new(TypeConstructor::Invokation( return_type: Box::new(TypeConstructor::Invokation(
TypeInvokationConstructor { TypeInvokationConstructor {
identifier: Identifier::new("T").with_position((0, 0)), identifier: Identifier::new("T").with_position((27, 28)),
type_arguments: None 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( FunctionCall::new(
Expression::Identifier(Identifier::new("foobar").with_position((0, 6))), Expression::Identifier(Identifier::new("foobar").with_position((0, 6))),
Some(vec![TypeConstructor::Raw( Some(vec![TypeConstructor::Raw(
Type::String.with_position((9, 12)) RawTypeConstructor::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))
@ -493,7 +505,9 @@ fn function() {
ValueNode::Function { ValueNode::Function {
type_parameters: None, type_parameters: None,
value_parameters: vec![], 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( body: Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::Integer(0).with_position((15, 16)) ValueNode::Integer(0).with_position((15, 16))
))]) ))])
@ -510,9 +524,11 @@ fn function() {
type_parameters: None, type_parameters: None,
value_parameters: vec![( value_parameters: vec![(
Identifier::new("x"), 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( body: Block::new(vec![Statement::Expression(Expression::Identifier(
Identifier::new("x").with_position((21, 22)) Identifier::new("x").with_position((21, 22))
))]) ))])
@ -832,7 +848,9 @@ fn assignment_with_type() {
Statement::Assignment( Statement::Assignment(
Assignment::new( Assignment::new(
Identifier::new("foobar").with_position((0, 6)), 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, AssignmentOperator::Assign,
Statement::Expression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(1).with_position((14, 15)) ValueNode::Integer(1).with_position((14, 15))

View File

@ -6,7 +6,7 @@ fn simple_enum() {
interpret( interpret(
"test", "test",
" "
type FooBar = enum { enum FooBar {
Foo, Foo,
Bar, Bar,
} }
@ -28,7 +28,7 @@ fn big_enum() {
interpret( interpret(
"test", "test",
" "
type FooBarBaz = enum |T, U, V| { enum FooBarBaz <T, U, V> {
Foo(T), Foo(T),
Bar(U), Bar(U),
Baz(V), Baz(V),