parser: add support for mutable if guards (#13132)
parent
ecc7accc8e
commit
10efe47f03
|
@ -1418,6 +1418,7 @@ pub mut:
|
|||
pub struct IfGuardExpr {
|
||||
pub:
|
||||
var_name string
|
||||
is_mut bool
|
||||
pos token.Position
|
||||
pub mut:
|
||||
expr Expr
|
||||
|
|
|
@ -1893,6 +1893,9 @@ fn branch_is_single_line(b ast.IfBranch) bool {
|
|||
}
|
||||
|
||||
pub fn (mut f Fmt) if_guard_expr(node ast.IfGuardExpr) {
|
||||
if node.is_mut {
|
||||
f.write('mut ')
|
||||
}
|
||||
f.write(node.var_name + ' := ')
|
||||
f.expr(node.expr)
|
||||
}
|
||||
|
|
|
@ -81,10 +81,17 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
|
|||
comments << p.eat_comments()
|
||||
mut cond := ast.empty_expr()
|
||||
mut is_guard := false
|
||||
|
||||
// `if x := opt() {`
|
||||
if !is_comptime && p.peek_tok.kind == .decl_assign {
|
||||
if !is_comptime && (p.peek_tok.kind == .decl_assign
|
||||
|| (p.tok.kind == .key_mut && p.peek_token(2).kind == .decl_assign)) {
|
||||
p.open_scope()
|
||||
is_guard = true
|
||||
mut is_mut := false
|
||||
if p.tok.kind == .key_mut {
|
||||
is_mut = true
|
||||
p.check(.key_mut)
|
||||
}
|
||||
var_pos := p.tok.position()
|
||||
var_name := p.check_name()
|
||||
if p.scope.known_var(var_name) {
|
||||
|
@ -96,10 +103,12 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
|
|||
expr := p.expr(0)
|
||||
cond = ast.IfGuardExpr{
|
||||
var_name: var_name
|
||||
is_mut: is_mut
|
||||
expr: expr
|
||||
}
|
||||
p.scope.register(ast.Var{
|
||||
name: var_name
|
||||
is_mut: is_mut
|
||||
expr: cond
|
||||
pos: var_pos
|
||||
})
|
||||
|
|
|
@ -106,21 +106,28 @@ fn test_chan_pop_empty() {
|
|||
}
|
||||
|
||||
struct Thing {
|
||||
name string
|
||||
mut:
|
||||
value int
|
||||
}
|
||||
|
||||
fn test_return_if_guard() {
|
||||
ret := option_check('zoo')
|
||||
println(ret)
|
||||
assert ret == 'zs'
|
||||
}
|
||||
|
||||
fn option_check(name string) string {
|
||||
return if thing := find_thing_by_name(name) { thing.name } else { 'safename' }
|
||||
}
|
||||
|
||||
fn find_thing_by_name(name string) ?&Thing {
|
||||
return &Thing{
|
||||
name: 'zs'
|
||||
fn maybe_a_thing() ?Thing {
|
||||
return Thing{
|
||||
value: 1
|
||||
}
|
||||
}
|
||||
|
||||
fn test_if_guard() {
|
||||
if val := maybe_a_thing() {
|
||||
assert val.value == 1
|
||||
} else {
|
||||
assert false
|
||||
}
|
||||
|
||||
if mut val := maybe_a_thing() {
|
||||
assert val.value == 1
|
||||
val.value = 2
|
||||
assert val.value == 2
|
||||
} else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue