cgen/autofree: fix and simplify optionals
parent
f162e61748
commit
b74c1805d7
|
@ -850,6 +850,15 @@ pub:
|
||||||
pos token.Position
|
pos token.Position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `or { ... }`
|
||||||
|
pub struct OrExpr2 {
|
||||||
|
pub:
|
||||||
|
call_expr CallExpr
|
||||||
|
stmts []Stmt // inside `or { }`
|
||||||
|
kind OrKind
|
||||||
|
pos token.Position
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Assoc {
|
pub struct Assoc {
|
||||||
pub:
|
pub:
|
||||||
var_name string
|
var_name string
|
||||||
|
|
|
@ -2629,6 +2629,9 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
||||||
// never happens
|
// never happens
|
||||||
return table.void_type
|
return table.void_type
|
||||||
}
|
}
|
||||||
|
// ast.OrExpr2 {
|
||||||
|
// return node.typ
|
||||||
|
// }
|
||||||
ast.ParExpr {
|
ast.ParExpr {
|
||||||
return c.expr(node.expr)
|
return c.expr(node.expr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1335,6 +1335,33 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||||
g.writeln('); // free str on re-assignment')
|
g.writeln('); // free str on re-assignment')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Handle optionals. We need to declare a temp variable for them, that's why they are handled
|
||||||
|
// here, not in call_expr().
|
||||||
|
// `pos := s.index('x') or { return }`
|
||||||
|
// ==========>
|
||||||
|
// Option_int _t190 = string_index(s, _STR("x"));
|
||||||
|
// if (!_t190.ok) {
|
||||||
|
// string err = _t190.v_error;
|
||||||
|
// int errcode = _t190.ecode;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// int pos = *(int*)_t190.data;
|
||||||
|
mut gen_or := false
|
||||||
|
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()
|
||||||
|
g.write('/*AF opt*/$styp $tmp_opt = ')
|
||||||
|
g.expr(assign_stmt.right[0])
|
||||||
|
gen_or = true
|
||||||
|
g.or_block(tmp_opt, call_expr.or_block, call_expr.return_type)
|
||||||
|
g.writeln('/*=============ret*/')
|
||||||
|
// return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
// json_test failed w/o this check
|
// json_test failed w/o this check
|
||||||
if return_type != table.void_type && return_type != 0 {
|
if return_type != table.void_type && return_type != 0 {
|
||||||
sym := g.table.get_type_symbol(return_type)
|
sym := g.table.get_type_symbol(return_type)
|
||||||
|
|
|
@ -280,9 +280,12 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
||||||
defer {
|
defer {
|
||||||
g.inside_call = false
|
g.inside_call = false
|
||||||
}
|
}
|
||||||
gen_or := node.or_block.kind != .absent
|
gen_or := node.or_block.kind != .absent && !g.pref.autofree
|
||||||
|
// if gen_or {
|
||||||
|
// g.writeln('/*start*/')
|
||||||
|
// }
|
||||||
is_gen_or_and_assign_rhs := gen_or && g.is_assign_rhs
|
is_gen_or_and_assign_rhs := gen_or && g.is_assign_rhs
|
||||||
cur_line := if is_gen_or_and_assign_rhs {
|
cur_line := if is_gen_or_and_assign_rhs && !g.pref.autofree {
|
||||||
line := g.go_before_stmt(0)
|
line := g.go_before_stmt(0)
|
||||||
g.out.write(tabs[g.indent])
|
g.out.write(tabs[g.indent])
|
||||||
line
|
line
|
||||||
|
@ -304,10 +307,13 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
||||||
} else {
|
} else {
|
||||||
g.fn_call(node)
|
g.fn_call(node)
|
||||||
}
|
}
|
||||||
if gen_or {
|
if gen_or { // && !g.pref.autofree {
|
||||||
|
if !g.pref.autofree {
|
||||||
g.or_block(tmp_opt, node.or_block, node.return_type)
|
g.or_block(tmp_opt, node.or_block, node.return_type)
|
||||||
|
}
|
||||||
if is_gen_or_and_assign_rhs {
|
if is_gen_or_and_assign_rhs {
|
||||||
g.write('\n$cur_line$tmp_opt')
|
g.write('\n $cur_line $tmp_opt')
|
||||||
|
// g.write('\n /*call_expr cur_line:*/ $cur_line /*C*/ $tmp_opt /*end*/')
|
||||||
// g.insert_before_stmt('\n /* VVV */ $tmp_opt')
|
// g.insert_before_stmt('\n /* VVV */ $tmp_opt')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -545,13 +551,14 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||||
t := '_tt${g.tmp_count2}_arg_expr_${fn_name}_$i'
|
t := '_tt${g.tmp_count2}_arg_expr_${fn_name}_$i'
|
||||||
g.called_fn_name = name
|
g.called_fn_name = name
|
||||||
str_expr := g.write_expr_to_string(arg.expr)
|
str_expr := g.write_expr_to_string(arg.expr)
|
||||||
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; // new. to free $i ')
|
g.writeln('string $t = $str_expr; // new3. to free $i ')
|
||||||
*/
|
// Now free the tmp arg vars right after the function call
|
||||||
|
g.strs_to_free << 'string_free(&$t);'
|
||||||
}
|
}
|
||||||
|
// g.strs_to_free << (';')
|
||||||
}
|
}
|
||||||
// Handle `print(x)`
|
// Handle `print(x)`
|
||||||
if is_print && node.args[0].typ != table.string_type { // && !free_tmp_arg_vars {
|
if is_print && node.args[0].typ != table.string_type { // && !free_tmp_arg_vars {
|
||||||
|
@ -617,7 +624,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||||
// Simple function call
|
// Simple function call
|
||||||
if free_tmp_arg_vars {
|
if free_tmp_arg_vars {
|
||||||
// g.writeln(';')
|
// g.writeln(';')
|
||||||
g.write(cur_line + ' /* cur line*/')
|
g.write(cur_line + ' /* <== af cur line*/')
|
||||||
}
|
}
|
||||||
g.write('${g.get_ternary_name(name)}(')
|
g.write('${g.get_ternary_name(name)}(')
|
||||||
if g.is_json_fn {
|
if g.is_json_fn {
|
||||||
|
@ -630,22 +637,6 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||||
}
|
}
|
||||||
g.is_c_call = false
|
g.is_c_call = false
|
||||||
g.is_json_fn = false
|
g.is_json_fn = false
|
||||||
if free_tmp_arg_vars { // && tmp_arg_vars_to_free.len > 0 {
|
|
||||||
// g.writeln(';')
|
|
||||||
// g.write(cur_line + ' /* cur line*/')
|
|
||||||
// g.write(tmp)
|
|
||||||
// Now free the tmp arg vars right after the function call
|
|
||||||
g.strs_to_free << (';')
|
|
||||||
for i, arg in node.args {
|
|
||||||
if arg.is_tmp_autofree {
|
|
||||||
fn_name := node.name.replace('.', '_')
|
|
||||||
tmp := '_tt${g.tmp_count2}_arg_expr_${fn_name}_$i'
|
|
||||||
g.strs_to_free << ('string_free(&$tmp);')
|
|
||||||
// g.writeln('string_free(&$tmp);')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// g.writeln('')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn (mut g Gen) call_args(args []ast.CallArg, expected_types []table.Type, tmp_arg_vars_to_free []string) {
|
// fn (mut g Gen) call_args(args []ast.CallArg, expected_types []table.Type, tmp_arg_vars_to_free []string) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import v.token
|
||||||
import v.util
|
import v.util
|
||||||
|
|
||||||
pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExpr {
|
pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExpr {
|
||||||
|
// pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.Expr {
|
||||||
first_pos := p.tok.position()
|
first_pos := p.tok.position()
|
||||||
mut fn_name := if language == .c {
|
mut fn_name := if language == .c {
|
||||||
'C.$p.check_name()'
|
'C.$p.check_name()'
|
||||||
|
@ -88,6 +89,25 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
|
||||||
fn_name = registered.name
|
fn_name = registered.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
call_expr := ast.CallExpr{
|
||||||
|
name: fn_name
|
||||||
|
args: args
|
||||||
|
mod: fn_mod
|
||||||
|
pos: pos
|
||||||
|
language: language
|
||||||
|
generic_type: generic_type
|
||||||
|
}
|
||||||
|
if or_kind != .absent {
|
||||||
|
return ast.OrExpr2{
|
||||||
|
call_expr: call_expr
|
||||||
|
stmts: or_stmts
|
||||||
|
kind: or_kind
|
||||||
|
pos: pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return call_expr
|
||||||
|
*/
|
||||||
return ast.CallExpr{
|
return ast.CallExpr{
|
||||||
name: fn_name
|
name: fn_name
|
||||||
args: args
|
args: args
|
||||||
|
|
|
@ -64,17 +64,21 @@ fn match_expr() string {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
fn opt(s string) ?int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
fn optional_str() {
|
fn optional_str() {
|
||||||
q := 'select'
|
q := 'select'
|
||||||
s := 'x'
|
s := 'x'
|
||||||
pos := s.index('query: $q') or {
|
pos2 := opt('query:$q') or {
|
||||||
|
// pos := s.index('query: $q') or {
|
||||||
println('exiting')
|
println('exiting')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
println(pos)
|
println(pos2)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println('start')
|
println('start')
|
||||||
foo()
|
foo()
|
||||||
|
@ -82,6 +86,7 @@ fn main() {
|
||||||
str_inter()
|
str_inter()
|
||||||
match_expr()
|
match_expr()
|
||||||
reassign_str()
|
reassign_str()
|
||||||
|
// optional_str()
|
||||||
// str_replace()
|
// str_replace()
|
||||||
println('end')
|
println('end')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue