This commit is contained in:
JT 2021-07-02 19:32:30 +12:00
parent fb42c94b79
commit a91efc3cbd
2 changed files with 77 additions and 2 deletions

View File

@ -5,6 +5,7 @@ pub enum ParseError {
ExtraTokens(Span),
ExtraPositional(Span),
UnexpectedEof(String, Span),
Unclosed(String, Span),
UnknownStatement(Span),
Mismatch(String, Span),
VariableNotFound(Span),

View File

@ -102,6 +102,7 @@ pub enum Expr {
Operator(Operator),
BinaryOp(Box<Expression>, Box<Expression>, Box<Expression>), //lhs, op, rhs
Subexpression(Box<Block>),
Block(Box<Block>),
Garbage,
}
@ -539,6 +540,17 @@ impl ParserWorkingSet {
}
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 {
@ -552,8 +564,6 @@ impl ParserWorkingSet {
let (output, err) = lex(&source[..end], span.file_id, start, crate::LexMode::Normal);
error = error.or(err);
println!("parsing subexpression: {:?} {:?}", output, error);
let (output, err) = lite_parse(&output);
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(
&mut self,
span: Span,
@ -580,6 +644,15 @@ impl ParserWorkingSet {
return self.parse_dollar_expr(span);
} else if bytes.starts_with(b"(") {
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 {
@ -603,6 +676,7 @@ impl ParserWorkingSet {
)
}
}
SyntaxShape::Block => self.parse_block_expression(span),
SyntaxShape::Any => {
let shapes = vec![
SyntaxShape::Int,