feat: handle expect in parser

* map both assert/expect to Token::Expect
* use the new token in the parser
* new unit test to expect
This commit is contained in:
rvcas 2023-02-09 00:43:29 -05:00
parent 5a4a8df727
commit dbd162e985
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
5 changed files with 78 additions and 5 deletions

View File

@ -1028,7 +1028,7 @@ pub fn expr_parser(
}, },
); );
let assert_parser = just(Token::Assert) let assert_parser = just(Token::Expect)
.ignore_then(pattern_parser()) .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))

View File

@ -87,7 +87,8 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
"trace" => Token::Trace, "trace" => Token::Trace,
"error" => Token::ErrorTerm, "error" => Token::ErrorTerm,
"as" => Token::As, "as" => Token::As,
"assert" => Token::Assert, "assert" => Token::Expect,
"expect" => Token::Expect,
"const" => Token::Const, "const" => Token::Const,
"fn" => Token::Fn, "fn" => Token::Fn,
"test" => Token::Test, "test" => Token::Test,

View File

@ -60,7 +60,6 @@ pub enum Token {
NewLine, NewLine,
// Keywords (alphabetically): // Keywords (alphabetically):
As, As,
Assert,
Const, Const,
Fn, Fn,
If, If,
@ -141,7 +140,6 @@ impl fmt::Display for Token {
Token::EmptyLine => "EMPTYLINE", Token::EmptyLine => "EMPTYLINE",
Token::NewLine => "NEWLINE", Token::NewLine => "NEWLINE",
Token::As => "as", Token::As => "as",
Token::Assert => "assert",
Token::Expect => "expect", Token::Expect => "expect",
Token::When => "when", Token::When => "when",
Token::Is => "is", Token::Is => "is",

View File

@ -324,6 +324,77 @@ fn empty_function() {
) )
} }
#[test]
fn expect() {
let code = indoc! {r#"
pub fn run() {
expect Some(x) = something.field
x.other_field
}
"#};
assert_definitions(
code,
vec![ast::UntypedDefinition::Fn(Function {
arguments: vec![],
body: expr::UntypedExpr::Sequence {
location: Span::new((), 19..69),
expressions: vec![
expr::UntypedExpr::Assignment {
location: Span::new((), 19..51),
value: expr::UntypedExpr::FieldAccess {
location: Span::new((), 36..51),
label: "field".to_string(),
container: expr::UntypedExpr::Var {
location: Span::new((), 36..45),
name: "something".to_string(),
}
.into(),
}
.into(),
pattern: ast::Pattern::Constructor {
is_record: false,
location: Span::new((), 26..33),
name: "Some".to_string(),
arguments: vec![ast::CallArg {
label: None,
location: Span::new((), 31..32),
value: ast::Pattern::Var {
location: Span::new((), 31..32),
name: "x".to_string(),
},
}],
module: None,
constructor: (),
with_spread: false,
tipo: (),
},
kind: ast::AssignmentKind::Assert,
annotation: None,
},
expr::UntypedExpr::FieldAccess {
location: Span::new((), 56..69),
label: "other_field".to_string(),
container: expr::UntypedExpr::Var {
location: Span::new((), 56..57),
name: "x".to_string(),
}
.into(),
},
],
},
doc: None,
location: Span::new((), 0..12),
name: "run".to_string(),
public: true,
return_annotation: None,
return_type: (),
end_position: 70,
})],
)
}
#[test] #[test]
fn plus_binop() { fn plus_binop() {
let code = indoc! {r#" let code = indoc! {r#"

View File

@ -511,8 +511,11 @@ fn validate_module_name(name: &str) -> Result<(), Error> {
fn str_to_keyword(word: &str) -> Option<Token> { fn str_to_keyword(word: &str) -> Option<Token> {
// Alphabetical keywords: // Alphabetical keywords:
match word { match word {
"assert" => Some(Token::Expect),
"expect" => Some(Token::Expect),
"else" => Some(Token::Else),
"is" => Some(Token::Is),
"as" => Some(Token::As), "as" => Some(Token::As),
"assert" => Some(Token::Assert),
"when" => Some(Token::When), "when" => Some(Token::When),
"const" => Some(Token::Const), "const" => Some(Token::Const),
"fn" => Some(Token::Fn), "fn" => Some(Token::Fn),