Skip to main content

luaur_ast/methods/
parser_parse_function_name.rs

1use crate::records::ast_expr::AstExpr;
2use crate::records::ast_expr_index_name::AstExprIndexName;
3use crate::records::ast_name::AstName;
4use crate::records::lexeme::Type;
5use crate::records::location::Location;
6use crate::records::name::Name;
7use crate::records::parser::Parser;
8use crate::records::position::Position;
9
10impl Parser {
11    pub fn parse_function_name(
12        &mut self,
13        hasself: &mut bool,
14        debugname: &mut AstName,
15    ) -> *mut AstExpr {
16        let current = self.lexer.current();
17        if current.r#type == Type::Name {
18            *debugname = AstName {
19                value: unsafe { current.data.name },
20            };
21        }
22
23        // parse funcname into a chain of indexing operators
24        let mut expr = self.parse_name_expr("function name");
25
26        let old_recursion_count = self.recursion_counter;
27
28        while self.lexer.current().r#type == Type('.' as i32) {
29            let op_position = self.lexer.current().location.begin;
30            self.next_lexeme();
31
32            let name = self.parse_name("field name");
33
34            // while we could concatenate the name chain, for now let's just write the short name
35            *debugname = name.name;
36
37            let location = unsafe { Location::new((*expr).base.location.begin, name.location.end) };
38            expr = unsafe {
39                (*self.allocator).alloc(AstExprIndexName {
40                    base: AstExpr {
41                        base: crate::records::ast_node::AstNode {
42                            class_index:
43                                <AstExprIndexName as crate::rtti::AstNodeClass>::CLASS_INDEX,
44                            location,
45                        },
46                    },
47                    expr,
48                    index: name.name,
49                    index_location: name.location,
50                    op_position,
51                    op: '.' as core::ffi::c_char,
52                }) as *mut AstExpr
53            };
54
55            // note: while the parser isn't recursive here, we're generating recursive structures of unbounded depth
56            self.increment_recursion_counter("function name");
57        }
58
59        self.recursion_counter = old_recursion_count;
60
61        // finish with :
62        if self.lexer.current().r#type == Type(':' as i32) {
63            let op_position = self.lexer.current().location.begin;
64            self.next_lexeme();
65
66            let name = self.parse_name("method name");
67
68            // while we could concatenate the name chain, for now let's just write the short name
69            *debugname = name.name;
70
71            let location = unsafe { Location::new((*expr).base.location.begin, name.location.end) };
72            expr = unsafe {
73                (*self.allocator).alloc(AstExprIndexName {
74                    base: AstExpr {
75                        base: crate::records::ast_node::AstNode {
76                            class_index:
77                                <AstExprIndexName as crate::rtti::AstNodeClass>::CLASS_INDEX,
78                            location,
79                        },
80                    },
81                    expr,
82                    index: name.name,
83                    index_location: name.location,
84                    op_position,
85                    op: ':' as core::ffi::c_char,
86                }) as *mut AstExpr
87            };
88
89            *hasself = true;
90        }
91
92        expr
93    }
94}