Skip to main content

luaur_ast/methods/
parser_parse_string.rs

1use crate::records::ast_array::AstArray;
2use crate::records::ast_expr::AstExpr;
3use crate::records::ast_expr_constant_string::AstExprConstantString;
4use crate::records::cst_expr_constant_string::CstExprConstantString;
5use crate::records::lexeme::Type;
6use crate::records::location::Location;
7use crate::records::parser::Parser;
8use core::ffi::c_char;
9use luaur_common::macros::luau_assert::LUAU_ASSERT;
10
11impl Parser {
12    pub fn parse_string(&mut self) -> *mut AstExpr {
13        let location: Location = self.lexer.current().location;
14
15        let style = match self.lexer.current().r#type {
16            Type::QuotedString | Type::InterpStringSimple => AstExprConstantString::QuotedSimple,
17            Type::RawString => AstExprConstantString::QuotedRaw,
18            _ => {
19                LUAU_ASSERT!(false);
20                AstExprConstantString::QuotedSimple
21            }
22        };
23
24        let mut full_style = crate::enums::quote_style_cst::QuoteStyle::QuotedDouble;
25        let mut block_depth: u32 = 0;
26
27        if self.options.store_cst_data {
28            let (fs, bd) = self.extract_string_details();
29            full_style = fs;
30            block_depth = bd;
31        }
32
33        let mut original_string = AstArray::<c_char> {
34            data: core::ptr::null_mut(),
35            size: 0,
36        };
37
38        if let Some(value) = self.parse_char_array(if self.options.store_cst_data {
39            Some(&mut original_string)
40        } else {
41            None
42        }) {
43            let node = unsafe {
44                (*self.allocator).alloc(AstExprConstantString {
45                    base: AstExpr {
46                        base: crate::records::ast_node::AstNode {
47                            class_index:
48                                <AstExprConstantString as crate::rtti::AstNodeClass>::CLASS_INDEX,
49                            location,
50                        },
51                    },
52                    value,
53                    quote_style: style,
54                })
55            };
56
57            if self.options.store_cst_data {
58                let cst_node = unsafe {
59                    (*self.allocator).alloc(CstExprConstantString {
60                        base: crate::records::cst_node::CstNode {
61                            class_index:
62                                <CstExprConstantString as crate::rtti::CstNodeClass>::CLASS_INDEX,
63                        },
64                        source_string: original_string,
65                        quote_style: full_style,
66                        block_depth,
67                    })
68                };
69                self.cst_node_map.try_insert(
70                    node as *mut crate::records::ast_node::AstNode,
71                    cst_node as *mut crate::records::cst_node::CstNode,
72                );
73            }
74
75            node as *mut AstExpr
76        } else {
77            self.report_expr_error(
78                location,
79                AstArray {
80                    data: core::ptr::null_mut(),
81                    size: 0,
82                },
83                format_args!("String literal contains malformed escape sequence"),
84            ) as *mut AstExpr
85        }
86    }
87}