Skip to main content

luaur_ast/methods/
parser_parse_name_expr.rs

1use crate::records::allocator::Allocator;
2use crate::records::ast_array::AstArray;
3use crate::records::ast_expr::AstExpr;
4use crate::records::ast_expr_error::AstExprError;
5use crate::records::ast_expr_global::AstExprGlobal;
6use crate::records::ast_expr_local::AstExprLocal;
7use crate::records::ast_local::AstLocal;
8use crate::records::ast_node::AstNode;
9use crate::records::name::Name;
10use crate::records::parser::Parser;
11use crate::rtti::AstNodeClass;
12
13impl Parser {
14    pub fn parse_name_expr(&mut self, context: &str) -> *mut AstExpr {
15        let name: Option<Name> = self.parse_name_opt(context);
16
17        if name.is_none() {
18            let location = self.lexer.current().location;
19            let expressions = self.copy_initializer_list_t::<*mut AstExpr>(&[]);
20            let message_index = (self.parse_errors.len() as u32).saturating_sub(1);
21
22            return unsafe {
23                Allocator::alloc(
24                    &mut *self.allocator,
25                    AstExprError {
26                        base: AstExpr {
27                            base: AstNode {
28                                class_index: <AstExprError as AstNodeClass>::CLASS_INDEX,
29                                location,
30                            },
31                        },
32                        expressions,
33                        message_index,
34                    },
35                ) as *mut AstExpr
36            };
37        }
38
39        let name = name.unwrap();
40        let value = self.local_map.find(&name.name);
41
42        if let Some(local) = value.copied().filter(|p| !p.is_null()) {
43            if unsafe { (*local).function_depth < self.type_function_depth } {
44                return self.report_expr_error(
45                    self.lexer.current().location,
46                    AstArray::default(),
47                    format_args!("Type function cannot reference outer local '{}'", unsafe {
48                        core::ffi::CStr::from_ptr((*local).name.value).to_string_lossy()
49                    }),
50                ) as *mut AstExpr;
51            }
52
53            let upvalue =
54                unsafe { (*local).function_depth != self.function_stack.len().saturating_sub(1) };
55
56            return unsafe {
57                Allocator::alloc(
58                    &mut *self.allocator,
59                    AstExprLocal {
60                        base: AstExpr {
61                            base: AstNode {
62                                class_index: <AstExprLocal as AstNodeClass>::CLASS_INDEX,
63                                location: name.location,
64                            },
65                        },
66                        local,
67                        upvalue,
68                    },
69                ) as *mut AstExpr
70            };
71        }
72
73        unsafe {
74            Allocator::alloc(
75                &mut *self.allocator,
76                AstExprGlobal {
77                    base: AstExpr {
78                        base: AstNode {
79                            class_index: <AstExprGlobal as AstNodeClass>::CLASS_INDEX,
80                            location: name.location,
81                        },
82                    },
83                    name: name.name,
84                },
85            ) as *mut AstExpr
86        }
87    }
88}