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 struct IfGuardExpr {
pub: pub:
var_name string var_name string
is_mut bool
pos token.Position pos token.Position
pub mut: pub mut:
expr Expr 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) { pub fn (mut f Fmt) if_guard_expr(node ast.IfGuardExpr) {
if node.is_mut {
f.write('mut ')
}
f.write(node.var_name + ' := ') f.write(node.var_name + ' := ')
f.expr(node.expr) 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() comments << p.eat_comments()
mut cond := ast.empty_expr() mut cond := ast.empty_expr()
mut is_guard := false mut is_guard := false
// `if x := opt() {` // `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() p.open_scope()
is_guard = true 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_pos := p.tok.position()
var_name := p.check_name() var_name := p.check_name()
if p.scope.known_var(var_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) expr := p.expr(0)
cond = ast.IfGuardExpr{ cond = ast.IfGuardExpr{
var_name: var_name var_name: var_name
is_mut: is_mut
expr: expr expr: expr
} }
p.scope.register(ast.Var{ p.scope.register(ast.Var{
name: var_name name: var_name
is_mut: is_mut
expr: cond expr: cond
pos: var_pos pos: var_pos
}) })

View File

@ -106,21 +106,28 @@ fn test_chan_pop_empty() {
} }
struct Thing { struct Thing {
name string mut:
value int
} }
fn test_return_if_guard() { fn maybe_a_thing() ?Thing {
ret := option_check('zoo') return Thing{
println(ret) value: 1
assert ret == 'zs' }
} }
fn option_check(name string) string { fn test_if_guard() {
return if thing := find_thing_by_name(name) { thing.name } else { 'safename' } if val := maybe_a_thing() {
} assert val.value == 1
} else {
fn find_thing_by_name(name string) ?&Thing { assert false
return &Thing{ }
name: 'zs'
if mut val := maybe_a_thing() {
assert val.value == 1
val.value = 2
assert val.value == 2
} else {
assert false
} }
} }