Skip to main content

luaur_ast/methods/
parser_parse_while.rs

1//! Node: `cxx:Method:Luau.Ast:Ast/src/Parser.cpp:620:parseWhile`
2//!
3//! Faithful port of `Parser::parseWhile` — `while exp do block end`. Tracks
4//! loop depth on the current function frame around the body parse and records
5//! the `do` keyword location for CST-free reconstruction.
6
7use crate::records::allocator::Allocator;
8use crate::records::ast_stat::AstStat;
9use crate::records::ast_stat_while::AstStatWhile;
10use crate::records::lexeme::Type;
11use crate::records::location::Location;
12use crate::records::match_lexeme::MatchLexeme;
13use crate::records::parser::Parser;
14
15impl Parser {
16    pub fn parse_while(&mut self) -> *mut AstStat {
17        let start = self.lexer.current().location;
18
19        self.next_lexeme(); // while
20
21        let cond = self.parse_expr_i32(0);
22
23        let match_do = *self.lexer.current();
24        let has_do = self.expect_and_consume_type(Type::ReservedDo, "while loop");
25
26        unsafe {
27            (*self.function_stack.last_mut().unwrap()).loop_depth += 1;
28        }
29
30        let body = self.parse_block();
31
32        unsafe {
33            (*self.function_stack.last_mut().unwrap()).loop_depth -= 1;
34        }
35
36        let end = self.lexer.current().location;
37
38        let has_end =
39            self.expect_match_end_and_consume(Type::ReservedEnd, &MatchLexeme::new(&match_do));
40        unsafe {
41            (*body).has_end = has_end;
42        }
43
44        unsafe {
45            (*self.allocator).alloc(AstStatWhile::new(
46                Location::new(start.begin, end.end),
47                cond,
48                body,
49                has_do,
50                match_do.location,
51            )) as *mut AstStat
52        }
53    }
54}