Skip to content

Commit 770ec1c

Browse files
committed
fix(parser): external argument with subexpressions
1 parent d528bb7 commit 770ec1c

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

crates/nu-parser/src/parser.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,10 @@ fn parse_external_string(working_set: &mut StateWorkingSet, span: Span) -> Expre
264264
quote_char: u8,
265265
escaped: bool,
266266
},
267+
Parenthesized {
268+
from: usize,
269+
depth: usize,
270+
},
267271
}
268272
// Find the spans of parts of the string that can be parsed as their own strings for
269273
// concatenation.
@@ -315,6 +319,15 @@ fn parse_external_string(working_set: &mut StateWorkingSet, span: Span) -> Expre
315319
}
316320
state = State::BackTickQuote { from: index }
317321
}
322+
b'(' => {
323+
if index != *from {
324+
spans.push(make_span(*from, index))
325+
}
326+
state = State::Parenthesized {
327+
from: index,
328+
depth: 1,
329+
}
330+
}
318331
// Continue to consume
319332
_ => (),
320333
},
@@ -343,6 +356,18 @@ fn parse_external_string(working_set: &mut StateWorkingSet, span: Span) -> Expre
343356
state = State::Bare { from: index + 1 };
344357
}
345358
}
359+
State::Parenthesized { from, depth } => {
360+
if ch == b')' {
361+
if *depth == 1 {
362+
spans.push(make_span(*from, index + 1));
363+
state = State::Bare { from: index + 1 };
364+
} else {
365+
*depth -= 1;
366+
}
367+
} else if ch == b'(' {
368+
*depth += 1;
369+
}
370+
}
346371
}
347372
index += 1;
348373
}
@@ -351,6 +376,7 @@ fn parse_external_string(working_set: &mut StateWorkingSet, span: Span) -> Expre
351376
match state {
352377
State::Bare { from }
353378
| State::Quote { from, .. }
379+
| State::Parenthesized { from, .. }
354380
| State::BackTickQuote { from, .. } => {
355381
if from < contents.len() {
356382
spans.push(make_span(from, contents.len()));

tests/repl/test_parser.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,3 +1027,9 @@ fn not_panic_with_recursive_call() {
10271027
);
10281028
assert!(result.status.success());
10291029
}
1030+
1031+
// https://github.com/nushell/nushell/issues/16040
1032+
#[test]
1033+
fn external_argument_with_subexpressions() -> TestResult {
1034+
run_test(r#"^echo foo( ('bar') | $in ++ 'baz' )"#, "foobarbaz")
1035+
}

0 commit comments

Comments
 (0)