Actually just three programming languages in a trenchcoat
at main 51 lines 2.0 kB view raw
1use super::*; 2use crate::Parser; 3use trilogy_scanner::{Token, TokenType::*}; 4 5#[derive(Clone, Debug, Spanned)] 6pub enum HandlerStrategy { 7 Cancel { cancel: Token, body: Expression }, 8 Resume { resume: Token, body: Expression }, 9 Yield(Token), 10 Bare(FollowingExpression), 11} 12 13impl HandlerStrategy { 14 pub(crate) fn parse(parser: &mut Parser) -> SyntaxResult<Self> { 15 let token = match parser.check([KwCancel, KwResume, KwThen, KwYield, OBrace]) { 16 Ok(token) => token, 17 Err(token) => { 18 let token = token.clone(); 19 return Err(parser.expected( 20 token, 21 "expected `cancel`, `resume`, `then`, `yield`, or a block in handler", 22 )); 23 } 24 }; 25 26 match token.token_type { 27 KwCancel => Ok(Self::Cancel { 28 cancel: parser.expect(KwCancel).unwrap(), 29 body: Expression::parse(parser)?, 30 }), 31 KwResume => Ok(Self::Resume { 32 resume: parser.expect(KwResume).unwrap(), 33 body: Expression::parse(parser)?, 34 }), 35 KwYield => Ok(Self::Yield(parser.expect(KwYield).unwrap())), 36 KwThen | OBrace => Ok(Self::Bare(FollowingExpression::parse(parser)?)), 37 _ => unreachable!(), 38 } 39 } 40} 41 42#[cfg(test)] 43mod test { 44 use super::*; 45 46 test_parse!(handler_strategy_yield: "yield" => HandlerStrategy::parse => HandlerStrategy::Yield(..)); 47 test_parse!(handler_strategy_cancel: "cancel 3" => HandlerStrategy::parse => HandlerStrategy::Cancel { .. }); 48 test_parse!(handler_strategy_then: "then cancel resume 5" => HandlerStrategy::parse => HandlerStrategy::Bare(..)); 49 test_parse!(handler_strategy_block: "{ cancel resume 5 }" => HandlerStrategy::parse => HandlerStrategy::Bare(..)); 50 test_parse!(handler_strategy_resume: "resume 4" => HandlerStrategy::parse => HandlerStrategy::Resume { .. }); 51}