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