v.gen.c: fix error of if_expr in infix_expr (#11200)
							parent
							
								
									d7490abe19
								
							
						
					
					
						commit
						90b052b1db
					
				| 
						 | 
				
			
			@ -168,13 +168,14 @@ mut:
 | 
			
		|||
	// TypeOne, TypeTwo {}
 | 
			
		||||
	// 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
 | 
			
		||||
	aggregate_type_idx int
 | 
			
		||||
	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
 | 
			
		||||
	timers             &util.Timers = util.new_timers(false)
 | 
			
		||||
	force_main_console bool // true when [console] used on fn main()
 | 
			
		||||
	as_cast_type_names map[string]string // table for type name lookup in runtime (for __as_cast)
 | 
			
		||||
	obf_table          map[string]string
 | 
			
		||||
	aggregate_type_idx  int
 | 
			
		||||
	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
 | 
			
		||||
	infix_left_var_name string // a && if expr
 | 
			
		||||
	timers              &util.Timers = util.new_timers(false)
 | 
			
		||||
	force_main_console  bool // true when [console] used on fn main()
 | 
			
		||||
	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
 | 
			
		||||
	expected_cast_type ast.Type // for match expr of sumtypes
 | 
			
		||||
	defer_vars         []string
 | 
			
		||||
| 
						 | 
				
			
			@ -4626,6 +4627,10 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
 | 
			
		|||
		cur_line = g.go_before_stmt(0)
 | 
			
		||||
		g.empty_line = true
 | 
			
		||||
		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 {
 | 
			
		||||
		g.inside_ternary++
 | 
			
		||||
		g.write('(')
 | 
			
		||||
| 
						 | 
				
			
			@ -4739,6 +4744,10 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
 | 
			
		|||
	}
 | 
			
		||||
	g.writeln('}')
 | 
			
		||||
	if needs_tmp_var {
 | 
			
		||||
		if g.infix_left_var_name.len > 0 {
 | 
			
		||||
			g.indent--
 | 
			
		||||
			g.writeln('}')
 | 
			
		||||
		}
 | 
			
		||||
		g.empty_line = false
 | 
			
		||||
		g.write('$cur_line $tmp')
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,9 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
 | 
			
		|||
		.left_shift {
 | 
			
		||||
			g.infix_expr_left_shift_op(node)
 | 
			
		||||
		}
 | 
			
		||||
		.and, .logical_or {
 | 
			
		||||
			g.infix_expr_and_or_op(node)
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			// `x & y == 0` => `(x & y) == 0` in C
 | 
			
		||||
			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,
 | 
			
		||||
// without any overloading of any kind
 | 
			
		||||
// i.e. v`a + 1` => c`a + 1`
 | 
			
		||||
// It handles auto dereferencing of variables, as well as automatic casting
 | 
			
		||||
// (see Gen.expr_with_cast for more details)
 | 
			
		||||
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() {
 | 
			
		||||
		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