90 lines
2.4 KiB
Rust
90 lines
2.4 KiB
Rust
use chumsky::prelude::*;
|
|
|
|
use crate::{
|
|
ast,
|
|
expr::UntypedExpr,
|
|
parser::{annotation, error::ParseError, pattern, token::Token},
|
|
};
|
|
|
|
pub fn let_(
|
|
r: Recursive<'_, Token, UntypedExpr, ParseError>,
|
|
) -> impl Parser<Token, UntypedExpr, Error = ParseError> + '_ {
|
|
just(Token::Let)
|
|
.ignore_then(pattern())
|
|
.then(just(Token::Colon).ignore_then(annotation()).or_not())
|
|
.then_ignore(just(Token::Equal))
|
|
.then(r.clone())
|
|
.map_with_span(
|
|
move |((pattern, annotation), value), span| UntypedExpr::Assignment {
|
|
location: span,
|
|
value: Box::new(value),
|
|
pattern,
|
|
kind: ast::AssignmentKind::Let,
|
|
annotation,
|
|
},
|
|
)
|
|
}
|
|
|
|
pub fn expect(
|
|
r: Recursive<'_, Token, UntypedExpr, ParseError>,
|
|
) -> impl Parser<Token, UntypedExpr, Error = ParseError> + '_ {
|
|
just(Token::Expect)
|
|
.ignore_then(
|
|
pattern()
|
|
.then(just(Token::Colon).ignore_then(annotation()).or_not())
|
|
.then_ignore(just(Token::Equal))
|
|
.or_not(),
|
|
)
|
|
.then(r.clone())
|
|
.map_with_span(move |(opt_pattern, value), span| {
|
|
let (pattern, annotation) = opt_pattern.unwrap_or_else(|| {
|
|
(
|
|
ast::UntypedPattern::Constructor {
|
|
is_record: false,
|
|
location: span,
|
|
name: "True".to_string(),
|
|
arguments: vec![],
|
|
module: None,
|
|
constructor: (),
|
|
with_spread: false,
|
|
tipo: (),
|
|
},
|
|
None,
|
|
)
|
|
});
|
|
|
|
UntypedExpr::Assignment {
|
|
location: span,
|
|
value: Box::new(value),
|
|
pattern,
|
|
kind: ast::AssignmentKind::Expect,
|
|
annotation,
|
|
}
|
|
})
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::assert_expr;
|
|
|
|
#[test]
|
|
fn let_bindings() {
|
|
assert_expr!("let thing = [ 1, 2, a ]");
|
|
}
|
|
|
|
#[test]
|
|
fn expect() {
|
|
assert_expr!("expect Some(x) = something.field");
|
|
}
|
|
|
|
#[test]
|
|
fn expect_bool_sugar() {
|
|
assert_expr!("expect something.field == wow");
|
|
}
|
|
|
|
#[test]
|
|
fn expect_trace_if_false() {
|
|
assert_expr!("expect foo?");
|
|
}
|
|
}
|