Actually just three programming languages in a trenchcoat
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}