Actually just three programming languages in a trenchcoat
at main 75 lines 2.3 kB view raw
1use super::{pattern::Precedence, *}; 2use crate::{Parser, Spanned}; 3use source_span::Span; 4use trilogy_scanner::{Token, TokenType::*}; 5 6#[derive(Clone, Debug)] 7pub struct GluePattern { 8 pub lhs: Pattern, 9 pub glue: Token, 10 pub rhs: Pattern, 11 pub span: Span, 12} 13 14impl Spanned for GluePattern { 15 fn span(&self) -> Span { 16 self.span 17 } 18} 19 20impl GluePattern { 21 pub(crate) fn new(lhs: Pattern, glue: Token, rhs: Pattern) -> Self { 22 Self { 23 span: lhs.span().union(rhs.span()), 24 lhs, 25 glue, 26 rhs, 27 } 28 } 29 30 pub(crate) fn parse(parser: &mut Parser, lhs: Pattern) -> SyntaxResult<Self> { 31 let glue = parser 32 .expect(OpGlue) 33 .expect("Caller should have found this"); 34 let rhs = Pattern::parse_precedence(parser, Precedence::Glue)?; 35 Ok(Self { 36 span: lhs.span().union(rhs.span()), 37 lhs, 38 glue, 39 rhs, 40 }) 41 } 42} 43 44impl TryFrom<BinaryOperation> for GluePattern { 45 type Error = SyntaxError; 46 47 fn try_from(value: BinaryOperation) -> Result<Self, Self::Error> { 48 let span = value.span(); 49 match value.operator { 50 BinaryOperator::Glue(token) => Ok(Self { 51 span, 52 lhs: value.lhs.try_into()?, 53 glue: token, 54 rhs: value.rhs.try_into()?, 55 }), 56 _ => Err(SyntaxError::new( 57 value.span(), 58 "incorrect operator for glue pattern", 59 )), 60 } 61 } 62} 63 64#[cfg(test)] 65mod test { 66 use super::*; 67 68 test_parse!(glue_pattern_left_str: r#""hello" <> x"# => Pattern::parse => Pattern::Glue(GluePattern { .. })); 69 test_parse!(glue_pattern_right_str: r#"x <> "hello""# => Pattern::parse => Pattern::Glue(GluePattern { .. })); 70 test_parse!(glue_pattern_no_str: r#"x <> y"# => Pattern::parse => Pattern::Glue(GluePattern { .. })); 71 test_parse!(glue_pattern_both_str: r#""x" <> "y""# => Pattern::parse => Pattern::Glue(GluePattern { .. })); 72 test_parse!(glue_pattern_not_str: r#"1 <> x"# => Pattern::parse => Pattern::Glue(GluePattern { .. })); 73 test_parse_error!(glue_pattern_incomplete: r#"x <>"# => Pattern::parse); 74 test_parse_error!(glue_pattern_invalid_expr: r#"x <> {}"# => Pattern::parse); 75}