parser: add support for mutable if guards (#13132)

pull/13136/head
Tim Basel 2022-01-11 14:32:58 +01:00 committed by GitHub
parent ecc7accc8e
commit 10efe47f03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 15 deletions

View File

@ -1418,6 +1418,7 @@ pub mut:
pub struct IfGuardExpr {
pub:
var_name string
is_mut bool
pos token.Position
pub mut:
expr Expr

View File

@ -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)
}

View File

@ -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
})

View File

@ -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
}
}