v.gen.c: fix error of if_expr in infix_expr (#11200)
parent
d7490abe19
commit
90b052b1db
|
@ -168,13 +168,14 @@ mut:
|
||||||
// TypeOne, TypeTwo {}
|
// TypeOne, TypeTwo {}
|
||||||
// where an aggregate (at least two types) is generated
|
// where an aggregate (at least two types) is generated
|
||||||
// sum type deref needs to know which index to deref because unions take care of the correct field
|
// sum type deref needs to know which index to deref because unions take care of the correct field
|
||||||
aggregate_type_idx int
|
aggregate_type_idx int
|
||||||
returned_var_name string // to detect that a var doesn't need to be freed since it's being returned
|
returned_var_name string // to detect that a var doesn't need to be freed since it's being returned
|
||||||
branch_parent_pos int // used in BranchStmt (continue/break) for autofree stop position
|
branch_parent_pos int // used in BranchStmt (continue/break) for autofree stop position
|
||||||
timers &util.Timers = util.new_timers(false)
|
infix_left_var_name string // a && if expr
|
||||||
force_main_console bool // true when [console] used on fn main()
|
timers &util.Timers = util.new_timers(false)
|
||||||
as_cast_type_names map[string]string // table for type name lookup in runtime (for __as_cast)
|
force_main_console bool // true when [console] used on fn main()
|
||||||
obf_table map[string]string
|
as_cast_type_names map[string]string // table for type name lookup in runtime (for __as_cast)
|
||||||
|
obf_table map[string]string
|
||||||
// main_fn_decl_node ast.FnDecl
|
// main_fn_decl_node ast.FnDecl
|
||||||
expected_cast_type ast.Type // for match expr of sumtypes
|
expected_cast_type ast.Type // for match expr of sumtypes
|
||||||
defer_vars []string
|
defer_vars []string
|
||||||
|
@ -4626,6 +4627,10 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
|
||||||
cur_line = g.go_before_stmt(0)
|
cur_line = g.go_before_stmt(0)
|
||||||
g.empty_line = true
|
g.empty_line = true
|
||||||
g.writeln('$styp $tmp; /* if prepend */')
|
g.writeln('$styp $tmp; /* if prepend */')
|
||||||
|
if g.infix_left_var_name.len > 0 {
|
||||||
|
g.writeln('if ($g.infix_left_var_name) {')
|
||||||
|
g.indent++
|
||||||
|
}
|
||||||
} else if node.is_expr || g.inside_ternary != 0 {
|
} else if node.is_expr || g.inside_ternary != 0 {
|
||||||
g.inside_ternary++
|
g.inside_ternary++
|
||||||
g.write('(')
|
g.write('(')
|
||||||
|
@ -4739,6 +4744,10 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
|
||||||
}
|
}
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
if needs_tmp_var {
|
if needs_tmp_var {
|
||||||
|
if g.infix_left_var_name.len > 0 {
|
||||||
|
g.indent--
|
||||||
|
g.writeln('}')
|
||||||
|
}
|
||||||
g.empty_line = false
|
g.empty_line = false
|
||||||
g.write('$cur_line $tmp')
|
g.write('$cur_line $tmp')
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,9 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
||||||
.left_shift {
|
.left_shift {
|
||||||
g.infix_expr_left_shift_op(node)
|
g.infix_expr_left_shift_op(node)
|
||||||
}
|
}
|
||||||
|
.and, .logical_or {
|
||||||
|
g.infix_expr_and_or_op(node)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// `x & y == 0` => `(x & y) == 0` in C
|
// `x & y == 0` => `(x & y) == 0` in C
|
||||||
need_par := node.op in [.amp, .pipe, .xor]
|
need_par := node.op in [.amp, .pipe, .xor]
|
||||||
|
@ -499,28 +502,34 @@ fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// infix_expr_and_or_op generates code for `&&` and `||`
|
||||||
|
fn (mut g Gen) infix_expr_and_or_op(node ast.InfixExpr) {
|
||||||
|
if node.right is ast.IfExpr {
|
||||||
|
// b := a && if true { a = false ...} else {...}
|
||||||
|
if g.need_tmp_var_in_if(node.right) {
|
||||||
|
tmp := g.new_tmp_var()
|
||||||
|
cur_line := g.go_before_stmt(0).trim_space()
|
||||||
|
g.empty_line = true
|
||||||
|
g.write('bool $tmp = (')
|
||||||
|
g.expr(node.left)
|
||||||
|
g.writeln(');')
|
||||||
|
g.stmt_path_pos << g.out.len
|
||||||
|
g.write('$cur_line $tmp $node.op.str() ')
|
||||||
|
g.infix_left_var_name = if node.op == .and { tmp } else { '!$tmp' }
|
||||||
|
g.expr(node.right)
|
||||||
|
g.infix_left_var_name = ''
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.gen_plain_infix_expr(node)
|
||||||
|
}
|
||||||
|
|
||||||
// gen_plain_infix_expr generates basic code for infix expressions,
|
// gen_plain_infix_expr generates basic code for infix expressions,
|
||||||
// without any overloading of any kind
|
// without any overloading of any kind
|
||||||
// i.e. v`a + 1` => c`a + 1`
|
// i.e. v`a + 1` => c`a + 1`
|
||||||
// It handles auto dereferencing of variables, as well as automatic casting
|
// It handles auto dereferencing of variables, as well as automatic casting
|
||||||
// (see Gen.expr_with_cast for more details)
|
// (see Gen.expr_with_cast for more details)
|
||||||
fn (mut g Gen) gen_plain_infix_expr(node ast.InfixExpr) {
|
fn (mut g Gen) gen_plain_infix_expr(node ast.InfixExpr) {
|
||||||
if node.left is ast.Ident && node.right is ast.IfExpr {
|
|
||||||
// b := a && if true { a = false ...} else {...}
|
|
||||||
if g.need_tmp_var_in_if(node.right) {
|
|
||||||
tmp := g.new_tmp_var()
|
|
||||||
styp := g.typ(node.left_type)
|
|
||||||
cur_line := g.go_before_stmt(0)
|
|
||||||
g.empty_line = true
|
|
||||||
g.write('$styp $tmp = ')
|
|
||||||
g.expr(node.left)
|
|
||||||
g.writeln(';')
|
|
||||||
g.stmt_path_pos << g.out.len
|
|
||||||
g.write('$cur_line $tmp $node.op.str() ')
|
|
||||||
g.expr(node.right)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if node.left_type.is_ptr() && node.left.is_auto_deref_var() {
|
if node.left_type.is_ptr() && node.left.is_auto_deref_var() {
|
||||||
g.write('*')
|
g.write('*')
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
fn main() {
|
||||||
|
mut a := false
|
||||||
|
b := a && if true {
|
||||||
|
a = true
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
println(b)
|
||||||
|
assert b == false
|
||||||
|
println(a)
|
||||||
|
assert a == false
|
||||||
|
}
|
Loading…
Reference in New Issue