From 78054a53525901c2a36b1bb0f9ae4ba6716572bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20=C5=BD=C3=A1dn=C3=ADk?= Date: Sun, 12 Sep 2021 15:29:27 +0300 Subject: [PATCH] Allow parsing left-unbounded range (..10) It is implemented as a preliminary check when parsing a call and relies on a fact that a token that successfully parses as a range is unlikely to be a valid path or command name. --- crates/nu-parser/src/parser.rs | 9 ++++++++ crates/nu-parser/tests/test_parser.rs | 31 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 6199e87ee1..839f43db88 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -469,6 +469,15 @@ pub fn parse_call( spans: &[Span], expand_aliases: bool, ) -> (Expression, Option) { + // We might be parsing left-unbounded range ("..10") + let bytes = working_set.get_span_contents(spans[0]); + if let (Some(b'.'), Some(b'.')) = (bytes.get(0), bytes.get(1)) { + let (range_expr, range_err) = parse_range(working_set, spans[0]); + if range_err.is_none() { + return (range_expr, range_err); + } + } + // assume spans.len() > 0? let mut pos = 0; let mut shorthand = vec![]; diff --git a/crates/nu-parser/tests/test_parser.rs b/crates/nu-parser/tests/test_parser.rs index 2015f356c0..11c8189f78 100644 --- a/crates/nu-parser/tests/test_parser.rs +++ b/crates/nu-parser/tests/test_parser.rs @@ -371,6 +371,37 @@ mod range { } } + #[test] + fn parse_left_unbounded_range() { + let engine_state = EngineState::new(); + let mut working_set = StateWorkingSet::new(&engine_state); + + let (block, err) = parse(&mut working_set, None, b"..10", true); + + assert!(err.is_none()); + assert!(block.len() == 1); + match &block[0] { + Statement::Pipeline(Pipeline { expressions }) => { + assert!(expressions.len() == 1); + assert!(matches!( + expressions[0], + Expression { + expr: Expr::Range( + None, + Some(_), + RangeOperator { + inclusion: RangeInclusion::Inclusive, + .. + } + ), + .. + } + )) + } + _ => panic!("No match"), + } + } + #[test] fn parse_negative_range() { let engine_state = EngineState::new();