cgen/autofree: fix and simplify optionals
parent
f162e61748
commit
b74c1805d7
|
@ -850,6 +850,15 @@ pub:
|
|||
pos token.Position
|
||||
}
|
||||
|
||||
// `or { ... }`
|
||||
pub struct OrExpr2 {
|
||||
pub:
|
||||
call_expr CallExpr
|
||||
stmts []Stmt // inside `or { }`
|
||||
kind OrKind
|
||||
pos token.Position
|
||||
}
|
||||
|
||||
pub struct Assoc {
|
||||
pub:
|
||||
var_name string
|
||||
|
|
|
@ -2629,6 +2629,9 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
|||
// never happens
|
||||
return table.void_type
|
||||
}
|
||||
// ast.OrExpr2 {
|
||||
// return node.typ
|
||||
// }
|
||||
ast.ParExpr {
|
||||
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')
|
||||
}
|
||||
}
|
||||
// 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
|
||||
if return_type != table.void_type && return_type != 0 {
|
||||
sym := g.table.get_type_symbol(return_type)
|
||||
|
|
|
@ -280,9 +280,12 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
|||
defer {
|
||||
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
|
||||
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)
|
||||
g.out.write(tabs[g.indent])
|
||||
line
|
||||
|
@ -304,10 +307,13 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
|||
} else {
|
||||
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)
|
||||
}
|
||||
if is_gen_or_and_assign_rhs {
|
||||
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')
|
||||
}
|
||||
}
|
||||
|
@ -545,13 +551,14 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
|||
t := '_tt${g.tmp_count2}_arg_expr_${fn_name}_$i'
|
||||
g.called_fn_name = name
|
||||
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)
|
||||
// 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)`
|
||||
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
|
||||
if free_tmp_arg_vars {
|
||||
// g.writeln(';')
|
||||
g.write(cur_line + ' /* cur line*/')
|
||||
g.write(cur_line + ' /* <== af cur line*/')
|
||||
}
|
||||
g.write('${g.get_ternary_name(name)}(')
|
||||
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_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) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import v.token
|
|||
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.Expr {
|
||||
first_pos := p.tok.position()
|
||||
mut fn_name := if language == .c {
|
||||
'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
|
||||
}
|
||||
}
|
||||
/*
|
||||
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{
|
||||
name: fn_name
|
||||
args: args
|
||||
|
|
|
@ -64,17 +64,21 @@ fn match_expr() string {
|
|||
return res
|
||||
}
|
||||
|
||||
/*
|
||||
fn opt(s string) ?int {
|
||||
return 1
|
||||
}
|
||||
|
||||
fn optional_str() {
|
||||
q := 'select'
|
||||
s := 'x'
|
||||
pos := s.index('query: $q') or {
|
||||
pos2 := opt('query:$q') or {
|
||||
// pos := s.index('query: $q') or {
|
||||
println('exiting')
|
||||
return
|
||||
}
|
||||
println(pos)
|
||||
println(pos2)
|
||||
}
|
||||
*/
|
||||
|
||||
fn main() {
|
||||
println('start')
|
||||
foo()
|
||||
|
@ -82,6 +86,7 @@ fn main() {
|
|||
str_inter()
|
||||
match_expr()
|
||||
reassign_str()
|
||||
// optional_str()
|
||||
// str_replace()
|
||||
println('end')
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue