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