Add rest param

This commit is contained in:
JT 2021-07-17 11:22:01 +12:00
parent d08f2e73d0
commit c03f700662
2 changed files with 21 additions and 7 deletions

View File

@ -8,6 +8,7 @@ pub enum ParseError {
Unclosed(String, Span), Unclosed(String, Span),
UnknownStatement(Span), UnknownStatement(Span),
Mismatch(String, Span), Mismatch(String, Span),
MultipleRestParams(Span),
VariableNotFound(Span), VariableNotFound(Span),
UnknownCommand(Span), UnknownCommand(Span),
NonUtf8(Span), NonUtf8(Span),

View File

@ -607,13 +607,16 @@ impl ParserWorkingSet {
// Parse a positional arg if there is one // Parse a positional arg if there is one
if let Some(positional) = decl.signature.get_positional(positional_idx) { if let Some(positional) = decl.signature.get_positional(positional_idx) {
//Make sure we leave enough spans for the remaining positionals //Make sure we leave enough spans for the remaining positionals
let remainder = decl.signature.num_positionals() - positional_idx;
let (arg, err) = self.parse_multispan_value( let end = if decl.signature.rest_positional.is_some() {
&spans[..(spans.len() - remainder + 1)], spans.len()
&mut spans_idx, } else {
positional.shape, let remainder = decl.signature.num_positionals() - positional_idx;
); spans.len() - remainder + 1
};
let (arg, err) =
self.parse_multispan_value(&spans[..end], &mut spans_idx, positional.shape);
error = error.or(err); error = error.or(err);
call.positional.push(arg); call.positional.push(arg);
positional_idx += 1; positional_idx += 1;
@ -1111,7 +1114,17 @@ impl ParserWorkingSet {
for arg in args { for arg in args {
match arg { match arg {
Arg::Positional(positional, required) => { Arg::Positional(positional, required) => {
if required { if positional.name == "...rest" {
if sig.rest_positional.is_none() {
sig.rest_positional = Some(PositionalArg {
name: "rest".into(),
..positional
})
} else {
// Too many rest params
error = error.or(Some(ParseError::MultipleRestParams(span)))
}
} else if required {
sig.required_positional.push(positional) sig.required_positional.push(positional)
} else { } else {
sig.optional_positional.push(positional) sig.optional_positional.push(positional)