mirror of
https://github.com/nushell/nushell.git
synced 2025-02-05 21:21:10 +01:00
blocks
This commit is contained in:
parent
fb42c94b79
commit
a91efc3cbd
@ -5,6 +5,7 @@ pub enum ParseError {
|
|||||||
ExtraTokens(Span),
|
ExtraTokens(Span),
|
||||||
ExtraPositional(Span),
|
ExtraPositional(Span),
|
||||||
UnexpectedEof(String, Span),
|
UnexpectedEof(String, Span),
|
||||||
|
Unclosed(String, Span),
|
||||||
UnknownStatement(Span),
|
UnknownStatement(Span),
|
||||||
Mismatch(String, Span),
|
Mismatch(String, Span),
|
||||||
VariableNotFound(Span),
|
VariableNotFound(Span),
|
||||||
|
@ -102,6 +102,7 @@ pub enum Expr {
|
|||||||
Operator(Operator),
|
Operator(Operator),
|
||||||
BinaryOp(Box<Expression>, Box<Expression>, Box<Expression>), //lhs, op, rhs
|
BinaryOp(Box<Expression>, Box<Expression>, Box<Expression>), //lhs, op, rhs
|
||||||
Subexpression(Box<Block>),
|
Subexpression(Box<Block>),
|
||||||
|
Block(Box<Block>),
|
||||||
Garbage,
|
Garbage,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,6 +540,17 @@ impl ParserWorkingSet {
|
|||||||
}
|
}
|
||||||
if bytes.ends_with(b")") {
|
if bytes.ends_with(b")") {
|
||||||
end -= 1;
|
end -= 1;
|
||||||
|
} else {
|
||||||
|
error = error.or_else(|| {
|
||||||
|
Some(ParseError::Unclosed(
|
||||||
|
")".into(),
|
||||||
|
Span {
|
||||||
|
start: end,
|
||||||
|
end: end + 1,
|
||||||
|
file_id: span.file_id,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = Span {
|
let span = Span {
|
||||||
@ -552,8 +564,6 @@ impl ParserWorkingSet {
|
|||||||
let (output, err) = lex(&source[..end], span.file_id, start, crate::LexMode::Normal);
|
let (output, err) = lex(&source[..end], span.file_id, start, crate::LexMode::Normal);
|
||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
|
|
||||||
println!("parsing subexpression: {:?} {:?}", output, error);
|
|
||||||
|
|
||||||
let (output, err) = lite_parse(&output);
|
let (output, err) = lite_parse(&output);
|
||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
|
|
||||||
@ -570,6 +580,60 @@ impl ParserWorkingSet {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_block_expression(&mut self, span: Span) -> (Expression, Option<ParseError>) {
|
||||||
|
let bytes = self.get_span_contents(span);
|
||||||
|
let mut error = None;
|
||||||
|
|
||||||
|
let mut start = span.start;
|
||||||
|
let mut end = span.end;
|
||||||
|
|
||||||
|
if bytes.starts_with(b"{") {
|
||||||
|
start += 1;
|
||||||
|
}
|
||||||
|
if bytes.ends_with(b"}") {
|
||||||
|
end -= 1;
|
||||||
|
} else {
|
||||||
|
error = error.or_else(|| {
|
||||||
|
Some(ParseError::Unclosed(
|
||||||
|
"}".into(),
|
||||||
|
Span {
|
||||||
|
start: end,
|
||||||
|
end: end + 1,
|
||||||
|
file_id: span.file_id,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let span = Span {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
file_id: span.file_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let source = self.get_file_contents(span.file_id);
|
||||||
|
|
||||||
|
let (output, err) = lex(&source[..end], span.file_id, start, crate::LexMode::Normal);
|
||||||
|
error = error.or(err);
|
||||||
|
|
||||||
|
let (output, err) = lite_parse(&output);
|
||||||
|
error = error.or(err);
|
||||||
|
|
||||||
|
let (output, err) = self.parse_block(&output);
|
||||||
|
error = error.or(err);
|
||||||
|
|
||||||
|
println!("{:?} {:?}", output, error);
|
||||||
|
|
||||||
|
(
|
||||||
|
Expression {
|
||||||
|
expr: Expr::Block(Box::new(output)),
|
||||||
|
ty: Type::Unknown,
|
||||||
|
span,
|
||||||
|
},
|
||||||
|
error,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_arg(
|
pub fn parse_arg(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -580,6 +644,15 @@ impl ParserWorkingSet {
|
|||||||
return self.parse_dollar_expr(span);
|
return self.parse_dollar_expr(span);
|
||||||
} else if bytes.starts_with(b"(") {
|
} else if bytes.starts_with(b"(") {
|
||||||
return self.parse_full_column_path(span);
|
return self.parse_full_column_path(span);
|
||||||
|
} else if bytes.starts_with(b"{") {
|
||||||
|
if shape != SyntaxShape::Block && shape != SyntaxShape::Any {
|
||||||
|
// FIXME: need better errors
|
||||||
|
return (
|
||||||
|
garbage(span),
|
||||||
|
Some(ParseError::Mismatch("not a block".into(), span)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return self.parse_block_expression(span);
|
||||||
}
|
}
|
||||||
|
|
||||||
match shape {
|
match shape {
|
||||||
@ -603,6 +676,7 @@ impl ParserWorkingSet {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SyntaxShape::Block => self.parse_block_expression(span),
|
||||||
SyntaxShape::Any => {
|
SyntaxShape::Any => {
|
||||||
let shapes = vec![
|
let shapes = vec![
|
||||||
SyntaxShape::Int,
|
SyntaxShape::Int,
|
||||||
|
Loading…
Reference in New Issue
Block a user