Actually just three programming languages in a trenchcoat
1use super::{Identifier, *};
2use crate::{Parser, Spanned};
3use source_span::Span;
4use trilogy_scanner::{
5 Token,
6 TokenType::{self, *},
7};
8
9/// A fallback `else` handler for a handled `when` statement or expression.
10#[derive(Clone, Debug, PrettyPrintSExpr)]
11pub struct ElseHandler {
12 pub r#else: Token,
13 pub identifier: Option<Identifier>,
14 pub strategy: HandlerStrategy,
15 span: Span,
16}
17
18impl ElseHandler {
19 pub(crate) fn parse(parser: &mut Parser) -> SyntaxResult<Self> {
20 let r#else = parser.expect(KwElse).unwrap();
21
22 let identifier = if parser.check(TokenType::Identifier).is_ok() {
23 Some(Identifier::parse(parser).unwrap())
24 } else {
25 None
26 };
27
28 let strategy = HandlerStrategy::parse(parser)?;
29
30 Ok(Self {
31 span: r#else.span.union(strategy.span()),
32 r#else,
33 identifier,
34 strategy,
35 })
36 }
37
38 pub fn else_token(&self) -> &Token {
39 &self.r#else
40 }
41}
42
43impl Spanned for ElseHandler {
44 fn span(&self) -> Span {
45 self.span
46 }
47}
48
49#[cfg(test)]
50mod test {
51 use super::*;
52
53 test_parse!(elsehandler_yield: "else yield" => ElseHandler::parse => "(ElseHandler _ () _)");
54 test_parse!(elsehandler_resume_without_id: "else resume 3" => ElseHandler::parse => "(ElseHandler _ () _)");
55 test_parse!(elsehandler_resume_with_id: "else x resume x" => ElseHandler::parse => "(ElseHandler _ (Identifier) _)");
56 test_parse!(elsehandler_cancel_without_id: "else cancel 3" => ElseHandler::parse => "(ElseHandler _ () _)");
57 test_parse!(elsehandler_cancel_with_id: "else x cancel x" => ElseHandler::parse => "(ElseHandler _ (Identifier) _)");
58}