mirror of
https://github.com/nushell/nushell
synced 2024-12-27 05:23:11 +00:00
More forgiving def parse
This commit is contained in:
parent
0a48bc973d
commit
84d0e0a059
1 changed files with 87 additions and 51 deletions
|
@ -47,71 +47,107 @@ pub fn parse_def(
|
|||
let mut error = None;
|
||||
let name = working_set.get_span_contents(spans[0]);
|
||||
|
||||
if name == b"def" && spans.len() >= 4 {
|
||||
//FIXME: don't use expect here
|
||||
let (name_expr, err) = parse_string(working_set, spans[1]);
|
||||
error = error.or(err);
|
||||
if name == b"def" {
|
||||
let def_decl_id = working_set
|
||||
.find_decl(b"def")
|
||||
.expect("internal error: missing def command");
|
||||
|
||||
working_set.enter_scope();
|
||||
let (sig, err) = parse_signature(working_set, spans[2]);
|
||||
error = error.or(err);
|
||||
let mut call = Box::new(Call {
|
||||
head: spans[0],
|
||||
decl_id: def_decl_id,
|
||||
positional: vec![],
|
||||
named: vec![],
|
||||
});
|
||||
|
||||
let (block, err) =
|
||||
parse_block_expression(working_set, &SyntaxShape::Block(Some(vec![])), spans[3]);
|
||||
error = error.or(err);
|
||||
working_set.exit_scope();
|
||||
let call = if let Some(name_span) = spans.get(1) {
|
||||
let (name_expr, err) = parse_string(working_set, *name_span);
|
||||
error = error.or(err);
|
||||
|
||||
if error.is_some() {
|
||||
return (
|
||||
Statement::Pipeline(Pipeline::from_vec(vec![garbage(span(spans))])),
|
||||
error,
|
||||
);
|
||||
}
|
||||
let name = name_expr.as_string();
|
||||
call.positional.push(name_expr);
|
||||
|
||||
let name = name_expr.as_string();
|
||||
if let Some(sig_span) = spans.get(2) {
|
||||
working_set.enter_scope();
|
||||
let (sig, err) = parse_signature(working_set, *sig_span);
|
||||
error = error.or(err);
|
||||
|
||||
let signature = sig.as_signature();
|
||||
let signature = sig.as_signature();
|
||||
|
||||
let block_id = block.as_block();
|
||||
call.positional.push(sig);
|
||||
|
||||
match (name, signature, block_id) {
|
||||
(Some(name), Some(mut signature), Some(block_id)) => {
|
||||
let decl_id = working_set
|
||||
.find_decl(name.as_bytes())
|
||||
.expect("internal error: predeclaration failed to add definition");
|
||||
if let Some(block_span) = spans.get(3) {
|
||||
let (block, err) = parse_block_expression(
|
||||
working_set,
|
||||
&SyntaxShape::Block(Some(vec![])),
|
||||
*block_span,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
let declaration = working_set.get_decl_mut(decl_id);
|
||||
let block_id = block.as_block();
|
||||
|
||||
signature.name = name;
|
||||
call.positional.push(block);
|
||||
|
||||
*declaration = signature.into_block_command(block_id);
|
||||
if let (Some(name), Some(mut signature), Some(block_id)) =
|
||||
(name, signature, block_id)
|
||||
{
|
||||
let decl_id = working_set
|
||||
.find_decl(name.as_bytes())
|
||||
.expect("internal error: predeclaration failed to add definition");
|
||||
|
||||
let def_decl_id = working_set
|
||||
.find_decl(b"def")
|
||||
.expect("internal error: missing def command");
|
||||
let declaration = working_set.get_decl_mut(decl_id);
|
||||
|
||||
let call = Box::new(Call {
|
||||
head: spans[0],
|
||||
decl_id: def_decl_id,
|
||||
positional: vec![name_expr, sig, block],
|
||||
named: vec![],
|
||||
});
|
||||
signature.name = name;
|
||||
|
||||
(
|
||||
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||
expr: Expr::Call(call),
|
||||
span: span(spans),
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
}])),
|
||||
error,
|
||||
)
|
||||
*declaration = signature.into_block_command(block_id);
|
||||
}
|
||||
} else {
|
||||
let err_span = Span {
|
||||
start: sig_span.end,
|
||||
end: sig_span.end,
|
||||
};
|
||||
|
||||
error = error
|
||||
.or_else(|| Some(ParseError::MissingPositional("block".into(), err_span)));
|
||||
}
|
||||
working_set.exit_scope();
|
||||
|
||||
call
|
||||
} else {
|
||||
let err_span = Span {
|
||||
start: name_span.end,
|
||||
end: name_span.end,
|
||||
};
|
||||
|
||||
error = error
|
||||
.or_else(|| Some(ParseError::MissingPositional("parameters".into(), err_span)));
|
||||
|
||||
call
|
||||
}
|
||||
_ => (
|
||||
Statement::Pipeline(Pipeline::from_vec(vec![garbage(span(spans))])),
|
||||
error,
|
||||
),
|
||||
}
|
||||
} else {
|
||||
let err_span = Span {
|
||||
start: spans[0].end,
|
||||
end: spans[0].end,
|
||||
};
|
||||
|
||||
error = error.or_else(|| {
|
||||
Some(ParseError::MissingPositional(
|
||||
"definition name".into(),
|
||||
err_span,
|
||||
))
|
||||
});
|
||||
|
||||
call
|
||||
};
|
||||
|
||||
(
|
||||
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||
expr: Expr::Call(call),
|
||||
span: span(spans),
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
}])),
|
||||
error,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
garbage_statement(spans),
|
||||
|
|
Loading…
Reference in a new issue