[fine] Don't panic on this parse error
This commit is contained in:
parent
607847abc3
commit
f634e4da18
2 changed files with 19 additions and 4 deletions
|
|
@ -430,7 +430,7 @@ impl<'a> CParser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expect_start(&mut self, kind: TokenKind) {
|
fn expect_start(&mut self, kind: TokenKind) {
|
||||||
assert!(self.eat(kind));
|
assert!(self.eat(kind), "should have started with {kind:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn advance_with_error<T>(&mut self, error: T) -> MarkClosed
|
fn advance_with_error<T>(&mut self, error: T) -> MarkClosed
|
||||||
|
|
@ -708,7 +708,7 @@ fn block(p: &mut CParser) {
|
||||||
while !p.at(TokenKind::RightBrace) && !p.eof() {
|
while !p.at(TokenKind::RightBrace) && !p.eof() {
|
||||||
statement(p);
|
statement(p);
|
||||||
}
|
}
|
||||||
p.expect(TokenKind::RightBrace, "expect '}' to start a block");
|
p.expect(TokenKind::RightBrace, "expect '}' to end a block");
|
||||||
|
|
||||||
p.end(m, TreeKind::Block);
|
p.end(m, TreeKind::Block);
|
||||||
}
|
}
|
||||||
|
|
@ -756,6 +756,7 @@ fn statement_return(p: &mut CParser) {
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
|
|
||||||
p.expect_start(TokenKind::Return);
|
p.expect_start(TokenKind::Return);
|
||||||
|
// TODO: Make expression optional if we're returning ()
|
||||||
expression(p);
|
expression(p);
|
||||||
if !p.at(TokenKind::RightBrace) {
|
if !p.at(TokenKind::RightBrace) {
|
||||||
p.expect(TokenKind::Semicolon, "expect ';' to end a return statement");
|
p.expect(TokenKind::Semicolon, "expect ';' to end a return statement");
|
||||||
|
|
@ -938,13 +939,19 @@ fn conditional(p: &mut CParser) -> MarkClosed {
|
||||||
|
|
||||||
p.expect_start(TokenKind::If);
|
p.expect_start(TokenKind::If);
|
||||||
expression(p);
|
expression(p);
|
||||||
block(p);
|
if p.at(TokenKind::LeftBrace) {
|
||||||
|
block(p)
|
||||||
|
} else {
|
||||||
|
p.error("expected a block after `if`")
|
||||||
|
}
|
||||||
if p.eat(TokenKind::Else) {
|
if p.eat(TokenKind::Else) {
|
||||||
if p.at(TokenKind::If) {
|
if p.at(TokenKind::If) {
|
||||||
// Don't require another block, just jump right into the conditional.
|
// Don't require another block, just jump right into the conditional.
|
||||||
conditional(p);
|
conditional(p);
|
||||||
} else {
|
} else if p.at(TokenKind::LeftBrace) {
|
||||||
block(p);
|
block(p);
|
||||||
|
} else {
|
||||||
|
p.error("expected a block after `else`")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
8
fine/tests/expression/errors/broken_conditional.fine
Normal file
8
fine/tests/expression/errors/broken_conditional.fine
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fun test() {
|
||||||
|
if true true { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: These errors should be better
|
||||||
|
// @expect-errors:
|
||||||
|
// | 2:10: Error at 'true': expected a block after `if`
|
||||||
|
// | 2:15: Error at '{': expect ';' to end an expression statement
|
||||||
Loading…
Add table
Add a link
Reference in a new issue