autofree: handle args in optional returns
parent
ea09bd5e45
commit
25947a7b23
|
@ -287,7 +287,7 @@ pub mut:
|
||||||
return_type table.Type
|
return_type table.Type
|
||||||
should_be_skipped bool
|
should_be_skipped bool
|
||||||
generic_type table.Type // TODO array, to support multiple types
|
generic_type table.Type // TODO array, to support multiple types
|
||||||
autofree_pregen string
|
// autofree_pregen string
|
||||||
// autofree_vars []AutofreeArgVar
|
// autofree_vars []AutofreeArgVar
|
||||||
// autofree_vars_ids []int
|
// autofree_vars_ids []int
|
||||||
}
|
}
|
||||||
|
@ -593,20 +593,20 @@ pub:
|
||||||
|
|
||||||
pub struct ForInStmt {
|
pub struct ForInStmt {
|
||||||
pub:
|
pub:
|
||||||
key_var string
|
key_var string
|
||||||
val_var string
|
val_var string
|
||||||
cond Expr
|
cond Expr
|
||||||
is_range bool
|
is_range bool
|
||||||
high Expr // `10` in `for i in 0..10 {`
|
high Expr // `10` in `for i in 0..10 {`
|
||||||
stmts []Stmt
|
stmts []Stmt
|
||||||
pos token.Position
|
pos token.Position
|
||||||
val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array
|
val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array
|
||||||
// and the array cannot be indexed inside the loop
|
|
||||||
pub mut:
|
pub mut:
|
||||||
key_type table.Type
|
// and the array cannot be indexed inside the loop
|
||||||
val_type table.Type
|
key_type table.Type
|
||||||
cond_type table.Type
|
val_type table.Type
|
||||||
kind table.Kind // array/map/string
|
cond_type table.Type
|
||||||
|
kind table.Kind // array/map/string
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ForCStmt {
|
pub struct ForCStmt {
|
||||||
|
@ -989,11 +989,7 @@ pub fn (expr Expr) position() token.Position {
|
||||||
AnonFn {
|
AnonFn {
|
||||||
return expr.decl.pos
|
return expr.decl.pos
|
||||||
}
|
}
|
||||||
ArrayInit, AsCast, Assoc, BoolLiteral, CallExpr, CastExpr, CharLiteral,
|
ArrayInit, AsCast, Assoc, BoolLiteral, CallExpr, CastExpr, CharLiteral, Comment, EnumVal, FloatLiteral, Ident, IfExpr, IndexExpr, IntegerLiteral, MapInit, MatchExpr, None, PostfixExpr, PrefixExpr, SelectExpr, SelectorExpr, SizeOf, StringLiteral, StringInterLiteral, StructInit, Likely {
|
||||||
Comment, EnumVal, FloatLiteral, Ident, IfExpr, IndexExpr,
|
|
||||||
IntegerLiteral, MapInit, MatchExpr, None, PostfixExpr, PrefixExpr,
|
|
||||||
SelectExpr, SelectorExpr, SizeOf, StringLiteral, StringInterLiteral,
|
|
||||||
StructInit, Likely {
|
|
||||||
return expr.pos
|
return expr.pos
|
||||||
}
|
}
|
||||||
InfixExpr {
|
InfixExpr {
|
||||||
|
@ -1042,11 +1038,15 @@ pub fn (expr Expr) is_expr() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if stmt can be an expression in C
|
// check if stmt can be an expression in C
|
||||||
pub fn (stmt Stmt) check_c_expr()? {
|
pub fn (stmt Stmt) check_c_expr() ? {
|
||||||
match stmt {
|
match stmt {
|
||||||
AssignStmt {return}
|
AssignStmt {
|
||||||
|
return
|
||||||
|
}
|
||||||
ExprStmt {
|
ExprStmt {
|
||||||
if stmt.expr.is_expr() {return}
|
if stmt.expr.is_expr() {
|
||||||
|
return
|
||||||
|
}
|
||||||
return error('unsupported statement (`${typeof(stmt.expr)}`)')
|
return error('unsupported statement (`${typeof(stmt.expr)}`)')
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
|
@ -1056,10 +1056,7 @@ pub fn (stmt Stmt) check_c_expr()? {
|
||||||
|
|
||||||
pub fn (stmt Stmt) position() token.Position {
|
pub fn (stmt Stmt) position() token.Position {
|
||||||
match stmt {
|
match stmt {
|
||||||
AssertStmt, AssignStmt, Block, ConstDecl, EnumDecl, ExprStmt, FnDecl,
|
AssertStmt, AssignStmt, Block, ConstDecl, EnumDecl, ExprStmt, FnDecl, ForCStmt, ForInStmt, ForStmt, Import, Return, StructDecl { return stmt.pos }
|
||||||
ForCStmt, ForInStmt, ForStmt, Import, Return, StructDecl {
|
|
||||||
return stmt.pos
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
Attr {}
|
Attr {}
|
||||||
BranchStmt {}
|
BranchStmt {}
|
||||||
|
|
|
@ -985,12 +985,16 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
ast.Return {
|
ast.Return {
|
||||||
g.write_defer_stmts_when_needed()
|
g.write_defer_stmts_when_needed()
|
||||||
|
af := g.pref.autofree && node.exprs.len > 0 && node.exprs[0] is ast.CallExpr && !g.is_builtin_mod
|
||||||
if g.pref.autofree {
|
if g.pref.autofree {
|
||||||
g.writeln('// ast.Return free')
|
g.writeln('// ast.Return free')
|
||||||
|
if af {
|
||||||
|
g.autofree_call_pregen(node.exprs[0] as ast.CallExpr)
|
||||||
|
}
|
||||||
// g.autofree_scope_vars(node.pos.pos)
|
// g.autofree_scope_vars(node.pos.pos)
|
||||||
g.write_autofree_stmts_when_needed(node)
|
g.write_autofree_stmts_when_needed(node)
|
||||||
}
|
}
|
||||||
g.return_statement(node)
|
g.return_statement(node, af)
|
||||||
}
|
}
|
||||||
ast.SqlStmt {
|
ast.SqlStmt {
|
||||||
g.sql_stmt(node)
|
g.sql_stmt(node)
|
||||||
|
@ -3458,7 +3462,7 @@ fn (g &Gen) expr_is_multi_return_call(expr ast.Expr) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) return_statement(node ast.Return) {
|
fn (mut g Gen) return_statement(node ast.Return, af bool) {
|
||||||
g.write_v_source_line_info(node.pos)
|
g.write_v_source_line_info(node.pos)
|
||||||
if node.exprs.len > 0 {
|
if node.exprs.len > 0 {
|
||||||
// skip `retun $vweb.html()`
|
// skip `retun $vweb.html()`
|
||||||
|
@ -3496,6 +3500,10 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||||
g.write('Option $tmp = ')
|
g.write('Option $tmp = ')
|
||||||
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
|
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
|
if af {
|
||||||
|
// free the tmp arg expr if we have one before the return
|
||||||
|
g.autofree_call_postgen()
|
||||||
|
}
|
||||||
styp := g.typ(g.fn_decl.return_type)
|
styp := g.typ(g.fn_decl.return_type)
|
||||||
g.writeln('return *($styp*)&$tmp;')
|
g.writeln('return *($styp*)&$tmp;')
|
||||||
return
|
return
|
||||||
|
|
|
@ -109,6 +109,20 @@ fn optional_str() {
|
||||||
println(pos + 1)
|
println(pos + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn return_error_with_freed_expr() ?string {
|
||||||
|
if true {
|
||||||
|
msg := 'oops'
|
||||||
|
return error('hm $msg')
|
||||||
|
}
|
||||||
|
return 'ok'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn optional_return() {
|
||||||
|
return_error_with_freed_expr() or {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn tt() {
|
fn tt() {
|
||||||
// time.parse_rfc2822('1234')
|
// time.parse_rfc2822('1234')
|
||||||
}
|
}
|
||||||
|
@ -123,6 +137,7 @@ fn main() {
|
||||||
match_expr()
|
match_expr()
|
||||||
reassign_str()
|
reassign_str()
|
||||||
optional_str()
|
optional_str()
|
||||||
|
optional_return()
|
||||||
// str_replace()
|
// str_replace()
|
||||||
println('end')
|
println('end')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue