1use crate::parser::Parser;
2use rajac_ast::*;
3use rajac_token::TokenKind;
4use rajac_types::Ident;
5
6impl<'a> Parser<'a> {
7 pub fn parse_block(&mut self) -> Option<StmtId> {
9 if !self.consume(TokenKind::LBrace) {
10 return None;
11 }
12
13 let mut stmts = Vec::new();
14 while !self.is(TokenKind::RBrace) && !self.is(TokenKind::Eof) {
15 if let Some(stmt) = self.parse_statement() {
16 stmts.push(stmt);
17 } else {
18 break;
19 }
20 }
21
22 self.expect(TokenKind::RBrace);
23 let block = Stmt::Block(stmts);
24 Some(self.arena.alloc_stmt(block))
25 }
26
27 pub fn parse_statement(&mut self) -> Option<StmtId> {
29 match self.peek() {
30 TokenKind::LBrace => self.parse_block(),
31 TokenKind::Semi => {
32 self.bump();
33 Some(self.arena.alloc_stmt(Stmt::Empty))
34 }
35 TokenKind::KwIf => self.parse_if_stmt(),
36 TokenKind::KwWhile => self.parse_while_stmt(),
37 TokenKind::KwDo => self.parse_do_while_stmt(),
38 TokenKind::KwFor => self.parse_for_stmt(),
39 TokenKind::KwSwitch => self.parse_switch_stmt(),
40 TokenKind::KwReturn => self.parse_return_stmt(),
41 TokenKind::KwBreak => self.parse_break_stmt(),
42 TokenKind::KwContinue => self.parse_continue_stmt(),
43 TokenKind::KwThrow => self.parse_throw_stmt(),
44 TokenKind::KwTry => self.parse_try_stmt(),
45 TokenKind::KwSynchronized => self.parse_synchronized_stmt(),
46 TokenKind::KwBoolean
48 | TokenKind::KwByte
49 | TokenKind::KwChar
50 | TokenKind::KwShort
51 | TokenKind::KwInt
52 | TokenKind::KwLong
53 | TokenKind::KwFloat
54 | TokenKind::KwDouble
55 | TokenKind::KwVoid
56 | TokenKind::Ident => {
57 if self.peek() == TokenKind::Ident && self.peek_n(1) == TokenKind::Colon {
58 return self.parse_label_stmt();
59 }
60
61 if self.is_local_var_decl() {
63 self.parse_local_var_decl()
64 } else {
65 self.parse_expr_stmt()
66 }
67 }
68 _ => {
69 if let Some(expr) = self.parse_expression() {
71 self.expect(TokenKind::Semi);
72 Some(self.arena.alloc_stmt(Stmt::Expr(expr)))
73 } else {
74 None
75 }
76 }
77 }
78 }
79
80 fn is_local_var_decl(&self) -> bool {
81 matches!(
82 self.peek(),
83 TokenKind::KwBoolean
84 | TokenKind::KwByte
85 | TokenKind::KwChar
86 | TokenKind::KwShort
87 | TokenKind::KwInt
88 | TokenKind::KwLong
89 | TokenKind::KwFloat
90 | TokenKind::KwDouble
91 | TokenKind::KwVoid
92 | TokenKind::KwVar
93 )
94 }
95
96 fn parse_local_var_decl(&mut self) -> Option<StmtId> {
97 if let Some(ty) = self.parse_type()
98 && self.peek() == TokenKind::Ident
99 {
100 let name = Ident::new(self.ident_text());
101 self.bump();
102
103 let initializer = if self.consume(TokenKind::Eq) {
104 self.parse_expression()
105 } else {
106 None
107 };
108
109 self.expect(TokenKind::Semi);
110
111 let stmt = Stmt::LocalVar {
112 ty,
113 name,
114 initializer,
115 };
116 return Some(self.arena.alloc_stmt(stmt));
117 }
118 None
119 }
120
121 fn parse_expr_stmt(&mut self) -> Option<StmtId> {
122 if let Some(expr) = self.parse_expression() {
123 self.expect(TokenKind::Semi);
124 Some(self.arena.alloc_stmt(Stmt::Expr(expr)))
125 } else {
126 None
127 }
128 }
129
130 fn parse_if_stmt(&mut self) -> Option<StmtId> {
131 self.expect(TokenKind::KwIf);
132 self.expect(TokenKind::LParen);
133 let condition = self.parse_expression()?;
134 self.expect(TokenKind::RParen);
135
136 let then_branch = self.parse_statement()?;
137
138 let else_branch = if self.consume(TokenKind::KwElse) {
139 self.parse_statement()
140 } else {
141 None
142 };
143
144 let stmt = Stmt::If {
145 condition,
146 then_branch,
147 else_branch,
148 };
149 Some(self.arena.alloc_stmt(stmt))
150 }
151
152 fn parse_while_stmt(&mut self) -> Option<StmtId> {
153 self.expect(TokenKind::KwWhile);
154 self.expect(TokenKind::LParen);
155 let condition = self.parse_expression()?;
156 self.expect(TokenKind::RParen);
157
158 let body = self.parse_statement()?;
159
160 let stmt = Stmt::While { condition, body };
161 Some(self.arena.alloc_stmt(stmt))
162 }
163
164 fn parse_do_while_stmt(&mut self) -> Option<StmtId> {
165 self.expect(TokenKind::KwDo);
166 let body = self.parse_statement()?;
167 self.expect(TokenKind::KwWhile);
168 self.expect(TokenKind::LParen);
169 let condition = self.parse_expression()?;
170 self.expect(TokenKind::RParen);
171 self.expect(TokenKind::Semi);
172
173 let stmt = Stmt::DoWhile { body, condition };
174 Some(self.arena.alloc_stmt(stmt))
175 }
176
177 fn parse_for_stmt(&mut self) -> Option<StmtId> {
178 self.expect(TokenKind::KwFor);
179 self.expect(TokenKind::LParen);
180
181 let init = if self.is(TokenKind::Semi) {
182 None
183 } else if self.is_local_var_decl() {
184 let ty = self.parse_type()?;
185 let name = if self.peek() == TokenKind::Ident {
186 Ident::new(self.ident_text())
187 } else {
188 return None;
189 };
190 self.bump();
191
192 let initializer = if self.consume(TokenKind::Eq) {
193 self.parse_expression()
194 } else {
195 None
196 };
197
198 Some(ForInit::LocalVar {
199 ty,
200 name,
201 initializer,
202 })
203 } else {
204 self.parse_expression().map(ForInit::Expr)
205 };
206
207 self.expect(TokenKind::Semi);
208
209 let condition = if self.is(TokenKind::Semi) {
210 None
211 } else {
212 self.parse_expression()
213 };
214
215 self.expect(TokenKind::Semi);
216
217 let update = if self.is(TokenKind::RParen) {
218 None
219 } else {
220 self.parse_expression()
221 };
222
223 self.expect(TokenKind::RParen);
224
225 let body = self.parse_statement()?;
226
227 let stmt = Stmt::For {
228 init,
229 condition,
230 update,
231 body,
232 };
233 Some(self.arena.alloc_stmt(stmt))
234 }
235
236 fn parse_switch_stmt(&mut self) -> Option<StmtId> {
237 self.expect(TokenKind::KwSwitch);
238 self.expect(TokenKind::LParen);
239 let expr = self.parse_expression()?;
240 self.expect(TokenKind::RParen);
241
242 self.expect(TokenKind::LBrace);
243
244 let mut cases = Vec::new();
245 while !self.is(TokenKind::RBrace) && !self.is(TokenKind::Eof) {
246 match self.peek() {
247 TokenKind::KwCase => {
248 self.bump();
249 if let Some(case_expr) = self.parse_expression() {
250 self.expect(TokenKind::Colon);
251 let label = SwitchLabel::Case(case_expr);
252
253 let mut body = Vec::new();
254 while !self.is(TokenKind::KwCase)
255 && !self.is(TokenKind::KwDefault)
256 && !self.is(TokenKind::RBrace)
257 {
258 if let Some(stmt) = self.parse_statement() {
259 body.push(stmt);
260 } else {
261 break;
262 }
263 }
264
265 cases.push(SwitchCase {
266 labels: vec![label],
267 body,
268 });
269 }
270 }
271 TokenKind::KwDefault => {
272 self.bump();
273 self.expect(TokenKind::Colon);
274
275 let mut body = Vec::new();
276 while !self.is(TokenKind::KwCase)
277 && !self.is(TokenKind::KwDefault)
278 && !self.is(TokenKind::RBrace)
279 {
280 if let Some(stmt) = self.parse_statement() {
281 body.push(stmt);
282 } else {
283 break;
284 }
285 }
286
287 cases.push(SwitchCase {
288 labels: vec![SwitchLabel::Default],
289 body,
290 });
291 }
292 _ => break,
293 }
294 }
295
296 self.expect(TokenKind::RBrace);
297
298 let stmt = Stmt::Switch { expr, cases };
299 Some(self.arena.alloc_stmt(stmt))
300 }
301
302 fn parse_label_stmt(&mut self) -> Option<StmtId> {
303 let name = if self.peek() == TokenKind::Ident {
304 Ident::new(self.ident_text())
305 } else {
306 return None;
307 };
308 self.bump();
309 self.expect(TokenKind::Colon);
310 let body = self.parse_statement()?;
311
312 Some(self.arena.alloc_stmt(Stmt::Label(name, body)))
313 }
314
315 fn parse_return_stmt(&mut self) -> Option<StmtId> {
316 self.expect(TokenKind::KwReturn);
317 let expr = if self.is(TokenKind::Semi) {
318 None
319 } else {
320 self.parse_expression()
321 };
322 self.expect(TokenKind::Semi);
323
324 let stmt = Stmt::Return(expr);
325 Some(self.arena.alloc_stmt(stmt))
326 }
327
328 fn parse_break_stmt(&mut self) -> Option<StmtId> {
329 self.expect(TokenKind::KwBreak);
330 let label = if self.peek() == TokenKind::Ident && !self.is(TokenKind::Semi) {
331 Some(Ident::new(self.ident_text()))
332 } else {
333 None
334 };
335 if label.is_some() {
336 self.bump();
337 }
338 self.expect(TokenKind::Semi);
339
340 let stmt = Stmt::Break(label);
341 Some(self.arena.alloc_stmt(stmt))
342 }
343
344 fn parse_continue_stmt(&mut self) -> Option<StmtId> {
345 self.expect(TokenKind::KwContinue);
346 let label = if self.peek() == TokenKind::Ident && !self.is(TokenKind::Semi) {
347 Some(Ident::new(self.ident_text()))
348 } else {
349 None
350 };
351 if label.is_some() {
352 self.bump();
353 }
354 self.expect(TokenKind::Semi);
355
356 let stmt = Stmt::Continue(label);
357 Some(self.arena.alloc_stmt(stmt))
358 }
359
360 fn parse_throw_stmt(&mut self) -> Option<StmtId> {
361 self.expect(TokenKind::KwThrow);
362 let expr = self.parse_expression()?;
363 self.expect(TokenKind::Semi);
364
365 let stmt = Stmt::Throw(expr);
366 Some(self.arena.alloc_stmt(stmt))
367 }
368
369 fn parse_try_stmt(&mut self) -> Option<StmtId> {
370 self.expect(TokenKind::KwTry);
371
372 let try_block = self.parse_block()?;
373
374 let mut catches = Vec::new();
375 while self.is(TokenKind::KwCatch) {
376 self.bump();
377 self.expect(TokenKind::LParen);
378
379 let ty = self.parse_type()?;
380 let name = if self.peek() == TokenKind::Ident {
381 Ident::new(self.ident_text())
382 } else {
383 Ident::new(rajac_base::shared_string::SharedString::new("e"))
384 };
385 self.bump();
386
387 self.expect(TokenKind::RParen);
388
389 let body = self.parse_block()?;
390
391 catches.push(CatchClause {
392 param: self.arena.alloc_param(Param {
393 ty,
394 name,
395 varargs: false,
396 }),
397 body,
398 });
399 }
400
401 let finally_block = if self.consume(TokenKind::KwFinally) {
402 self.parse_block()
403 } else {
404 None
405 };
406
407 let stmt = Stmt::Try {
408 try_block,
409 catches,
410 finally_block,
411 };
412 Some(self.arena.alloc_stmt(stmt))
413 }
414
415 fn parse_synchronized_stmt(&mut self) -> Option<StmtId> {
416 self.expect(TokenKind::KwSynchronized);
417
418 let expr = if self.consume(TokenKind::LParen) {
419 let e = self.parse_expression();
420 self.expect(TokenKind::RParen);
421 e
422 } else {
423 None
424 };
425
426 let block = self.parse_block()?;
427
428 let stmt = Stmt::Synchronized { expr, block };
429 Some(self.arena.alloc_stmt(stmt))
430 }
431}