diff --git a/crates/aiken-lang/src/parser/expr/fail_todo.rs b/crates/aiken-lang/src/parser/expr/fail_todo.rs index 5db5dd9d..f7e15251 100644 --- a/crates/aiken-lang/src/parser/expr/fail_todo.rs +++ b/crates/aiken-lang/src/parser/expr/fail_todo.rs @@ -1,25 +1,48 @@ use chumsky::prelude::*; use crate::{ + ast::TraceKind, expr::UntypedExpr, parser::{ error::ParseError, - expr::{block::parser as block, string}, + expr::{string, when::clause}, token::Token, }, }; -pub fn parser( - sequence: Recursive<'_, Token, UntypedExpr, ParseError>, -) -> impl Parser + '_ { - let message = || choice((string::hybrid(), block(sequence.clone()))); +pub fn parser<'a>( + expression: Recursive<'a, Token, UntypedExpr, ParseError>, + sequence: Recursive<'a, Token, UntypedExpr, ParseError>, +) -> impl Parser + 'a { choice(( - just(Token::Todo) - .ignore_then(message().or_not()) - .map_with_span(UntypedExpr::todo), - just(Token::Fail) - .ignore_then(message().or_not()) - .map_with_span(UntypedExpr::fail), + just(Token::Todo).ignore_then(choice(( + clause(expression.clone()) + .ignored() + .rewind() + .map_with_span(|_, span| UntypedExpr::todo(None, span)), + choice((string::hybrid(), expression.clone())) + .or_not() + .map_with_span(UntypedExpr::todo), + ))), + just(Token::Fail).ignore_then(choice(( + clause(expression.clone()) + .ignored() + .rewind() + .map_with_span(|_, span| UntypedExpr::fail(None, span)), + choice((string::hybrid(), expression.clone())) + .or_not() + .map_with_span(UntypedExpr::fail), + ))), + just(Token::Trace) + .ignore_then(clause(expression.clone()).or_not().ignored().rewind()) + .ignore_then(choice((string::hybrid(), expression.clone()))) + .then(sequence.clone()) + .map_with_span(|(text, then_), span| UntypedExpr::Trace { + kind: TraceKind::Trace, + location: span, + then: Box::new(then_), + text: Box::new(text), + }), )) } @@ -71,4 +94,22 @@ mod tests { "# ); } + + #[test] + fn fail_empty() { + assert_expr!( + r#" + fail + "# + ); + } + + #[test] + fn trace_expr() { + assert_expr!( + r#" + trace some_var + "# + ); + } } diff --git a/crates/aiken-lang/src/parser/expr/mod.rs b/crates/aiken-lang/src/parser/expr/mod.rs index 94ad489c..dd291ec4 100644 --- a/crates/aiken-lang/src/parser/expr/mod.rs +++ b/crates/aiken-lang/src/parser/expr/mod.rs @@ -43,7 +43,7 @@ pub fn parser( ) -> impl Parser + '_ { recursive(|expression| { choice(( - fail_todo(sequence.clone()), + fail_todo(expression.clone(), sequence.clone()), pure_expression(sequence, expression), )) }) diff --git a/crates/aiken-lang/src/parser/expr/sequence.rs b/crates/aiken-lang/src/parser/expr/sequence.rs index 199d9902..7ad30044 100644 --- a/crates/aiken-lang/src/parser/expr/sequence.rs +++ b/crates/aiken-lang/src/parser/expr/sequence.rs @@ -13,15 +13,19 @@ use crate::{ pub fn parser() -> impl Parser { recursive(|sequence| { choice(( - just(Token::Trace) - .ignore_then(choice((string::hybrid(), block(sequence.clone())))) - .then(sequence.clone()) - .map_with_span(|(text, then_), span| UntypedExpr::Trace { - kind: TraceKind::Trace, - location: span, - then: Box::new(then_), - text: Box::new(text), - }), + // just(Token::Trace) + // .ignore_then(choice(( + // string::hybrid(), + // block(sequence.clone()), + // sequence.clone(), + // ))) + // .then(sequence.clone()) + // .map_with_span(|(text, then_), span| UntypedExpr::Trace { + // kind: TraceKind::Trace, + // location: span, + // then: Box::new(then_), + // text: Box::new(text), + // }), super::parser(sequence.clone()) .then(sequence.repeated()) .foldl(|current, next| current.append_in_sequence(next)), diff --git a/crates/aiken-lang/src/tests/format.rs b/crates/aiken-lang/src/tests/format.rs index 073deec0..92bf0d7a 100644 --- a/crates/aiken-lang/src/tests/format.rs +++ b/crates/aiken-lang/src/tests/format.rs @@ -581,3 +581,14 @@ fn format_int_uint() { "# ); } + +#[test] +fn fail_expr() { + assert_format!( + r#" + fn foo() { + fail some_var + } + "# + ); +}