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::{
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
{

View File

@ -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)

View File

@ -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)),

View File

@ -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,8 +407,10 @@ 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))))
.with_position((9, 15))
Box::new(TypeConstructor::Raw(
RawTypeConstructor::Boolean.with_position((10, 14))
))
.with_position((9, 15))
)),
AssignmentOperator::Assign,
Statement::Expression(Expression::Value(
@ -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))

View File

@ -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),