Skip to main content

luaur_compiler/methods/
compiler_compile_l_value_index.rs

1use crate::enums::kind::Kind;
2use crate::enums::type_constant_folding::Type;
3use crate::records::compiler::Compiler;
4use crate::records::constant::Constant;
5use crate::records::l_value::LValue;
6use crate::records::reg_scope::RegScope;
7use luaur_ast::records::ast_expr::AstExpr;
8
9impl Compiler {
10    pub fn compile_l_value_index(
11        &mut self,
12        reg: u8,
13        index: *mut AstExpr,
14        rs: &mut RegScope,
15    ) -> LValue {
16        let cv = self.get_constant(index);
17        if cv.r#type == Type::Type_Number && {
18            let value_number = unsafe { cv.data.value_number };
19            value_number >= 1.0
20                && value_number <= 256.0
21                && (value_number as i32) as f64 == value_number
22        } {
23            let value_number = unsafe { cv.data.value_number };
24            LValue {
25                kind: Kind::Kind_IndexNumber,
26                reg,
27                upval: 0,
28                index: 0,
29                number: (value_number as i32 - 1) as u8,
30                name: Default::default(),
31                location: unsafe { (*index).base.location },
32            }
33        } else if cv.r#type == Type::Type_String {
34            LValue {
35                kind: Kind::Kind_IndexName,
36                reg,
37                upval: 0,
38                index: 0,
39                number: 0,
40                // C++ `sref(cv.getString())` preserves the byte length. Routing through
41                // AstName::ast_name_c_char treated the data as a NUL-terminated C-string and
42                // truncated keys containing embedded NULs (e.g. "a\0" -> "a"), wrongly
43                // deduping them with "a".
44                name: crate::functions::sref_compiler_alt_c::sref_ast_array_c_char(cv.get_string()),
45                location: unsafe { (*index).base.location },
46            }
47        } else {
48            LValue {
49                kind: Kind::Kind_IndexExpr,
50                reg,
51                upval: 0,
52                index: self.compile_expr_auto(index, rs),
53                number: 0,
54                name: Default::default(),
55                location: unsafe { (*index).base.location },
56            }
57        }
58    }
59}