parser: add support for mutable if guards (#13132)
parent
ecc7accc8e
commit
10efe47f03
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue