checker: check if BranchStmt is in a loop

pull/4282/head
Daniel Däschle 2020-04-07 12:29:11 +02:00 committed by GitHub
parent fd75cce0f3
commit fe0942043c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 3 deletions

View File

@ -31,6 +31,7 @@ mut:
//assigned_var_name string
// fn_decl ast.FnDecl
pref &pref.Preferences // Preferences shared from V struct
in_for_count int // if checker is currently in an for loop
}
pub fn new_checker(table &table.Table, pref &pref.Preferences) Checker {
@ -597,6 +598,11 @@ fn (c mut Checker) stmt(node ast.Stmt) {
ast.Block {
c.stmts(it.stmts)
}
ast.BranchStmt {
if c.in_for_count == 0 {
c.error('$it.tok.lit statement not within a loop', it.tok.position())
}
}
// ast.Attr {}
ast.CompIf {
// c.expr(it.cond)
@ -660,6 +666,7 @@ fn (c mut Checker) stmt(node ast.Stmt) {
c.stmts(it.stmts)
}
ast.ForStmt {
c.in_for_count++
typ := c.expr(it.cond)
if !it.is_inf && table.type_idx(typ) != table.bool_type_idx {
c.error('non-bool used as for condition', it.pos)
@ -667,15 +674,19 @@ fn (c mut Checker) stmt(node ast.Stmt) {
// TODO: update loop var type
// how does this work currenly?
c.stmts(it.stmts)
c.in_for_count--
}
ast.ForCStmt {
c.in_for_count++
c.stmt(it.init)
c.expr(it.cond)
// c.stmt(it.inc)
c.expr(it.inc)
c.stmts(it.stmts)
c.in_for_count--
}
ast.ForInStmt {
c.in_for_count++
typ := c.expr(it.cond)
if it.is_range {
c.expr(it.high)
@ -690,7 +701,7 @@ fn (c mut Checker) stmt(node ast.Stmt) {
}
else {
table.int_type}
}
}
it.key_type = key_type
scope.update_var_type(it.key_var, key_type)
}
@ -705,6 +716,7 @@ fn (c mut Checker) stmt(node ast.Stmt) {
scope.update_var_type(it.val_var, value_type)
}
c.stmts(it.stmts)
c.in_for_count--
}
ast.GoStmt{
c.expr(it.call_expr)

View File

@ -379,7 +379,7 @@ pub fn (s mut Scanner) scan() token.Token {
// Check if not .eof to prevent panic
next_char := if s.pos + 1 < s.text.len { s.text[s.pos + 1] } else { `\0` }
if token.is_key(name) {
return s.new_token(token.key_to_token(name), '')
return s.new_token(token.key_to_token(name), name)
}
// 'asdf $b' => "b" is the last name in the string, dont start parsing string
// at the next ', skip it