luaur_compiler/methods/
compiler_compile_stat_compound_assign.rs1use crate::enums::type_constant_folding::Type;
2use crate::records::assignment::Assignment;
3use crate::records::compiler::Compiler;
4use crate::records::constant::Constant;
5use crate::records::reg_scope::RegScope;
6use luaur_ast::records::ast_expr_binary::AstExprBinaryOp;
7use luaur_ast::records::ast_stat_compound_assign::AstStatCompoundAssign;
8use luaur_common::enums::luau_bytecode_type::LuauBytecodeType;
9use luaur_common::enums::luau_opcode::LuauOpcode;
10use luaur_common::macros::luau_assert::LUAU_ASSERT;
11
12impl Compiler {
13 pub fn compile_stat_compound_assign(&mut self, stat: *mut AstStatCompoundAssign) {
14 unsafe {
15 let stat_ref = &*stat;
16 let mut rs = self.reg_scope_compiler();
17 let var = self.compile_l_value(stat_ref.var, &mut rs);
18 let target = if var.kind == crate::enums::kind::Kind::Kind_Local {
19 var.reg
20 } else {
21 self.alloc_reg(stat as *mut _, 1)
22 };
23
24 match stat_ref.op {
25 AstExprBinaryOp::Add
26 | AstExprBinaryOp::Sub
27 | AstExprBinaryOp::Mul
28 | AstExprBinaryOp::Div
29 | AstExprBinaryOp::FloorDiv
30 | AstExprBinaryOp::Mod
31 | AstExprBinaryOp::Pow => {
32 if var.kind != crate::enums::kind::Kind::Kind_Local {
33 self.compile_l_value_use(&var, target, false, stat_ref.var);
34 }
35 let rc = self.get_constant_number(stat_ref.value);
36 if rc >= 0 && rc <= 255 {
37 (*self.bytecode).emit_abc(
38 self.get_binary_op_arith(stat_ref.op, true),
39 target,
40 target,
41 rc as u8,
42 );
43 } else {
44 let rr = self.compile_expr_auto(stat_ref.value, &mut rs);
45 (*self.bytecode).emit_abc(
46 self.get_binary_op_arith(stat_ref.op, false),
47 target,
48 target,
49 rr,
50 );
51 if var.kind != crate::enums::kind::Kind::Kind_Local {
52 self.hint_temporary_reg_type(
53 stat_ref.var,
54 target as i32,
55 LuauBytecodeType(2),
56 1,
57 );
58 }
59 self.hint_temporary_expr_reg_type(
60 stat_ref.value,
61 rr as i32,
62 LuauBytecodeType(2),
63 1,
64 );
65 }
66 }
67 AstExprBinaryOp::Concat => {
68 let mut args = vec![stat_ref.value];
69 self.unroll_concats(&mut args);
70 let regs = self.alloc_reg(stat as *mut _, (1 + args.len()) as u32);
71 self.compile_l_value_use(&var, regs, false, stat_ref.var);
72 for (i, &arg) in args.iter().enumerate() {
73 self.compile_expr_temp(arg, regs + 1 + i as u8);
74 }
75 (*self.bytecode).emit_abc(
76 LuauOpcode::LOP_CONCAT,
77 target,
78 regs,
79 regs + args.len() as u8,
80 );
81 }
82 _ => LUAU_ASSERT!(false),
83 }
84
85 if var.kind != crate::enums::kind::Kind::Kind_Local {
86 self.compile_assign(&var, target, stat_ref.var);
87 }
88 }
89 }
90}