Skip to main content

luaur_ast/methods/
parser_parse_number.rs

1use crate::enums::constant_number_parse_result::ConstantNumberParseResult;
2use crate::functions::parse_double::parse_double;
3use crate::functions::parse_integer_64::parse_integer_64;
4use crate::records::ast_array::AstArray;
5use crate::records::ast_expr::AstExpr;
6use crate::records::ast_expr_constant_integer::AstExprConstantInteger;
7use crate::records::ast_expr_constant_number::AstExprConstantNumber;
8use crate::records::cst_expr_constant_integer::CstExprConstantInteger;
9use crate::records::cst_expr_constant_number::CstExprConstantNumber;
10use crate::records::parser::Parser;
11use luaur_common::FFlag;
12
13impl Parser {
14    pub fn parse_number(&mut self) -> *mut AstExpr {
15        // scratchData.assign(lexer.current().data, lexer.current().getLength());
16        let (start, data_ptr, lexeme_len) = {
17            let current = self.lexer.current();
18            (
19                current.location,
20                unsafe { current.data.data } as *const u8,
21                current.get_length() as usize,
22            )
23        };
24        self.scratch_data.clear();
25        let bytes = unsafe { core::slice::from_raw_parts(data_ptr, lexeme_len) };
26        self.scratch_data
27            .push_str(core::str::from_utf8(bytes).unwrap_or(""));
28
29        let mut source_data = AstArray::default();
30        if self.options.store_cst_data {
31            let sd = self.scratch_data.clone();
32            source_data = self.copy_string(&sd);
33        }
34
35        // Remove all internal _
36        if self.scratch_data.contains('_') {
37            self.scratch_data.retain(|c| c != '_');
38        }
39
40        if FFlag::LuauIntegerType2.get() && self.scratch_data.ends_with('i') {
41            let mut value: i64 = 0;
42            let result: ConstantNumberParseResult;
43
44            if self.scratch_data.starts_with("0x") || self.scratch_data.starts_with("0X") {
45                result = parse_integer_64(&mut value, &self.scratch_data, 16);
46            } else if self.scratch_data.starts_with("0b") || self.scratch_data.starts_with("0B") {
47                result = parse_integer_64(&mut value, &self.scratch_data[2..], 2);
48            } else {
49                result = parse_integer_64(&mut value, &self.scratch_data, 10);
50            }
51
52            self.next_lexeme();
53
54            if result == ConstantNumberParseResult::Malformed {
55                return self.report_expr_error(
56                    start,
57                    AstArray::default(),
58                    format_args!("Malformed integer"),
59                ) as *mut AstExpr;
60            }
61
62            if result != ConstantNumberParseResult::Ok {
63                return self.report_expr_error(
64                    start,
65                    AstArray::default(),
66                    format_args!("Integer overflow"),
67                ) as *mut AstExpr;
68            }
69
70            let node = unsafe {
71                (*self.allocator).alloc(AstExprConstantInteger {
72                    base: AstExpr {
73                        base: crate::records::ast_node::AstNode {
74                            class_index:
75                                <AstExprConstantInteger as crate::rtti::AstNodeClass>::CLASS_INDEX,
76                            location: start,
77                        },
78                    },
79                    value,
80                    parse_result: result,
81                })
82            };
83
84            if self.options.store_cst_data {
85                let cst_node = unsafe {
86                    (*self.allocator).alloc(CstExprConstantInteger {
87                        base: crate::records::cst_node::CstNode {
88                            class_index:
89                                <CstExprConstantInteger as crate::rtti::CstNodeClass>::CLASS_INDEX,
90                        },
91                        value: source_data,
92                    })
93                };
94                self.cst_node_map.try_insert(
95                    node as *mut crate::records::ast_node::AstNode,
96                    cst_node as *mut crate::records::cst_node::CstNode,
97                );
98            }
99
100            node as *mut AstExpr
101        } else {
102            let mut value: f64 = 0.0;
103            let result = parse_double(&mut value, &self.scratch_data);
104
105            self.next_lexeme();
106
107            if result == ConstantNumberParseResult::Malformed {
108                return self.report_expr_error(
109                    start,
110                    AstArray::default(),
111                    format_args!("Malformed number"),
112                ) as *mut AstExpr;
113            }
114
115            let node = unsafe {
116                (*self.allocator).alloc(AstExprConstantNumber {
117                    base: AstExpr {
118                        base: crate::records::ast_node::AstNode {
119                            class_index:
120                                <AstExprConstantNumber as crate::rtti::AstNodeClass>::CLASS_INDEX,
121                            location: start,
122                        },
123                    },
124                    value,
125                    parse_result: result,
126                })
127            };
128
129            if self.options.store_cst_data {
130                let cst_node = unsafe {
131                    (*self.allocator).alloc(CstExprConstantNumber {
132                        base: crate::records::cst_node::CstNode {
133                            class_index:
134                                <CstExprConstantNumber as crate::rtti::CstNodeClass>::CLASS_INDEX,
135                        },
136                        value: source_data,
137                    })
138                };
139                self.cst_node_map.try_insert(
140                    node as *mut crate::records::ast_node::AstNode,
141                    cst_node as *mut crate::records::cst_node::CstNode,
142                );
143            }
144
145            node as *mut AstExpr
146        }
147    }
148}