cgen: write defer statements at the end of the function

pull/4131/head
Alexander Medvednikov 2020-03-27 11:21:00 +01:00
parent fd8bb2c95c
commit 7fdce50718
3 changed files with 41 additions and 22 deletions

View File

@ -5,8 +5,12 @@ fn foo() string {
fn foo2() string { fn foo2() string {
println('start') println('start')
defer { println('defer') } defer {
defer { println('defer2') } println('defer')
}
defer {
println('defer2')
}
println('end') println('end')
return foo() return foo()
} }
@ -16,17 +20,23 @@ fn test_defer() {
} }
fn set_num(i int, n mut Num) { fn set_num(i int, n mut Num) {
defer { n.val++ } defer {
println("Hi") println('exiting')
n.val++
}
println('Hi')
if i < 5 { if i < 5 {
return return
} else { }
else {
n.val++ n.val++
} }
} }
fn set_num_opt(n mut Num) ?int { fn set_num_opt(n mut Num) ?int {
defer { n.val = 1 } defer {
n.val = 1
}
return 99 return 99
} }
@ -36,16 +46,18 @@ mut:
} }
fn test_defer_early_exit() { fn test_defer_early_exit() {
mut sum := Num{0} mut sum := Num{
0}
for i in 0 .. 10 { for i in 0 .. 10 {
set_num(i, mut sum) set_num(i, mut sum)
} }
println("sum: $sum.val") println('sum: $sum.val')
assert sum.val == 15 assert sum.val == 15
} }
fn test_defer_option() { fn test_defer_option() {
mut ok := Num{0} mut ok := Num{
0}
set_num_opt(mut ok) or { set_num_opt(mut ok) or {
assert false assert false
} }

View File

@ -404,17 +404,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
ast.Import {} ast.Import {}
ast.Return { ast.Return {
if g.defer_stmts.len > 0 { if g.defer_stmts.len > 0 {
for defer_stmt in g.defer_stmts { g.write_defer_stmts()
g.writeln('// defer')
if defer_stmt.ifdef.len > 0 {
g.writeln(defer_stmt.ifdef)
g.stmts(defer_stmt.stmts)
g.writeln('#endif')
}
else {
g.stmts(defer_stmt.stmts)
}
}
} }
g.return_statement(it) g.return_statement(it)
} }
@ -442,6 +432,20 @@ fn (g mut Gen) stmt(node ast.Stmt) {
} }
} }
fn (g mut Gen) write_defer_stmts() {
for defer_stmt in g.defer_stmts {
g.writeln('// defer')
if defer_stmt.ifdef.len > 0 {
g.writeln(defer_stmt.ifdef)
g.stmts(defer_stmt.stmts)
g.writeln('#endif')
}
else {
g.stmts(defer_stmt.stmts)
}
}
}
fn (g mut Gen) for_in(it ast.ForInStmt) { fn (g mut Gen) for_in(it ast.ForInStmt) {
if it.is_range { if it.is_range {
// `for x in 1..10 {` // `for x in 1..10 {`
@ -755,6 +759,9 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
} }
g.writeln('return 0;') g.writeln('return 0;')
} }
if g.defer_stmts.len > 0 {
g.write_defer_stmts()
}
g.writeln('}') g.writeln('}')
g.defer_stmts = [] g.defer_stmts = []
g.fn_decl = 0 g.fn_decl = 0