cgen: else if guard (#5822)

pull/5827/head
Enzo 2020-07-14 17:19:55 +02:00 committed by GitHub
parent d33fbe4547
commit 880c8e4dc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 12 deletions

View File

@ -2352,15 +2352,34 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
return
}
mut is_guard := false
mut guard_vars := []string{ len: node.branches.len }
for i, branch in node.branches {
if i == 0 {
match branch.cond {
if branch.cond is ast.IfGuardExpr as cond {
if !is_guard {
is_guard = true
g.writeln('{ /* if guard */ ')
}
var_name := g.new_tmp_var()
guard_vars[i] = var_name
g.writeln('${g.typ(cond.expr_type)} $var_name;')
}
}
for i, branch in node.branches {
if i > 0 {
g.write('} else ')
}
if i == node.branches.len - 1 && node.has_else {
g.writeln('{')
} else {
match branch.cond as cond {
ast.IfGuardExpr {
is_guard = true
g.write('{ /* if guard */ ${g.typ(it.expr_type)} $it.var_name = ')
var_name := guard_vars[i]
g.write('if ($var_name = ')
g.expr(it.expr)
g.writeln(';')
g.writeln('if (${it.var_name}.ok) {')
g.writeln(', ${var_name}.ok) {')
if cond.var_name != '_' {
g.writeln('\t${g.typ(cond.expr_type)} $cond.var_name = $var_name;')
}
}
else {
g.write('if (')
@ -2368,12 +2387,6 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
g.writeln(') {')
}
}
} else if i < node.branches.len - 1 || !node.has_else {
g.write('} else if (')
g.expr(branch.cond)
g.writeln(') {')
} else if i == node.branches.len - 1 && node.has_else {
g.writeln('} else {')
}
if branch.smartcast && branch.stmts.len > 0 {
infix := branch.cond as ast.InfixExpr

View File

@ -13,6 +13,28 @@ fn test_if_opt() {
assert true
}
fn test_simple_else_if_guard() {
if false {
assert false
} else if val := err_call(true) {
assert val == 42
} else {
assert false
}
}
fn test_multiple_else_if_guard() {
if _ := err_call(false) {
assert false
} else if val := err_call(false) {
assert val == 0 // assert false
} else if val := err_call(true) {
assert val == 42
} else {
assert false
}
}
fn test_opt_with_fall_through() {
mut x := 1
err_call(false) or {