Skip to main content

luaur_compiler/methods/
compiler_try_index_constant_table.rs

1use crate::enums::table_constant_kind::TableConstantKind;
2use crate::enums::type_constant_folding::Type;
3use crate::functions::unwrap_expr_of_type::unwrap_expr_of_type;
4use crate::records::compiler::Compiler;
5use crate::records::constant::Constant;
6use crate::records::variable::Variable;
7use luaur_ast::records::ast_expr::AstExpr;
8use luaur_ast::records::ast_expr_index_name::AstExprIndexName;
9use luaur_ast::records::ast_expr_local::AstExprLocal;
10use luaur_ast::records::ast_expr_table::AstExprTable;
11use luaur_ast::records::ast_name::AstName;
12use luaur_ast::records::item_ast::ItemKind;
13
14impl Compiler {
15    pub fn try_index_constant_table(&mut self, expr: *mut AstExprIndexName) -> *mut AstExpr {
16        unsafe {
17            if expr.is_null() {
18                return core::ptr::null_mut();
19            }
20
21            let table_expr = (*expr).expr;
22            let table_local = unwrap_expr_of_type::<AstExprLocal>(table_expr);
23            if table_local.is_null() {
24                return core::ptr::null_mut();
25            }
26
27            let lv = self.variables.find(&(*table_local).local);
28            if lv.is_none() {
29                return core::ptr::null_mut();
30            }
31            let lv = *lv.unwrap();
32            if lv.written || lv.init.is_null() {
33                return core::ptr::null_mut();
34            }
35
36            let table_kind = self.table_constants.find(&(*table_local).local);
37            if table_kind.is_none() {
38                return core::ptr::null_mut();
39            }
40            let table_kind = *table_kind.unwrap();
41            if table_kind != TableConstantKind::ConstantTable {
42                return core::ptr::null_mut();
43            }
44
45            let table = unwrap_expr_of_type::<AstExprTable>(lv.init);
46            if table.is_null() {
47                return core::ptr::null_mut();
48            }
49
50            let mut match_value: *mut AstExpr = core::ptr::null_mut();
51
52            for item in (*table).items.as_slice() {
53                if item.kind == ItemKind::Record || item.kind == ItemKind::General {
54                    let key_constant = self.constants.find(&item.key);
55                    if key_constant.is_none() {
56                        match_value = core::ptr::null_mut();
57                    } else {
58                        let key_constant = key_constant.unwrap();
59                        if key_constant.r#type == Type::Type_String
60                            && key_constant.string_length != 0
61                        {
62                            let key_name = unsafe {
63                                let arr = key_constant.get_string();
64                                (*self.names).get_or_add(arr.data, arr.size as usize)
65                            };
66
67                            if key_name.operator_eq_ast_name(&(*expr).index) {
68                                match_value = item.value;
69                            }
70                        }
71                    }
72                }
73            }
74
75            match_value
76        }
77    }
78}