diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 7f3916b228..a1bb8a6553 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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) diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 9969caeb86..75938068c8 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -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 @@ -1019,7 +1019,7 @@ pub fn (s &Scanner) error(msg string) { pos := token.Position{ line_nr: s.line_nr pos: s.pos - } + } eprintln(util.formated_error('error', msg, s.file_path, pos)) exit(1) }