use chumsky::prelude::*;
mod bytearray;
mod constructor;
mod discard;
mod int;
mod list;
mod pair;
mod string;
mod tuple;
mod var;
use crate::{
ast::UntypedPattern,
parser::{error::ParseError, token::Token},
};
pub use bytearray::parser as bytearray;
pub use constructor::parser as constructor;
pub use discard::parser as discard;
pub use int::parser as int;
pub use list::parser as list;
pub use pair::parser as pair;
pub use string::parser as string;
pub use tuple::parser as tuple;
pub use var::parser as var;
pub fn parser() -> impl Parser<Token, UntypedPattern, Error = ParseError> {
recursive(|pattern| {
choice((
pair(pattern.clone()),
constructor(pattern.clone()),
var(pattern.clone()),
discard(),
int(),
bytearray(),
tuple(pattern.clone()),
list(pattern),
string(),
))
.then(
just(Token::As)
.ignore_then(select! { Token::Name {name} => name})
.or_not(),
)
.map_with_span(|(pattern, opt_as), span| {
if let Some(name) = opt_as {
UntypedPattern::Assign {
name,
location: span,
pattern: Box::new(pattern),
}
} else {
pattern
}
})
})
}
#[cfg(test)]
mod tests {
use crate::{assert_expr, assert_pattern};
#[test]
fn pattern_var() {
assert_pattern!("foo");
}
#[test]
fn pattern_discard_unnamed() {
assert_pattern!("_");
}
#[test]
fn pattern_discard_named() {
assert_pattern!("_foo");
}
#[test]
fn pattern_pair_discards() {
assert_pattern!("Pair(_, _)");
}
#[test]
fn pattern_pair_explicit_depth_1() {
assert_pattern!("Pair(14, True)");
}
#[test]
fn pattern_pair_explicit_depth_2() {
assert_pattern!("Pair([1,2,3], Pair((14, 42), _))");
}
#[test]
fn pattern_constructor_no_labels() {
assert_pattern!("Foo(a, b)");
}
#[test]
fn pattern_constructor_labels() {
assert_pattern!("Foo { a, b }");
}
#[test]
fn pattern_constructor_spread() {
assert_pattern!("Foo { a, .. }");
}
#[test]
fn pattern_constructor_pair_interleaved() {
assert_pattern!("Foo(a, Pair(1, 2))");
}
#[test]
fn pattern_list_spread() {
assert_pattern!("[head, ..]");
}
#[test]
fn pattern_list_spread_without_head_is_rejected() {
assert_expr!(
r#"
when foo is {
[, ..] -> Void
}
"#
);
}
}