Skip to main content

luaur_ast/methods/
parser_parse_repeat.rs

1use crate::records::allocator::Allocator;
2use crate::records::ast_expr::AstExpr;
3use crate::records::ast_stat::AstStat;
4use crate::records::ast_stat_block::AstStatBlock;
5use crate::records::ast_stat_repeat::AstStatRepeat;
6use crate::records::cst_stat_repeat::CstStatRepeat;
7use crate::records::lexeme::Type;
8use crate::records::location::Location;
9use crate::records::match_lexeme::MatchLexeme;
10use crate::records::parser::Parser;
11use crate::records::position::Position;
12
13impl Parser {
14    pub fn parse_repeat(&mut self) -> *mut AstStat {
15        let start = self.lexer.current().location;
16
17        let match_repeat = *self.lexer.current();
18        self.next_lexeme(); // repeat
19
20        let locals_begin = self.save_locals();
21
22        unsafe {
23            (*self.function_stack.last_mut().unwrap()).loop_depth += 1;
24        }
25
26        let body = self.parse_block_no_scope();
27
28        unsafe {
29            (*self.function_stack.last_mut().unwrap()).loop_depth -= 1;
30        }
31
32        let has_until = self
33            .expect_match_end_and_consume(Type::ReservedUntil, &MatchLexeme::new(&match_repeat));
34        unsafe {
35            (*body).has_end = has_until;
36        }
37        let until_position = if has_until {
38            self.lexer.previous_location().begin
39        } else {
40            Position::missing()
41        };
42
43        let cond = self.parse_expr_i32(0);
44
45        self.restore_locals(locals_begin);
46
47        let node = unsafe {
48            (*self.allocator).alloc(AstStatRepeat::new(
49                Location::new(start.begin, unsafe { (*cond).base.location }.end),
50                cond,
51                body,
52                has_until,
53            ))
54        };
55
56        if self.options.store_cst_data {
57            let cst_node = unsafe { (*self.allocator).alloc(CstStatRepeat::new(until_position)) };
58            self.cst_node_map.try_insert(
59                node as *mut crate::records::ast_node::AstNode,
60                cst_node as *mut crate::records::cst_node::CstNode,
61            );
62        }
63
64        node as *mut AstStat
65    }
66}