luaur_compiler/methods/
compiler_compile_expr_if_else.rs1use crate::records::compiler::Compiler;
2use luaur_ast::records::ast_expr::AstExpr;
3use luaur_ast::records::ast_expr_if_else::AstExprIfElse;
4use luaur_ast::records::ast_node::AstNode;
5use luaur_common::enums::luau_opcode::LuauOpcode;
6
7impl Compiler {
8 pub fn compile_expr_if_else(
9 &mut self,
10 expr: *mut AstExprIfElse,
11 target: u8,
12 target_temp: bool,
13 ) {
14 let expr_ref = unsafe { &*expr };
15
16 if self.is_constant(expr_ref.condition) {
17 if self.is_constant_true(expr_ref.condition) {
18 self.compile_expr(expr_ref.true_expr, target, target_temp);
19 } else {
20 self.compile_expr(expr_ref.false_expr, target, target_temp);
21 }
22 } else {
23 let creg = self.get_expr_local_reg(expr_ref.condition);
24 if creg >= 0 {
25 let true_reg = self.get_expr_local_reg(expr_ref.true_expr);
26 let false_reg = self.get_expr_local_reg(expr_ref.false_expr);
27
28 if creg == true_reg && (false_reg >= 0 || self.is_constant(expr_ref.false_expr)) {
29 return self.compile_expr_if_else_and_or(
30 false,
31 creg as u8,
32 expr_ref.false_expr,
33 target,
34 );
35 } else if creg == false_reg
36 && (true_reg >= 0 || self.is_constant(expr_ref.true_expr))
37 {
38 return self.compile_expr_if_else_and_or(
39 true,
40 creg as u8,
41 expr_ref.true_expr,
42 target,
43 );
44 }
45 }
46
47 let mut else_jump = Vec::new();
48 self.compile_condition_value(
49 expr_ref.condition,
50 core::ptr::null(),
51 &mut else_jump,
52 false,
53 );
54 self.compile_expr(expr_ref.true_expr, target, target_temp);
55
56 let bytecode = unsafe { &mut *self.bytecode };
57 let then_label = bytecode.emit_label();
58 bytecode.emit_ad(LuauOpcode::LOP_JUMP, 0, 0);
59
60 let else_label = bytecode.emit_label();
61 self.compile_expr(expr_ref.false_expr, target, target_temp);
62 let end_label = bytecode.emit_label();
63
64 self.patch_jumps(expr as *mut AstNode, &mut else_jump, else_label);
65 self.patch_jump(expr as *mut AstNode, then_label, end_label);
66 }
67 }
68}