Skip to content

Commit

Permalink
parser: avoid infinite loop when a block is not finished
Browse files Browse the repository at this point in the history
  • Loading branch information
StunxFS committed Dec 4, 2024
1 parent da6480d commit c37f7e6
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 4 deletions.
3 changes: 3 additions & 0 deletions compiler/parser/expr.v
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import compiler.ast
import compiler.context

fn (mut p Parser) parse_expr() ast.Expr {
if p.should_abort() {
return ast.empty_expr
}
match p.tok.kind {
.kw_if {}
.kw_match {}
Expand Down
1 change: 0 additions & 1 deletion compiler/parser/mod.v
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ fn (mut p Parser) parse_file(filename string, is_root bool) {
}

p.advance(2)

for {
p.file.stmts << p.parse_stmt()
if p.should_abort() {
Expand Down
18 changes: 16 additions & 2 deletions compiler/parser/stmt.v
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,32 @@ import compiler.ast
import compiler.context

fn (mut p Parser) parse_block() []ast.Stmt {
if p.tok.kind == .lbrace && p.next_tok.kind == .rbrace {
// empty block: `{}`
p.advance(2)
return []
}

old_inside_local_scope := p.inside_local_scope
defer { p.inside_local_scope = old_inside_local_scope }
p.inside_local_scope = true

mut is_finished := false
mut stmts := []ast.Stmt{}
lbrace_pos := p.tok.pos
p.expect(.lbrace)
for !p.accept(.rbrace) {
for {
stmts << p.parse_stmt()
if p.should_abort() {
is_finished = p.accept(.rbrace)
if is_finished || p.should_abort() {
break
}
}
if !is_finished && !p.abort {
// we give an error because the block has not been finished (`}` was not found),
// but it has not been aborted (due to poor formation of expressions or statements)
context.error('unfinished block, expected `}` and found ${p.tok}', lbrace_pos)
}
return stmts
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/tokenizer/token.v
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ fn build_keys() map[string]Kind {
fn build_token_str() []string {
mut s := []string{len: int(Kind._end_)}
s[Kind.unknown] = 'unknown'
s[Kind.eof] = 'eof'
s[Kind.eof] = 'end of file'
s[Kind.ident] = 'identifier'
s[Kind.number] = 'number'
s[Kind.string] = 'string'
Expand Down

0 comments on commit c37f7e6

Please sign in to comment.