luaur_compiler/methods/
compiler_try_index_constant_table.rs1use 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}