Skip to main content

luaur_code_gen/functions/
to_string_ir_dump_alt_e.rs

1extern crate alloc;
2
3use crate::enums::ir_const_kind::IrConstKind;
4use crate::functions::append::append;
5use crate::functions::append_vm_constant::append_vm_constant;
6use crate::functions::format_g::format_g;
7use crate::functions::get_tag_name::get_tag_name;
8use crate::records::ir_const::IrConst;
9use alloc::string::String;
10use luaur_vm::type_aliases::proto::Proto;
11
12pub fn to_string(result: &mut String, proto: *mut Proto, constant: IrConst) {
13    unsafe {
14        match constant.kind {
15            IrConstKind::Int => append(result, format_args!("{}i", constant.value.value_int)),
16            IrConstKind::Int64 => append(
17                result,
18                format_args!("{}i", constant.value.value_int64 as i64),
19            ),
20            IrConstKind::Uint => append(result, format_args!("{}u", constant.value.value_uint)),
21            IrConstKind::Double => {
22                let d = constant.value.value_double;
23                if d != d {
24                    append(result, format_args!("nan"));
25                } else {
26                    // C++ uses printf "%.17g"; Rust's `{}` prints the shortest
27                    // round-tripping form (e.g. `0.4` vs `0.40000000000000002`).
28                    result.push_str(&format_g(d, 17));
29                }
30            }
31            IrConstKind::Tag => result.push_str(get_tag_name(constant.value.value_tag)),
32            IrConstKind::Import => {
33                append(result, format_args!("{}u", constant.value.value_uint));
34
35                if !proto.is_null() {
36                    append(result, format_args!(" ("));
37
38                    let value_uint = constant.value.value_uint;
39                    let count = (value_uint >> 30) as i32;
40                    let id0 = if count > 0 {
41                        ((value_uint >> 20) & 1023) as i32
42                    } else {
43                        -1
44                    };
45                    let id1 = if count > 1 {
46                        ((value_uint >> 10) & 1023) as i32
47                    } else {
48                        -1
49                    };
50                    let id2 = if count > 2 {
51                        (value_uint & 1023) as i32
52                    } else {
53                        -1
54                    };
55
56                    if id0 != -1 {
57                        append_vm_constant(result, proto, id0);
58                    }
59
60                    if id1 != -1 {
61                        append(result, format_args!("."));
62                        append_vm_constant(result, proto, id1);
63                    }
64
65                    if id2 != -1 {
66                        append(result, format_args!("."));
67                        append_vm_constant(result, proto, id2);
68                    }
69
70                    append(result, format_args!(")"));
71                }
72            }
73        }
74    }
75}