all: `for mut val in vals {` (part 1)

pull/6613/head
Alexander Medvednikov 2020-10-13 16:27:24 +02:00
parent d316f78f94
commit a07f31feae
4 changed files with 33 additions and 5 deletions

View File

@ -600,6 +600,8 @@ pub:
high Expr // `10` in `for i in 0..10 {`
stmts []Stmt
pos token.Position
val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array
// and the array cannot be indexed inside the loop
pub mut:
key_type table.Type
val_type table.Type

View File

@ -2357,17 +2357,24 @@ fn (mut c Checker) stmt(node ast.Stmt) {
node.key_type = key_type
scope.update_var_type(node.key_var, key_type)
}
value_type := c.table.value_type(typ)
mut value_type := c.table.value_type(typ)
if value_type == table.void_type || typ.has_flag(.optional) {
if typ != table.void_type {
c.error('for in: cannot index `${c.table.type_to_str(typ)}`',
node.cond.position())
}
}
// if node.val_is_mut {
// value_type = value_type.to_ptr()
// }
node.cond_type = typ
node.kind = sym.kind
node.val_type = value_type
scope.update_var_type(node.val_var, value_type)
if node.val_is_mut {
scope.update_var_type(node.val_var, value_type.to_ptr())
} else {
scope.update_var_type(node.val_var, value_type)
}
}
c.stmts(node.stmts)
c.in_for_count--

View File

@ -25,10 +25,11 @@ fn (mut p Parser) for_stmt() ast.Stmt {
pos: pos
is_inf: true
}
} else if p.tok.kind == .key_mut {
p.error('`mut` is not needed in for loops')
} else if p.peek_tok.kind in [.decl_assign, .assign, .semicolon] || p.tok.kind == .semicolon {
// `for i := 0; i < 10; i++ {`
if p.tok.kind == .key_mut {
p.error('`mut` is not needed in `for ;;` loops: use `for i := 0; i < n; i ++ {`')
}
mut init := ast.Stmt{}
mut cond := p.new_true_expr()
mut inc := ast.Stmt{}
@ -68,8 +69,13 @@ fn (mut p Parser) for_stmt() ast.Stmt {
inc: inc
pos: pos
}
} else if p.peek_tok.kind in [.key_in, .comma] {
} else if p.peek_tok.kind in [.key_in, .comma] ||
(p.tok.kind == .key_mut && p.peek_tok2.kind in [.key_in, .comma]) {
// `for i in vals`, `for i in start .. end`
val_is_mut := p.tok.kind == .key_mut
if val_is_mut {
p.next()
}
key_var_pos := p.tok.position()
mut val_var_pos := p.tok.position()
mut key_var_name := ''
@ -124,6 +130,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
p.scope.register(val_var_name, ast.Var{
name: val_var_name
pos: val_var_pos
is_mut: val_is_mut
})
}
p.inside_for = false
@ -138,6 +145,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
high: high_expr
is_range: is_range
pos: pos
val_is_mut: val_is_mut
}
}
// `for cond {`

View File

@ -54,3 +54,14 @@ fn test_for_char_in_map() {
}
assert acc == 'a: b, c: d, '
}
fn test_mut_for() {
/*
mut vals := [1,2,3]
for mut val in vals {
(*val)++
}
assert vals == [2,3,4]
println(vals)
*/
}