feat: lists and flatten sequences
This commit is contained in:
parent
3208dab718
commit
43b147a9e0
|
@ -277,17 +277,42 @@ impl UntypedExpr {
|
||||||
..self.location()
|
..self.location()
|
||||||
};
|
};
|
||||||
|
|
||||||
match self {
|
match (self.clone(), next.clone()) {
|
||||||
|
(
|
||||||
Self::Sequence {
|
Self::Sequence {
|
||||||
mut expressions, ..
|
expressions: mut current_expressions,
|
||||||
} => {
|
..
|
||||||
expressions.push(next);
|
},
|
||||||
|
Self::Sequence {
|
||||||
|
expressions: mut next_expressions,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
current_expressions.append(&mut next_expressions);
|
||||||
|
|
||||||
Self::Sequence {
|
Self::Sequence {
|
||||||
location,
|
location,
|
||||||
expressions,
|
expressions: current_expressions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Self::Sequence {
|
(
|
||||||
|
_,
|
||||||
|
Self::Sequence {
|
||||||
|
expressions: mut next_expressions,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
let mut current_expressions = vec![self];
|
||||||
|
|
||||||
|
current_expressions.append(&mut next_expressions);
|
||||||
|
|
||||||
|
Self::Sequence {
|
||||||
|
location,
|
||||||
|
expressions: current_expressions,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(_, _) => Self::Sequence {
|
||||||
location,
|
location,
|
||||||
expressions: vec![self, next],
|
expressions: vec![self, next],
|
||||||
},
|
},
|
||||||
|
|
|
@ -249,18 +249,67 @@ pub fn expr_seq_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseE
|
||||||
}),
|
}),
|
||||||
expr_parser()
|
expr_parser()
|
||||||
.then(r.repeated())
|
.then(r.repeated())
|
||||||
.map_with_span(|(expr, exprs), _span| {
|
.foldl(|current, next| current.append_in_sequence(next)),
|
||||||
exprs
|
|
||||||
.into_iter()
|
|
||||||
.fold(expr, |acc, elem| acc.append_in_sequence(elem))
|
|
||||||
}),
|
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseError> {
|
pub fn expr_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseError> {
|
||||||
recursive(|r| {
|
recursive(|r| {
|
||||||
let assignment_parser = pattern_parser()
|
let string_parser =
|
||||||
|
select! {Token::String {value} => value}.map_with_span(|value, span| {
|
||||||
|
expr::UntypedExpr::String {
|
||||||
|
location: span,
|
||||||
|
value,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let int_parser = select! { Token::Int {value} => value}.map_with_span(|value, span| {
|
||||||
|
expr::UntypedExpr::Int {
|
||||||
|
location: span,
|
||||||
|
value,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let var_parser = select! {
|
||||||
|
Token::Name { name } => name,
|
||||||
|
Token::UpName { name } => name,
|
||||||
|
}
|
||||||
|
.map_with_span(|name, span| expr::UntypedExpr::Var {
|
||||||
|
location: span,
|
||||||
|
name,
|
||||||
|
});
|
||||||
|
|
||||||
|
let todo_parser = just(Token::Todo)
|
||||||
|
.ignore_then(
|
||||||
|
select! {Token::String {value} => value}
|
||||||
|
.delimited_by(just(Token::LeftParen), just(Token::RightParen))
|
||||||
|
.or_not(),
|
||||||
|
)
|
||||||
|
.map_with_span(|label, span| expr::UntypedExpr::Todo {
|
||||||
|
kind: TodoKind::Keyword,
|
||||||
|
location: span,
|
||||||
|
label,
|
||||||
|
});
|
||||||
|
|
||||||
|
let list_parser = just(Token::LeftSquare)
|
||||||
|
.ignore_then(r.clone().separated_by(just(Token::Comma)).allow_trailing())
|
||||||
|
.then(
|
||||||
|
just(Token::DotDot)
|
||||||
|
.ignore_then(r.clone())
|
||||||
|
.map(Box::new)
|
||||||
|
.or_not(),
|
||||||
|
)
|
||||||
|
.then_ignore(just(Token::RightSquare))
|
||||||
|
// TODO: check if tail.is_some and elements.is_empty then return ListSpreadWithoutElements error
|
||||||
|
.map_with_span(|(elements, tail), span| expr::UntypedExpr::List {
|
||||||
|
location: span,
|
||||||
|
elements,
|
||||||
|
tail,
|
||||||
|
});
|
||||||
|
|
||||||
|
let assignment_parser = just(Token::Let)
|
||||||
|
.ignore_then(pattern_parser())
|
||||||
.then(just(Token::Colon).ignore_then(type_parser()).or_not())
|
.then(just(Token::Colon).ignore_then(type_parser()).or_not())
|
||||||
.then_ignore(just(Token::Equal))
|
.then_ignore(just(Token::Equal))
|
||||||
.then(r)
|
.then(r)
|
||||||
|
@ -275,40 +324,12 @@ pub fn expr_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseError
|
||||||
);
|
);
|
||||||
|
|
||||||
let expr_unit_parser = choice((
|
let expr_unit_parser = choice((
|
||||||
select! {Token::String {value} => value}.map_with_span(|value, span| {
|
string_parser,
|
||||||
expr::UntypedExpr::String {
|
int_parser,
|
||||||
location: span,
|
var_parser,
|
||||||
value,
|
todo_parser,
|
||||||
}
|
list_parser,
|
||||||
}),
|
assignment_parser,
|
||||||
select! { Token::Int {value} => value}.map_with_span(|value, span| {
|
|
||||||
expr::UntypedExpr::Int {
|
|
||||||
location: span,
|
|
||||||
value,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
select! {
|
|
||||||
Token::Name { name } => name,
|
|
||||||
Token::UpName { name } => name,
|
|
||||||
}
|
|
||||||
.map_with_span(|name, span| expr::UntypedExpr::Var {
|
|
||||||
location: span,
|
|
||||||
name,
|
|
||||||
}),
|
|
||||||
just(Token::Todo)
|
|
||||||
.ignore_then(
|
|
||||||
select! {Token::String {value} => value}
|
|
||||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen))
|
|
||||||
.or_not(),
|
|
||||||
)
|
|
||||||
.map_with_span(|label, span| expr::UntypedExpr::Todo {
|
|
||||||
kind: TodoKind::Keyword,
|
|
||||||
location: span,
|
|
||||||
label,
|
|
||||||
}),
|
|
||||||
just(Token::Let)
|
|
||||||
.then(assignment_parser)
|
|
||||||
.map(|(_, assign)| assign),
|
|
||||||
))
|
))
|
||||||
.boxed();
|
.boxed();
|
||||||
|
|
||||||
|
@ -659,6 +680,10 @@ mod tests {
|
||||||
|> add_one
|
|> add_one
|
||||||
|> add_one
|
|> add_one
|
||||||
|
|
||||||
|
let thing = [ 1, 2, a ]
|
||||||
|
|
||||||
|
let idk = thing
|
||||||
|
|
||||||
y
|
y
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
@ -954,10 +979,10 @@ mod tests {
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},],
|
},],
|
||||||
body: expr::UntypedExpr::Sequence {
|
body: expr::UntypedExpr::Sequence {
|
||||||
location: Span::new(SrcId::empty(), 645..741),
|
location: Span::new(SrcId::empty(), 641..819),
|
||||||
expressions: vec![
|
expressions: vec![
|
||||||
expr::UntypedExpr::Assignment {
|
expr::UntypedExpr::Assignment {
|
||||||
location: Span::new(SrcId::empty(), 645..724),
|
location: Span::new(SrcId::empty(), 641..724),
|
||||||
value: Box::new(expr::UntypedExpr::PipeLine {
|
value: Box::new(expr::UntypedExpr::PipeLine {
|
||||||
expressions: vec1::vec1![
|
expressions: vec1::vec1![
|
||||||
expr::UntypedExpr::BinOp {
|
expr::UntypedExpr::BinOp {
|
||||||
|
@ -989,14 +1014,54 @@ mod tests {
|
||||||
kind: ast::AssignmentKind::Let,
|
kind: ast::AssignmentKind::Let,
|
||||||
annotation: None,
|
annotation: None,
|
||||||
},
|
},
|
||||||
|
expr::UntypedExpr::Assignment {
|
||||||
|
location: Span::new(SrcId::empty(), 748..771),
|
||||||
|
value: Box::new(expr::UntypedExpr::List {
|
||||||
|
location: Span::new(SrcId::empty(), 760..771),
|
||||||
|
elements: vec![
|
||||||
|
expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 762..763),
|
||||||
|
value: "1".to_string(),
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 765..766),
|
||||||
|
value: "2".to_string(),
|
||||||
|
},
|
||||||
expr::UntypedExpr::Var {
|
expr::UntypedExpr::Var {
|
||||||
location: Span::new(SrcId::empty(), 740..741),
|
location: Span::new(SrcId::empty(), 768..769),
|
||||||
|
name: "a".to_string(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
tail: None,
|
||||||
|
}),
|
||||||
|
pattern: ast::Pattern::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 752..757),
|
||||||
|
name: "thing".to_string(),
|
||||||
|
},
|
||||||
|
kind: ast::AssignmentKind::Let,
|
||||||
|
annotation: None,
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::Assignment {
|
||||||
|
location: Span::new(SrcId::empty(), 787..802),
|
||||||
|
value: Box::new(expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 797..802),
|
||||||
|
name: "thing".to_string(),
|
||||||
|
}),
|
||||||
|
pattern: ast::Pattern::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 791..794),
|
||||||
|
name: "idk".to_string(),
|
||||||
|
},
|
||||||
|
kind: ast::AssignmentKind::Let,
|
||||||
|
annotation: None,
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 818..819),
|
||||||
name: "y".to_string(),
|
name: "y".to_string(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
doc: None,
|
doc: None,
|
||||||
location: Span::new(SrcId::empty(), 606..755),
|
location: Span::new(SrcId::empty(), 606..833),
|
||||||
name: "wow".to_string(),
|
name: "wow".to_string(),
|
||||||
public: true,
|
public: true,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
|
|
Loading…
Reference in New Issue