From f24bc43906b3d310e3d558a01b2d446fe977a4ba Mon Sep 17 00:00:00 2001 From: tslil Date: Sat, 18 Oct 2025 23:58:30 +0100 Subject: Parse & explain groups! --- rprt-engine/src/parser.rs | 162 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) (limited to 'rprt-engine/src/parser.rs') diff --git a/rprt-engine/src/parser.rs b/rprt-engine/src/parser.rs index c17913a..9536046 100644 --- a/rprt-engine/src/parser.rs +++ b/rprt-engine/src/parser.rs @@ -120,6 +120,7 @@ fn can_start_composition(context: &ParseContext, offset: usize) -> bool { | Some(Token::Complement) | Some(Token::Conditional) | Some(Token::LParen) + | Some(Token::LBrace) | Some(Token::Dot) | Some(Token::Change) | Some(Token::Insert) @@ -144,6 +145,21 @@ fn parse_base_function(context: &mut ParseContext) -> Result panic!(), } } + + #[test] + fn test_parse_group() { + let input = r#"{e, #5 -, "tr"}"#; + let tokens = tokenise(input).unwrap(); + let result = parse(tokens).unwrap(); + match result { + Composite::Group { operations } => { + assert_eq!(operations.len(), 3); + match &operations[0] { + Composite::SelectionFunction { + func: BuiltinSelectionFn::Empty, + search_mod: None, + result_transform: None, + } => {} + _ => panic!(), + } + match &operations[1] { + Composite::Train2 { f, g } => { + match &**f { + Composite::SelectionFunction { + func: BuiltinSelectionFn::CharOffset(5), + search_mod: None, + result_transform: None, + } => {} + _ => panic!(), + } + match &**g { + Composite::SelectionFunction { + func: BuiltinSelectionFn::Span, + search_mod: None, + result_transform: None, + } => {} + _ => panic!(), + } + } + _ => panic!(), + } + match &operations[2] { + Composite::TextFunction { + func: BuiltinTextFn::Literal(s), + swapped: false, + } => { + assert_eq!(s, "tr"); + } + _ => panic!(), + } + } + _ => panic!(), + } + } + + #[test] + fn test_parse_nested_groups_in_train() { + let input = r#"{e<#5, ;$ i} (~e { + match f.as_ref() { + Composite::Group { operations } => { + assert_eq!(operations.len(), 2); + match &operations[0] { + Composite::Hook { + kind: HookKind::After, + left, + right, + } => { + match left.as_ref() { + Composite::SelectionFunction { + func: BuiltinSelectionFn::Empty, + search_mod: None, + result_transform: None, + } => {} + _ => panic!(), + } + match right.as_ref() { + Composite::SelectionFunction { + func: BuiltinSelectionFn::CharOffset(5), + search_mod: None, + result_transform: None, + } => {} + _ => panic!(), + } + } + _ => panic!(), + } + match &operations[1] { + Composite::Train2 { f: f2, g: g2 } => { + match f2.as_ref() { + Composite::SelectionFunction { + func: BuiltinSelectionFn::EndOfBuffer, + search_mod: Some(SearchModifier::Sequential), + result_transform: None, + } => {} + _ => panic!(), + } + match g2.as_ref() { + Composite::TextFunction { + func: BuiltinTextFn::Insert, + swapped: false, + } => {} + _ => panic!(), + } + } + _ => panic!(), + } + } + _ => panic!(), + } + match g.as_ref() { + Composite::Hook { + kind: HookKind::After, + left, + right, + } => { + match left.as_ref() { + Composite::SelectionFunction { + func: BuiltinSelectionFn::Empty, + search_mod: None, + result_transform: Some(ResultTransform::Complement), + } => {} + _ => panic!(), + } + match right.as_ref() { + Composite::TextFunction { + func: BuiltinTextFn::Delete, + swapped: false, + } => {} + _ => panic!(), + } + } + _ => panic!(), + } + match h.as_ref() { + Composite::SelectionFunction { + func: BuiltinSelectionFn::EndOfBuffer, + search_mod: None, + result_transform: None, + } => {} + _ => panic!(), + } + } + _ => panic!(), + } + } } -- cgit v1.2.3