Actually just three programming languages in a trenchcoat
at string-repr-callable 67 lines 2.1 kB view raw
1use super::*; 2use crate::{Parser, Spanned}; 3use source_span::Span; 4use trilogy_scanner::{Token, TokenType}; 5 6/// The optional message portion of an assert statement. 7/// 8/// ```trilogy 9/// #- assert -# "msg" as #- expression -# 10/// ``` 11#[derive(Clone, Debug, PrettyPrintSExpr)] 12pub struct AssertMessage { 13 pub message: Expression, 14 pub r#as: Token, 15} 16 17/// An assert statement. 18/// 19/// ```trilogy 20/// assert "msg" as expression 21/// ``` 22#[derive(Clone, Debug, PrettyPrintSExpr)] 23pub struct AssertStatement { 24 pub assert: Token, 25 pub message: Option<AssertMessage>, 26 pub assertion: Expression, 27} 28 29impl AssertStatement { 30 pub(crate) fn parse(parser: &mut Parser) -> SyntaxResult<Self> { 31 let assert = parser.expect(TokenType::KwAssert).unwrap(); 32 let message_or_assertion = Expression::parse(parser)?; 33 if let Ok(r#as) = parser.expect(TokenType::KwAs) { 34 let assertion = Expression::parse(parser)?; 35 return Ok(Self { 36 assert, 37 message: Some(AssertMessage { 38 message: message_or_assertion, 39 r#as, 40 }), 41 assertion, 42 }); 43 } 44 Ok(Self { 45 assert, 46 message: None, 47 assertion: message_or_assertion, 48 }) 49 } 50} 51 52impl Spanned for AssertStatement { 53 fn span(&self) -> Span { 54 self.assert.span.union(self.assertion.span()) 55 } 56} 57 58#[cfg(test)] 59mod test { 60 use super::*; 61 62 test_parse!(assert_true: "assert true" => AssertStatement::parse => "(AssertStatement _ () (Expression::Boolean _))"); 63 test_parse!(assert_expression: "assert if x then false else true" => AssertStatement::parse => "(AssertStatement _ () (Expression::IfElse _))"); 64 test_parse!(assert_with_message: "assert \"message\" as true" => AssertStatement::parse => "(AssertStatement _ (AssertMessage _ _) (Expression::Boolean _))"); 65 test_parse_error!(assert_without_expr: "assert" => AssertStatement::parse); 66 test_parse_error!(assert_invalid_expr: "assert + 5" => AssertStatement::parse); 67}