autofree: more fixes in optionals

pull/6357/head
Alexander Medvednikov 2020-09-13 03:00:20 +02:00
parent e77c4c182d
commit db51ee08ea
3 changed files with 22 additions and 4 deletions

View File

@ -850,6 +850,7 @@ pub:
pos token.Position
}
/*
// `or { ... }`
pub struct OrExpr2 {
pub:
@ -858,7 +859,7 @@ pub:
kind OrKind
pos token.Position
}
*/
pub struct Assoc {
pub:
var_name string

View File

@ -1347,12 +1347,13 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
// }
// int pos = *(int*)_t190.data;
mut gen_or := false
mut tmp_opt := ''
if g.pref.autofree && assign_stmt.op == .decl_assign && assign_stmt.left_types.len == 1 &&
assign_stmt.right[0] is ast.CallExpr {
call_expr := assign_stmt.right[0] as ast.CallExpr
if call_expr.or_block.kind != .absent {
styp := g.typ(call_expr.return_type.set_flag(.optional))
tmp_opt := g.new_tmp_var()
tmp_opt = g.new_tmp_var()
g.write('/*AF opt*/$styp $tmp_opt = ')
g.expr(assign_stmt.right[0])
gen_or = true
@ -1631,7 +1632,19 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
}
unwrap_optional := !var_type.has_flag(.optional) && val_type.has_flag(.optional)
if unwrap_optional {
// Unwrap the optional now that the testing code has been prepended.
// `pos := s.index(...
// `int pos = *(int)_t10.data;`
g.write('*($styp*)')
if g.pref.autofree {
g.write(tmp_opt + '.data/*FF*/')
g.right_is_opt = false
g.is_assign_rhs = false
if g.inside_ternary == 0 && !assign_stmt.is_simple {
g.writeln(';')
}
return
}
}
g.is_shared = var_type.has_flag(.shared_f)
if !cloned {
@ -1663,7 +1676,11 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
}
}
if unwrap_optional {
g.write('.data')
if g.pref.autofree {
// g.write(tmp_opt + '/*FF*/')
} else {
g.write('.data')
}
}
if str_add {
g.write(')')

View File

@ -554,7 +554,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
// g.insert_before_stmt('string $t = $str_expr; // new3. to free $i ')
cur_line = g.go_before_stmt(0)
// println('cur line ="$cur_line"')
g.writeln('string $t = $str_expr; // new3. to free $i ')
g.writeln('string $t = $str_expr; // new3. to free arg #$i name=$name')
// Now free the tmp arg vars right after the function call
g.strs_to_free << 'string_free(&$t);'
}