1use crate::parser::Parser;
2use rajac_ast::*;
3use rajac_token::TokenKind;
4use rajac_types::Ident;
5
6impl<'a> Parser<'a> {
7 pub fn parse_expression(&mut self) -> Option<ExprId> {
9 let expr = self.parse_ternary()?;
10 self.parse_assignment(expr)
11 }
12
13 fn parse_ternary(&mut self) -> Option<ExprId> {
14 let mut expr = self.parse_or()?;
15
16 if self.consume(TokenKind::Question) {
17 let then_expr = self.parse_expression()?;
18 self.expect(TokenKind::Colon);
19 let else_expr = self.parse_expression()?;
20
21 let ternary = Expr::Ternary {
22 condition: expr,
23 then_expr,
24 else_expr,
25 };
26 expr = self.arena.alloc_expr(ternary);
27 }
28
29 Some(expr)
30 }
31
32 fn parse_or(&mut self) -> Option<ExprId> {
33 let mut expr = self.parse_and()?;
34
35 while self.consume(TokenKind::Or) {
36 let rhs = self.parse_and()?;
37 let binary = Expr::Binary {
38 op: BinaryOp::Or,
39 lhs: expr,
40 rhs,
41 };
42 expr = self.arena.alloc_expr(binary);
43 }
44
45 Some(expr)
46 }
47
48 fn parse_and(&mut self) -> Option<ExprId> {
49 let mut expr = self.parse_bitwise_or()?;
50
51 while self.consume(TokenKind::And) {
52 let rhs = self.parse_bitwise_or()?;
53 let binary = Expr::Binary {
54 op: BinaryOp::And,
55 lhs: expr,
56 rhs,
57 };
58 expr = self.arena.alloc_expr(binary);
59 }
60
61 Some(expr)
62 }
63
64 fn parse_bitwise_or(&mut self) -> Option<ExprId> {
65 let mut expr = self.parse_bitwise_xor()?;
66
67 while self.is(TokenKind::Pipe) && !self.is_or() {
68 self.bump();
69 let rhs = self.parse_bitwise_xor()?;
70 let binary = Expr::Binary {
71 op: BinaryOp::BitOr,
72 lhs: expr,
73 rhs,
74 };
75 expr = self.arena.alloc_expr(binary);
76 }
77
78 Some(expr)
79 }
80
81 fn parse_bitwise_xor(&mut self) -> Option<ExprId> {
82 let mut expr = self.parse_bitwise_and()?;
83
84 while self.consume(TokenKind::Caret) {
85 let rhs = self.parse_bitwise_and()?;
86 let binary = Expr::Binary {
87 op: BinaryOp::BitXor,
88 lhs: expr,
89 rhs,
90 };
91 expr = self.arena.alloc_expr(binary);
92 }
93
94 Some(expr)
95 }
96
97 fn parse_bitwise_and(&mut self) -> Option<ExprId> {
98 let mut expr = self.parse_equality()?;
99
100 while self.is(TokenKind::Ampersand) && !self.is_and() {
101 self.bump();
102 let rhs = self.parse_equality()?;
103 let binary = Expr::Binary {
104 op: BinaryOp::BitAnd,
105 lhs: expr,
106 rhs,
107 };
108 expr = self.arena.alloc_expr(binary);
109 }
110
111 Some(expr)
112 }
113
114 fn parse_equality(&mut self) -> Option<ExprId> {
115 let mut expr = self.parse_relational()?;
116
117 loop {
118 let op = match self.peek() {
119 TokenKind::EqEq => BinaryOp::EqEq,
120 TokenKind::BangEq => BinaryOp::BangEq,
121 _ => break,
122 };
123 self.bump();
124 let rhs = self.parse_relational()?;
125 let binary = Expr::Binary { op, lhs: expr, rhs };
126 expr = self.arena.alloc_expr(binary);
127 }
128
129 Some(expr)
130 }
131
132 fn parse_relational(&mut self) -> Option<ExprId> {
133 let mut expr = self.parse_shift()?;
134
135 loop {
136 if self.consume(TokenKind::Lt) {
137 let rhs = self.parse_shift()?;
138 let binary = Expr::Binary {
139 op: BinaryOp::Lt,
140 lhs: expr,
141 rhs,
142 };
143 expr = self.arena.alloc_expr(binary);
144 } else if self.consume(TokenKind::LtEq) {
145 let rhs = self.parse_shift()?;
146 let binary = Expr::Binary {
147 op: BinaryOp::LtEq,
148 lhs: expr,
149 rhs,
150 };
151 expr = self.arena.alloc_expr(binary);
152 } else if self.consume(TokenKind::Gt) {
153 let rhs = self.parse_shift()?;
154 let binary = Expr::Binary {
155 op: BinaryOp::Gt,
156 lhs: expr,
157 rhs,
158 };
159 expr = self.arena.alloc_expr(binary);
160 } else if self.consume(TokenKind::GtEq) {
161 let rhs = self.parse_shift()?;
162 let binary = Expr::Binary {
163 op: BinaryOp::GtEq,
164 lhs: expr,
165 rhs,
166 };
167 expr = self.arena.alloc_expr(binary);
168 } else if self.consume(TokenKind::KwInstanceof) {
169 let ty = self.parse_type()?;
170 let instanceof = Expr::InstanceOf { expr, ty };
171 expr = self.arena.alloc_expr(instanceof);
172 } else {
173 break;
174 }
175 }
176
177 Some(expr)
178 }
179
180 fn parse_shift(&mut self) -> Option<ExprId> {
181 let mut expr = self.parse_additive()?;
182
183 loop {
184 let op = match self.peek() {
185 TokenKind::LtLt => BinaryOp::LShift,
186 TokenKind::GtGt => BinaryOp::RShift,
187 TokenKind::GtGtGt => BinaryOp::ARShift,
188 _ => break,
189 };
190 self.bump();
191 let rhs = self.parse_additive()?;
192 let binary = Expr::Binary { op, lhs: expr, rhs };
193 expr = self.arena.alloc_expr(binary);
194 }
195
196 Some(expr)
197 }
198
199 fn parse_additive(&mut self) -> Option<ExprId> {
200 let mut expr = self.parse_multiplicative()?;
201
202 loop {
203 let op = match self.peek() {
204 TokenKind::Plus => BinaryOp::Add,
205 TokenKind::Minus => BinaryOp::Sub,
206 _ => break,
207 };
208 self.bump();
209 let rhs = self.parse_multiplicative()?;
210 let binary = Expr::Binary { op, lhs: expr, rhs };
211 expr = self.arena.alloc_expr(binary);
212 }
213
214 Some(expr)
215 }
216
217 fn parse_multiplicative(&mut self) -> Option<ExprId> {
218 let mut expr = self.parse_unary()?;
219
220 loop {
221 let op = match self.peek() {
222 TokenKind::Star => BinaryOp::Mul,
223 TokenKind::Slash => BinaryOp::Div,
224 TokenKind::Percent => BinaryOp::Mod,
225 _ => break,
226 };
227 self.bump();
228 let rhs = self.parse_unary()?;
229 let binary = Expr::Binary { op, lhs: expr, rhs };
230 expr = self.arena.alloc_expr(binary);
231 }
232
233 Some(expr)
234 }
235
236 fn parse_unary(&mut self) -> Option<ExprId> {
237 match self.peek() {
238 TokenKind::Plus => {
239 self.bump();
240 let expr = self.parse_unary()?;
241 let unary = Expr::Unary {
242 op: UnaryOp::Plus,
243 expr,
244 };
245 Some(self.arena.alloc_expr(unary))
246 }
247 TokenKind::Minus => {
248 self.bump();
249 let expr = self.parse_unary()?;
250 let unary = Expr::Unary {
251 op: UnaryOp::Minus,
252 expr,
253 };
254 Some(self.arena.alloc_expr(unary))
255 }
256 TokenKind::Bang => {
257 self.bump();
258 let expr = self.parse_unary()?;
259 let unary = Expr::Unary {
260 op: UnaryOp::Bang,
261 expr,
262 };
263 Some(self.arena.alloc_expr(unary))
264 }
265 TokenKind::Tilde => {
266 self.bump();
267 let expr = self.parse_unary()?;
268 let unary = Expr::Unary {
269 op: UnaryOp::Tilde,
270 expr,
271 };
272 Some(self.arena.alloc_expr(unary))
273 }
274 TokenKind::PlusPlus => {
275 self.bump();
276 let expr = self.parse_unary()?;
277 let unary = Expr::Unary {
278 op: UnaryOp::Increment,
279 expr,
280 };
281 Some(self.arena.alloc_expr(unary))
282 }
283 TokenKind::MinusMinus => {
284 self.bump();
285 let expr = self.parse_unary()?;
286 let unary = Expr::Unary {
287 op: UnaryOp::Decrement,
288 expr,
289 };
290 Some(self.arena.alloc_expr(unary))
291 }
292 TokenKind::LParen => {
293 self.bump();
294 if matches!(
295 self.peek(),
296 TokenKind::KwBoolean
297 | TokenKind::KwByte
298 | TokenKind::KwChar
299 | TokenKind::KwShort
300 | TokenKind::KwInt
301 | TokenKind::KwLong
302 | TokenKind::KwFloat
303 | TokenKind::KwDouble
304 | TokenKind::KwVoid
305 | TokenKind::KwVar
306 ) {
307 let ty = self.parse_type()?;
308 self.expect(TokenKind::RParen);
309 let expr = self.parse_unary()?;
310 let cast = Expr::Cast { ty, expr };
311 return Some(self.arena.alloc_expr(cast));
312 }
313
314 let expr = self.parse_expression()?;
315 self.expect(TokenKind::RParen);
316 Some(expr)
317 }
318 _ => self.parse_postfix(),
319 }
320 }
321
322 fn parse_postfix(&mut self) -> Option<ExprId> {
323 let mut expr = self.parse_primary()?;
324
325 loop {
326 match self.peek() {
327 TokenKind::Dot => {
328 self.bump();
329 if self.peek() == TokenKind::Ident {
330 let name = Ident::new(self.ident_text());
331 self.bump();
332
333 if self.is(TokenKind::LParen) {
334 self.bump();
336 let args = self.parse_arguments();
337 self.expect(TokenKind::RParen);
338
339 let method_call = Expr::MethodCall {
340 expr: Some(expr),
341 name,
342 type_args: None,
343 args,
344 method_id: None,
345 };
346 expr = self.arena.alloc_expr(method_call);
347 } else {
348 let field_access = Expr::FieldAccess {
350 expr,
351 name,
352 field_id: None,
353 };
354 expr = self.arena.alloc_expr(field_access);
355 }
356 } else if self.peek() == TokenKind::KwClass {
357 self.bump();
359 let length = Expr::ArrayLength { array: expr };
360 expr = self.arena.alloc_expr(length);
361 }
362 }
363 TokenKind::LBracket => {
364 self.bump();
365 let index = self.parse_expression()?;
366 self.expect(TokenKind::RBracket);
367
368 let array_access = Expr::ArrayAccess { array: expr, index };
369 expr = self.arena.alloc_expr(array_access);
370 }
371 TokenKind::PlusPlus => {
372 self.bump();
373 let unary = Expr::Unary {
374 op: UnaryOp::Increment,
375 expr,
376 };
377 expr = self.arena.alloc_expr(unary);
378 }
379 TokenKind::MinusMinus => {
380 self.bump();
381 let unary = Expr::Unary {
382 op: UnaryOp::Decrement,
383 expr,
384 };
385 expr = self.arena.alloc_expr(unary);
386 }
387 _ => break,
388 }
389 }
390
391 Some(expr)
392 }
393
394 fn parse_primary(&mut self) -> Option<ExprId> {
395 match self.peek() {
396 TokenKind::IntLiteral | TokenKind::LongLiteral => {
397 let value = rajac_base::shared_string::SharedString::new(
398 &self.source[self.current.span.clone()],
399 );
400 let kind = if matches!(self.peek(), TokenKind::LongLiteral) {
401 LiteralKind::Long
402 } else {
403 LiteralKind::Int
404 };
405 self.bump();
406 let lit = Literal { kind, value };
407 Some(self.arena.alloc_expr(Expr::Literal(lit)))
408 }
409 TokenKind::FloatLiteral => {
410 let value = rajac_base::shared_string::SharedString::new(
411 &self.source[self.current.span.clone()],
412 );
413 self.bump();
414 let lit = Literal {
415 kind: LiteralKind::Float,
416 value,
417 };
418 Some(self.arena.alloc_expr(Expr::Literal(lit)))
419 }
420 TokenKind::DoubleLiteral => {
421 let value = rajac_base::shared_string::SharedString::new(
422 &self.source[self.current.span.clone()],
423 );
424 self.bump();
425 let lit = Literal {
426 kind: LiteralKind::Double,
427 value,
428 };
429 Some(self.arena.alloc_expr(Expr::Literal(lit)))
430 }
431 TokenKind::StringLiteral => {
432 let raw_value = &self.source[self.current.span.clone()];
433 let value = if raw_value.len() >= 2
435 && raw_value.starts_with('"')
436 && raw_value.ends_with('"')
437 {
438 &raw_value[1..raw_value.len() - 1]
439 } else {
440 raw_value
441 };
442 let value = rajac_base::shared_string::SharedString::new(value);
443 self.bump();
444 let lit = Literal {
445 kind: LiteralKind::String,
446 value,
447 };
448 Some(self.arena.alloc_expr(Expr::Literal(lit)))
449 }
450 TokenKind::CharLiteral => {
451 let value = rajac_base::shared_string::SharedString::new(
452 &self.source[self.current.span.clone()],
453 );
454 self.bump();
455 let lit = Literal {
456 kind: LiteralKind::Char,
457 value,
458 };
459 Some(self.arena.alloc_expr(Expr::Literal(lit)))
460 }
461 TokenKind::KwTrue | TokenKind::KwFalse => {
462 let value = rajac_base::shared_string::SharedString::new(
463 &self.source[self.current.span.clone()],
464 );
465 self.bump();
466 let lit = Literal {
467 kind: LiteralKind::Bool,
468 value,
469 };
470 Some(self.arena.alloc_expr(Expr::Literal(lit)))
471 }
472 TokenKind::NullLiteral => {
473 let value = rajac_base::shared_string::SharedString::new("null");
474 self.bump();
475 let lit = Literal {
476 kind: LiteralKind::Null,
477 value,
478 };
479 Some(self.arena.alloc_expr(Expr::Literal(lit)))
480 }
481 TokenKind::Ident => {
482 let name = Ident::new(self.ident_text());
483 self.bump();
484
485 if self.is(TokenKind::LParen) {
486 self.bump();
488 let args = self.parse_arguments();
489 self.expect(TokenKind::RParen);
490
491 let method_call = Expr::MethodCall {
492 expr: None,
493 name,
494 type_args: None,
495 args,
496 method_id: None,
497 };
498 Some(self.arena.alloc_expr(method_call))
499 } else {
500 Some(self.arena.alloc_expr(Expr::Ident(name)))
502 }
503 }
504 TokenKind::KwThis => {
505 self.bump();
506 let expr = if self.is(TokenKind::LParen) {
507 self.bump();
508 Some(self.arena.alloc_expr(Expr::Ident(Ident::new(
509 rajac_base::shared_string::SharedString::new("this"),
510 ))))
511 } else {
512 None
513 };
514 Some(self.arena.alloc_expr(Expr::This(expr)))
515 }
516 TokenKind::KwSuper => {
517 self.bump();
518 if self.is(TokenKind::LParen) {
519 self.bump();
520 let args = self.parse_arguments();
521 self.expect(TokenKind::RParen);
522 let super_call = Expr::SuperCall {
523 name: Ident::new(rajac_base::shared_string::SharedString::new("super")),
524 type_args: None,
525 args,
526 method_id: None,
527 };
528 Some(self.arena.alloc_expr(super_call))
529 } else {
530 Some(self.arena.alloc_expr(Expr::Super))
531 }
532 }
533 TokenKind::KwNew => {
534 self.bump();
535 if let Some(ty) = self.parse_type_without_array_suffix() {
536 if self.is(TokenKind::LBracket) {
537 let mut dimensions = Vec::new();
538 let mut empty_brackets = 0;
539 while self.consume(TokenKind::LBracket) {
540 if let Some(dim) = self.parse_expression() {
541 dimensions.push(dim);
542 } else {
543 empty_brackets += 1;
544 }
545 self.expect(TokenKind::RBracket);
546 }
547 let ty = if empty_brackets > 0 {
548 self.arena.alloc_type(AstType::array(ty, empty_brackets))
549 } else {
550 ty
551 };
552 let initializer = if self.is(TokenKind::LBrace) {
553 self.parse_array_initializer_expr()
554 } else {
555 None
556 };
557 let new_array = Expr::NewArray {
558 ty,
559 dimensions,
560 initializer,
561 };
562 Some(self.arena.alloc_expr(new_array))
563 } else if self.is(TokenKind::LParen) {
564 self.bump();
566 let args = self.parse_arguments();
567 self.expect(TokenKind::RParen);
568 let new_expr = Expr::New { ty, args };
569 Some(self.arena.alloc_expr(new_expr))
570 } else {
571 None
572 }
573 } else {
574 None
575 }
576 }
577 TokenKind::LParen => {
578 self.bump();
579 let expr = self.parse_expression()?;
580 self.expect(TokenKind::RParen);
581 Some(expr)
582 }
583 _ => None,
584 }
585 }
586
587 fn parse_array_initializer_expr(&mut self) -> Option<ExprId> {
588 if !self.consume(TokenKind::LBrace) {
589 return None;
590 }
591
592 let mut elements = Vec::new();
593 while !self.is(TokenKind::RBrace) && !self.is(TokenKind::Eof) {
594 let element = if self.is(TokenKind::LBrace) {
595 self.parse_array_initializer_expr()
596 } else {
597 self.parse_expression()
598 }?;
599 elements.push(element);
600
601 if !self.consume(TokenKind::Comma) {
602 break;
603 }
604 if self.is(TokenKind::RBrace) {
605 break;
606 }
607 }
608
609 self.expect(TokenKind::RBrace);
610 Some(self.arena.alloc_expr(Expr::ArrayInitializer { elements }))
611 }
612
613 fn parse_arguments(&mut self) -> Vec<ExprId> {
614 let mut args = Vec::new();
615
616 if self.is(TokenKind::RParen) {
617 return args;
618 }
619
620 loop {
621 if let Some(arg) = self.parse_expression() {
622 args.push(arg);
623 }
624 if !self.consume(TokenKind::Comma) {
625 break;
626 }
627 }
628
629 args
630 }
631
632 pub fn parse_assignment(&mut self, expr: ExprId) -> Option<ExprId> {
634 let op = match self.peek() {
635 TokenKind::Eq => AssignOp::Eq,
636 TokenKind::PlusEq => AssignOp::AddEq,
637 TokenKind::MinusEq => AssignOp::SubEq,
638 TokenKind::StarEq => AssignOp::MulEq,
639 TokenKind::SlashEq => AssignOp::DivEq,
640 TokenKind::PercentEq => AssignOp::ModEq,
641 TokenKind::AmpersandEq => AssignOp::AndEq,
642 TokenKind::PipeEq => AssignOp::OrEq,
643 TokenKind::CaretEq => AssignOp::XorEq,
644 TokenKind::LtLtEq => AssignOp::LShiftEq,
645 TokenKind::GtGtEq => AssignOp::RShiftEq,
646 TokenKind::GtGtGtEq => AssignOp::ARShiftEq,
647 _ => return Some(expr),
648 };
649 self.bump();
650 let rhs = self.parse_ternary()?;
651 let assign = Expr::Assign { op, lhs: expr, rhs };
652 Some(self.arena.alloc_expr(assign))
653 }
654
655 fn is_or(&self) -> bool {
657 self.peek() == TokenKind::Or
658 }
659
660 fn is_and(&self) -> bool {
662 self.peek() == TokenKind::And
663 }
664}