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 pos token.Position
} }
/*
// `or { ... }` // `or { ... }`
pub struct OrExpr2 { pub struct OrExpr2 {
pub: pub:
@ -858,7 +859,7 @@ pub:
kind OrKind kind OrKind
pos token.Position pos token.Position
} }
*/
pub struct Assoc { pub struct Assoc {
pub: pub:
var_name string 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; // int pos = *(int*)_t190.data;
mut gen_or := false mut gen_or := false
mut tmp_opt := ''
if g.pref.autofree && assign_stmt.op == .decl_assign && assign_stmt.left_types.len == 1 && if g.pref.autofree && assign_stmt.op == .decl_assign && assign_stmt.left_types.len == 1 &&
assign_stmt.right[0] is ast.CallExpr { assign_stmt.right[0] is ast.CallExpr {
call_expr := assign_stmt.right[0] as ast.CallExpr call_expr := assign_stmt.right[0] as ast.CallExpr
if call_expr.or_block.kind != .absent { if call_expr.or_block.kind != .absent {
styp := g.typ(call_expr.return_type.set_flag(.optional)) 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.write('/*AF opt*/$styp $tmp_opt = ')
g.expr(assign_stmt.right[0]) g.expr(assign_stmt.right[0])
gen_or = true 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) unwrap_optional := !var_type.has_flag(.optional) && val_type.has_flag(.optional)
if unwrap_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*)') 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) g.is_shared = var_type.has_flag(.shared_f)
if !cloned { if !cloned {
@ -1663,8 +1676,12 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
} }
} }
if unwrap_optional { if unwrap_optional {
if g.pref.autofree {
// g.write(tmp_opt + '/*FF*/')
} else {
g.write('.data') g.write('.data')
} }
}
if str_add { if str_add {
g.write(')') 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 ') // g.insert_before_stmt('string $t = $str_expr; // new3. to free $i ')
cur_line = g.go_before_stmt(0) cur_line = g.go_before_stmt(0)
// println('cur line ="$cur_line"') // 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 // Now free the tmp arg vars right after the function call
g.strs_to_free << 'string_free(&$t);' g.strs_to_free << 'string_free(&$t);'
} }