Skip to main content

luaur_compiler/methods/
compiler_compile_l_value.rs

1use crate::enums::kind::Kind;
2use crate::functions::sref_compiler::sref_ast_name;
3use crate::records::compiler::Compiler;
4use crate::records::l_value::LValue;
5use crate::records::reg_scope::RegScope;
6use luaur_ast::records::ast_expr::AstExpr;
7use luaur_ast::records::ast_expr_global::AstExprGlobal;
8use luaur_ast::records::ast_expr_index_expr::AstExprIndexExpr;
9use luaur_ast::records::ast_expr_index_name::AstExprIndexName;
10use luaur_ast::records::ast_expr_local::AstExprLocal;
11use luaur_ast::rtti;
12use luaur_common::macros::luau_assert::LUAU_ASSERT;
13
14impl Compiler {
15    pub fn compile_l_value(&mut self, node: *mut AstExpr, rs: &mut RegScope) -> LValue {
16        self.set_debug_line_ast_node(node as *mut _);
17        unsafe {
18            let expr = rtti::ast_node_as::<AstExprLocal>(node as *mut _);
19            if !expr.is_null() {
20                if luaur_common::FFlag::LuauExportValueSyntax.get() && (*(*expr).local).is_exported
21                {
22                    return LValue {
23                        kind: Kind::Kind_IndexName,
24                        reg: self.get_export_table_reg(node as *mut _),
25                        upval: 0,
26                        index: 0,
27                        number: 0,
28                        name: sref_ast_name((*(*expr).local).name),
29                        location: (*node).base.location,
30                    };
31                }
32                let reg = self.get_expr_local_reg(node);
33                if reg >= 0 {
34                    LValue {
35                        kind: Kind::Kind_Local,
36                        reg: reg as u8,
37                        upval: 0,
38                        index: 0,
39                        number: 0,
40                        name: Default::default(),
41                        location: (*node).base.location,
42                    }
43                } else {
44                    LUAU_ASSERT!((*expr).upvalue);
45                    LValue {
46                        kind: Kind::Kind_Upvalue,
47                        reg: 0,
48                        upval: self.get_upval((*expr).local),
49                        index: 0,
50                        number: 0,
51                        name: Default::default(),
52                        location: (*node).base.location,
53                    }
54                }
55            } else {
56                let expr = rtti::ast_node_as::<AstExprGlobal>(node as *mut _);
57                if !expr.is_null() {
58                    LValue {
59                        kind: Kind::Kind_Global,
60                        reg: 0,
61                        upval: 0,
62                        index: 0,
63                        number: 0,
64                        name: sref_ast_name((*expr).name),
65                        location: (*node).base.location,
66                    }
67                } else {
68                    let expr = rtti::ast_node_as::<AstExprIndexName>(node as *mut _);
69                    if !expr.is_null() {
70                        LValue {
71                            kind: Kind::Kind_IndexName,
72                            reg: self.compile_expr_auto((*expr).expr, rs),
73                            upval: 0,
74                            index: 0,
75                            number: 0,
76                            name: sref_ast_name((*expr).index),
77                            location: (*node).base.location,
78                        }
79                    } else {
80                        let expr = rtti::ast_node_as::<AstExprIndexExpr>(node as *mut _);
81                        if !expr.is_null() {
82                            let reg = self.compile_expr_auto((*expr).expr, rs);
83                            self.compile_l_value_index(reg, (*expr).index, rs)
84                        } else {
85                            LUAU_ASSERT!(false);
86                            LValue {
87                                kind: Kind::Kind_Local,
88                                reg: 0,
89                                upval: 0,
90                                index: 0,
91                                number: 0,
92                                name: Default::default(),
93                                location: (*node).base.location,
94                            }
95                        }
96                    }
97                }
98            }
99        }
100    }
101}