Skip to main content

luaur_ast/methods/
parser_parse_simple_expr.rs

1use crate::records::ast_array::AstArray;
2use crate::records::ast_attr::AstAttr;
3use crate::records::ast_expr::AstExpr;
4use crate::records::ast_expr_constant_bool::AstExprConstantBool;
5use crate::records::ast_expr_constant_nil::AstExprConstantNil;
6use crate::records::ast_expr_varargs::AstExprVarargs;
7use crate::records::ast_name::AstName;
8use crate::records::lexeme::Type;
9use crate::records::parser::Parser;
10
11impl Parser {
12    pub fn parse_simple_expr(&mut self) -> *mut AstExpr {
13        let start = self.lexer.current().location;
14
15        let mut attributes: AstArray<*mut AstAttr> = AstArray {
16            data: core::ptr::null_mut(),
17            size: 0,
18        };
19
20        if self.lexer.current().r#type == Type::Attribute
21            || self.lexer.current().r#type == Type::AttributeOpen
22        {
23            attributes = self.parse_attributes();
24
25            if self.lexer.current().r#type != Type::ReservedFunction {
26                return self.report_expr_error(
27                    start,
28                    AstArray {
29                        data: core::ptr::null_mut(),
30                        size: 0,
31                    },
32                    format_args!(
33                        "Expected 'function' declaration after attribute, but got {} instead",
34                        self.lexer.current().to_string()
35                    ),
36                ) as *mut AstExpr;
37            }
38        }
39
40        if self.lexer.current().r#type == Type::ReservedNil {
41            self.next_lexeme();
42            unsafe { (*self.allocator).alloc(AstExprConstantNil::new(start)) as *mut AstExpr }
43        } else if self.lexer.current().r#type == Type::ReservedTrue {
44            self.next_lexeme();
45            unsafe {
46                (*self.allocator).alloc(AstExprConstantBool::new(start, true)) as *mut AstExpr
47            }
48        } else if self.lexer.current().r#type == Type::ReservedFalse {
49            self.next_lexeme();
50            unsafe {
51                (*self.allocator).alloc(AstExprConstantBool::new(start, false)) as *mut AstExpr
52            }
53        } else if self.lexer.current().r#type == Type::ReservedFunction {
54            let match_function = self.lexer.current().clone();
55            self.next_lexeme();
56
57            self.parse_function_body(
58                false,
59                &match_function,
60                &AstName::new(),
61                None,
62                &attributes,
63                false,
64            )
65            .0 as *mut AstExpr
66        } else if self.lexer.current().r#type == Type::Number {
67            self.parse_number()
68        } else if self.lexer.current().r#type == Type::RawString
69            || self.lexer.current().r#type == Type::QuotedString
70            || self.lexer.current().r#type == Type::InterpStringSimple
71        {
72            self.parse_string()
73        } else if self.lexer.current().r#type == Type::InterpStringBegin {
74            self.parse_interp_string()
75        } else if self.lexer.current().r#type == Type::BrokenString {
76            self.next_lexeme();
77            self.report_expr_error(
78                start,
79                AstArray {
80                    data: core::ptr::null_mut(),
81                    size: 0,
82                },
83                format_args!("Malformed string; did you forget to finish it?"),
84            ) as *mut AstExpr
85        } else if self.lexer.current().r#type == Type::BrokenInterpDoubleBrace {
86            self.next_lexeme();
87            self.report_expr_error(
88                start,
89                AstArray {
90                    data: core::ptr::null_mut(),
91                    size: 0,
92                },
93                format_args!("Double braces are not permitted within interpolated strings; did you mean '\\{{'?"),
94            ) as *mut AstExpr
95        } else if self.lexer.current().r#type == Type::Dot3 {
96            if self.function_stack.last().map_or(false, |f| f.vararg) {
97                self.next_lexeme();
98                unsafe { (*self.allocator).alloc(AstExprVarargs::new(start)) as *mut AstExpr }
99            } else {
100                self.next_lexeme();
101                self.report_expr_error(
102                    start,
103                    AstArray {
104                        data: core::ptr::null_mut(),
105                        size: 0,
106                    },
107                    format_args!("Cannot use '...' outside of a vararg function"),
108                ) as *mut AstExpr
109            }
110        } else if self.lexer.current().r#type == Type('{' as i32) {
111            // C++ `else if (lexer.current().type == '{') return parseTableConstructor();`
112            // The model mistranslated the brace literal `'{'` as `'('`, routing
113            // parenthesized expressions into the table-constructor parser and causing
114            // unbounded recursion on any `(expr)`.
115            self.parse_table_constructor()
116        } else if self.lexer.current().r#type == Type::ReservedIf {
117            self.parse_if_else_expr()
118        } else {
119            self.parse_primary_expr(false)
120        }
121    }
122}