Skip to main content

luaur_compiler/methods/
compiler_compile_expr_unary.rs

1use crate::records::compile_error::CompileError;
2use crate::records::compiler::Compiler;
3use crate::records::reg_scope::RegScope;
4use luaur_ast::records::ast_expr_constant_integer::AstExprConstantInteger;
5use luaur_ast::records::ast_expr_unary::AstExprUnary;
6use luaur_ast::rtti;
7
8impl Compiler {
9    pub fn compile_expr_unary(&mut self, expr: *mut AstExprUnary, target: u8) {
10        unsafe {
11            let expr_ref = &*expr;
12            let mut rs = self.reg_scope_compiler();
13
14            if luaur_common::FFlag::LuauIntegerType2.get()
15                && expr_ref.op == luaur_ast::records::ast_expr_unary::AstExprUnaryOp::Minus
16            {
17                let cint = rtti::ast_node_as::<AstExprConstantInteger>(expr_ref.expr as *mut _);
18                if !cint.is_null() {
19                    let cid =
20                        (*self.bytecode).add_constant_integer((!((*cint).value as u64) + 1) as i64);
21                    if cid < 0 {
22                        CompileError::raise(
23                            &expr_ref.base.base.location,
24                            format_args!("Exceeded constant limit; simplify the code to compile"),
25                        );
26                    }
27                    self.emit_load_k(target, cid);
28                    return;
29                }
30            }
31
32            let re = self.compile_expr_auto(expr_ref.expr, &mut rs);
33            (*self.bytecode).emit_abc(self.get_unary_op(expr_ref.op), target, re, 0);
34        }
35    }
36}