we (web engine): Experimental web browser project to understand the limits of Claude
at main 3619 lines 126 kB view raw
1//! Recursive-descent JavaScript parser with Pratt expression parsing. 2//! 3//! Transforms a token stream from the [`crate::lexer::Lexer`] into an 4//! [`crate::ast::Program`] AST. 5 6use crate::ast::*; 7use crate::lexer::{LexError, Lexer, SourcePos, Span, Token, TokenKind}; 8use std::fmt; 9 10// ── Error ─────────────────────────────────────────────────── 11 12/// An error produced during parsing. 13#[derive(Debug, Clone, PartialEq)] 14pub struct ParseError { 15 pub message: String, 16 pub pos: SourcePos, 17} 18 19impl fmt::Display for ParseError { 20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 21 write!( 22 f, 23 "ParseError at {}:{}: {}", 24 self.pos.line, self.pos.col, self.message 25 ) 26 } 27} 28 29impl From<LexError> for ParseError { 30 fn from(e: LexError) -> Self { 31 ParseError { 32 message: e.message, 33 pos: e.pos, 34 } 35 } 36} 37 38// ── Parser ────────────────────────────────────────────────── 39 40pub struct Parser { 41 tokens: Vec<Token>, 42 pos: usize, 43 /// When false, `in` is not treated as a binary operator (for-init disambiguation). 44 allow_in: bool, 45} 46 47impl Parser { 48 /// Parse source as a script. 49 pub fn parse(source: &str) -> Result<Program, ParseError> { 50 let tokens = Lexer::tokenize(source)?; 51 let mut parser = Parser { 52 tokens, 53 pos: 0, 54 allow_in: true, 55 }; 56 parser.parse_program(SourceType::Script) 57 } 58 59 /// Parse source as a module. 60 pub fn parse_module(source: &str) -> Result<Program, ParseError> { 61 let tokens = Lexer::tokenize(source)?; 62 let mut parser = Parser { 63 tokens, 64 pos: 0, 65 allow_in: true, 66 }; 67 parser.parse_program(SourceType::Module) 68 } 69 70 // ── Token navigation ──────────────────────────────────── 71 72 fn peek(&self) -> &Token { 73 &self.tokens[self.pos.min(self.tokens.len() - 1)] 74 } 75 76 fn peek_kind(&self) -> &TokenKind { 77 &self.peek().kind 78 } 79 80 fn peek_ahead(&self, offset: usize) -> &TokenKind { 81 let idx = (self.pos + offset).min(self.tokens.len() - 1); 82 &self.tokens[idx].kind 83 } 84 85 fn at(&self, kind: &TokenKind) -> bool { 86 std::mem::discriminant(self.peek_kind()) == std::mem::discriminant(kind) 87 } 88 89 fn at_eof(&self) -> bool { 90 matches!(self.peek_kind(), TokenKind::Eof) 91 } 92 93 fn advance(&mut self) -> Token { 94 let tok = self.tokens[self.pos.min(self.tokens.len() - 1)].clone(); 95 if self.pos < self.tokens.len() - 1 { 96 self.pos += 1; 97 } 98 tok 99 } 100 101 fn eat(&mut self, kind: &TokenKind) -> bool { 102 if self.at(kind) { 103 self.advance(); 104 true 105 } else { 106 false 107 } 108 } 109 110 fn expect(&mut self, kind: &TokenKind) -> Result<Token, ParseError> { 111 if self.at(kind) { 112 Ok(self.advance()) 113 } else { 114 Err(self.error(format!("expected {:?}, found {:?}", kind, self.peek_kind()))) 115 } 116 } 117 118 fn expect_semicolon(&mut self) -> Result<(), ParseError> { 119 if self.eat(&TokenKind::Semicolon) { 120 return Ok(()); 121 } 122 // ASI: insert semicolon before `}`, at EOF, or after newline 123 if matches!(self.peek_kind(), TokenKind::RBrace | TokenKind::Eof) 124 || self.peek().preceded_by_newline 125 { 126 return Ok(()); 127 } 128 Err(self.error(format!("expected `;`, found {:?}", self.peek_kind()))) 129 } 130 131 fn expect_identifier(&mut self) -> Result<String, ParseError> { 132 match self.peek_kind().clone() { 133 TokenKind::Identifier(name) => { 134 self.advance(); 135 Ok(name) 136 } 137 _ => Err(self.error(format!("expected identifier, found {:?}", self.peek_kind()))), 138 } 139 } 140 141 fn start_span(&self) -> SourcePos { 142 self.peek().span.start 143 } 144 145 fn end_span(&self) -> SourcePos { 146 if self.pos > 0 { 147 self.tokens[self.pos - 1].span.end 148 } else { 149 self.peek().span.start 150 } 151 } 152 153 fn span_from(&self, start: SourcePos) -> Span { 154 Span { 155 start, 156 end: self.end_span(), 157 } 158 } 159 160 fn error(&self, message: String) -> ParseError { 161 ParseError { 162 message, 163 pos: self.peek().span.start, 164 } 165 } 166 167 // ── Program ───────────────────────────────────────────── 168 169 fn parse_program(&mut self, source_type: SourceType) -> Result<Program, ParseError> { 170 let start = self.start_span(); 171 let mut body = Vec::new(); 172 while !self.at_eof() { 173 body.push(self.parse_statement_list_item()?); 174 } 175 Ok(Program { 176 body, 177 source_type, 178 span: self.span_from(start), 179 }) 180 } 181 182 fn parse_statement_list_item(&mut self) -> Result<Stmt, ParseError> { 183 match self.peek_kind() { 184 TokenKind::Function => self.parse_function_declaration(), 185 TokenKind::Class => self.parse_class_declaration(), 186 TokenKind::Var | TokenKind::Let | TokenKind::Const => { 187 self.parse_variable_declaration_stmt() 188 } 189 TokenKind::Async 190 if matches!(self.peek_ahead(1), TokenKind::Function) 191 && !self.tokens[self.pos + 1].preceded_by_newline => 192 { 193 self.parse_async_function_declaration() 194 } 195 TokenKind::Import 196 if !matches!(self.peek_ahead(1), TokenKind::LParen | TokenKind::Dot) => 197 { 198 self.parse_import_declaration() 199 } 200 TokenKind::Export => self.parse_export_declaration(), 201 _ => self.parse_statement(), 202 } 203 } 204 205 // ── Statements ────────────────────────────────────────── 206 207 fn parse_statement(&mut self) -> Result<Stmt, ParseError> { 208 match self.peek_kind() { 209 TokenKind::LBrace => self.parse_block_stmt(), 210 TokenKind::Semicolon => { 211 let start = self.start_span(); 212 self.advance(); 213 Ok(Stmt { 214 kind: StmtKind::Empty, 215 span: self.span_from(start), 216 }) 217 } 218 TokenKind::If => self.parse_if(), 219 TokenKind::For => self.parse_for(), 220 TokenKind::While => self.parse_while(), 221 TokenKind::Do => self.parse_do_while(), 222 TokenKind::Switch => self.parse_switch(), 223 TokenKind::Try => self.parse_try(), 224 TokenKind::Return => self.parse_return(), 225 TokenKind::Throw => self.parse_throw(), 226 TokenKind::Break => self.parse_break(), 227 TokenKind::Continue => self.parse_continue(), 228 TokenKind::With => self.parse_with(), 229 TokenKind::Debugger => { 230 let start = self.start_span(); 231 self.advance(); 232 self.expect_semicolon()?; 233 Ok(Stmt { 234 kind: StmtKind::Debugger, 235 span: self.span_from(start), 236 }) 237 } 238 // Labeled statement: `ident: stmt` 239 TokenKind::Identifier(_) if matches!(self.peek_ahead(1), TokenKind::Colon) => { 240 self.parse_labeled() 241 } 242 // Variable declarations can also appear as statements 243 TokenKind::Var | TokenKind::Let | TokenKind::Const => { 244 self.parse_variable_declaration_stmt() 245 } 246 // Function/class declarations in statement position 247 TokenKind::Function => self.parse_function_declaration(), 248 TokenKind::Class => self.parse_class_declaration(), 249 TokenKind::Async 250 if matches!(self.peek_ahead(1), TokenKind::Function) 251 && !self.tokens[self.pos + 1].preceded_by_newline => 252 { 253 self.parse_async_function_declaration() 254 } 255 _ => self.parse_expression_statement(), 256 } 257 } 258 259 fn parse_block_stmt(&mut self) -> Result<Stmt, ParseError> { 260 let start = self.start_span(); 261 let body = self.parse_block_body()?; 262 Ok(Stmt { 263 kind: StmtKind::Block(body), 264 span: self.span_from(start), 265 }) 266 } 267 268 fn parse_block_body(&mut self) -> Result<Vec<Stmt>, ParseError> { 269 self.expect(&TokenKind::LBrace)?; 270 let mut body = Vec::new(); 271 while !self.at(&TokenKind::RBrace) && !self.at_eof() { 272 body.push(self.parse_statement_list_item()?); 273 } 274 self.expect(&TokenKind::RBrace)?; 275 Ok(body) 276 } 277 278 fn parse_expression_statement(&mut self) -> Result<Stmt, ParseError> { 279 let start = self.start_span(); 280 let expr = self.parse_expression()?; 281 self.expect_semicolon()?; 282 Ok(Stmt { 283 kind: StmtKind::Expr(expr), 284 span: self.span_from(start), 285 }) 286 } 287 288 fn parse_if(&mut self) -> Result<Stmt, ParseError> { 289 let start = self.start_span(); 290 self.expect(&TokenKind::If)?; 291 self.expect(&TokenKind::LParen)?; 292 let test = self.parse_expression()?; 293 self.expect(&TokenKind::RParen)?; 294 let consequent = Box::new(self.parse_statement()?); 295 let alternate = if self.eat(&TokenKind::Else) { 296 Some(Box::new(self.parse_statement()?)) 297 } else { 298 None 299 }; 300 Ok(Stmt { 301 kind: StmtKind::If { 302 test, 303 consequent, 304 alternate, 305 }, 306 span: self.span_from(start), 307 }) 308 } 309 310 fn parse_while(&mut self) -> Result<Stmt, ParseError> { 311 let start = self.start_span(); 312 self.expect(&TokenKind::While)?; 313 self.expect(&TokenKind::LParen)?; 314 let test = self.parse_expression()?; 315 self.expect(&TokenKind::RParen)?; 316 let body = Box::new(self.parse_statement()?); 317 Ok(Stmt { 318 kind: StmtKind::While { test, body }, 319 span: self.span_from(start), 320 }) 321 } 322 323 fn parse_do_while(&mut self) -> Result<Stmt, ParseError> { 324 let start = self.start_span(); 325 self.expect(&TokenKind::Do)?; 326 let body = Box::new(self.parse_statement()?); 327 self.expect(&TokenKind::While)?; 328 self.expect(&TokenKind::LParen)?; 329 let test = self.parse_expression()?; 330 self.expect(&TokenKind::RParen)?; 331 self.expect_semicolon()?; 332 Ok(Stmt { 333 kind: StmtKind::DoWhile { body, test }, 334 span: self.span_from(start), 335 }) 336 } 337 338 fn parse_for(&mut self) -> Result<Stmt, ParseError> { 339 let start = self.start_span(); 340 self.expect(&TokenKind::For)?; 341 self.expect(&TokenKind::LParen)?; 342 343 // Check for for-in/for-of with var/let/const 344 if matches!( 345 self.peek_kind(), 346 TokenKind::Var | TokenKind::Let | TokenKind::Const 347 ) { 348 let var_kind = match self.peek_kind() { 349 TokenKind::Var => VarKind::Var, 350 TokenKind::Let => VarKind::Let, 351 TokenKind::Const => VarKind::Const, 352 _ => unreachable!(), 353 }; 354 self.advance(); 355 let pattern = self.parse_binding_pattern()?; 356 357 if self.eat(&TokenKind::In) { 358 let right = self.parse_expression()?; 359 self.expect(&TokenKind::RParen)?; 360 let body = Box::new(self.parse_statement()?); 361 return Ok(Stmt { 362 kind: StmtKind::ForIn { 363 left: ForInOfLeft::VarDecl { 364 kind: var_kind, 365 pattern, 366 }, 367 right, 368 body, 369 }, 370 span: self.span_from(start), 371 }); 372 } 373 if self.eat(&TokenKind::Of) { 374 let right = self.parse_assignment_expression()?; 375 self.expect(&TokenKind::RParen)?; 376 let body = Box::new(self.parse_statement()?); 377 return Ok(Stmt { 378 kind: StmtKind::ForOf { 379 left: ForInOfLeft::VarDecl { 380 kind: var_kind, 381 pattern, 382 }, 383 right, 384 body, 385 is_await: false, 386 }, 387 span: self.span_from(start), 388 }); 389 } 390 391 // Regular for: parse remaining declarators 392 let mut declarators = vec![VarDeclarator { 393 span: pattern.span, 394 init: if self.eat(&TokenKind::Assign) { 395 Some(self.parse_assignment_expression_no_in()?) 396 } else { 397 None 398 }, 399 pattern, 400 }]; 401 while self.eat(&TokenKind::Comma) { 402 declarators.push(self.parse_var_declarator_no_in()?); 403 } 404 self.expect(&TokenKind::Semicolon)?; 405 let test = if self.at(&TokenKind::Semicolon) { 406 None 407 } else { 408 Some(self.parse_expression()?) 409 }; 410 self.expect(&TokenKind::Semicolon)?; 411 let update = if self.at(&TokenKind::RParen) { 412 None 413 } else { 414 Some(self.parse_expression()?) 415 }; 416 self.expect(&TokenKind::RParen)?; 417 let body = Box::new(self.parse_statement()?); 418 return Ok(Stmt { 419 kind: StmtKind::For { 420 init: Some(ForInit::VarDecl { 421 kind: var_kind, 422 declarators, 423 }), 424 test, 425 update, 426 body, 427 }, 428 span: self.span_from(start), 429 }); 430 } 431 432 // No var/let/const 433 if self.eat(&TokenKind::Semicolon) { 434 // for(; ...) 435 let test = if self.at(&TokenKind::Semicolon) { 436 None 437 } else { 438 Some(self.parse_expression()?) 439 }; 440 self.expect(&TokenKind::Semicolon)?; 441 let update = if self.at(&TokenKind::RParen) { 442 None 443 } else { 444 Some(self.parse_expression()?) 445 }; 446 self.expect(&TokenKind::RParen)?; 447 let body = Box::new(self.parse_statement()?); 448 return Ok(Stmt { 449 kind: StmtKind::For { 450 init: None, 451 test, 452 update, 453 body, 454 }, 455 span: self.span_from(start), 456 }); 457 } 458 459 // Expression init — might be for-in/for-of 460 let old_allow_in = self.allow_in; 461 self.allow_in = false; 462 let init_expr = self.parse_expression()?; 463 self.allow_in = old_allow_in; 464 465 if self.eat(&TokenKind::In) { 466 let pattern = self.expr_to_pattern(&init_expr)?; 467 let right = self.parse_expression()?; 468 self.expect(&TokenKind::RParen)?; 469 let body = Box::new(self.parse_statement()?); 470 return Ok(Stmt { 471 kind: StmtKind::ForIn { 472 left: ForInOfLeft::Pattern(pattern), 473 right, 474 body, 475 }, 476 span: self.span_from(start), 477 }); 478 } 479 if self.eat(&TokenKind::Of) { 480 let pattern = self.expr_to_pattern(&init_expr)?; 481 let right = self.parse_assignment_expression()?; 482 self.expect(&TokenKind::RParen)?; 483 let body = Box::new(self.parse_statement()?); 484 return Ok(Stmt { 485 kind: StmtKind::ForOf { 486 left: ForInOfLeft::Pattern(pattern), 487 right, 488 body, 489 is_await: false, 490 }, 491 span: self.span_from(start), 492 }); 493 } 494 495 self.expect(&TokenKind::Semicolon)?; 496 let test = if self.at(&TokenKind::Semicolon) { 497 None 498 } else { 499 Some(self.parse_expression()?) 500 }; 501 self.expect(&TokenKind::Semicolon)?; 502 let update = if self.at(&TokenKind::RParen) { 503 None 504 } else { 505 Some(self.parse_expression()?) 506 }; 507 self.expect(&TokenKind::RParen)?; 508 let body = Box::new(self.parse_statement()?); 509 Ok(Stmt { 510 kind: StmtKind::For { 511 init: Some(ForInit::Expr(init_expr)), 512 test, 513 update, 514 body, 515 }, 516 span: self.span_from(start), 517 }) 518 } 519 520 fn parse_switch(&mut self) -> Result<Stmt, ParseError> { 521 let start = self.start_span(); 522 self.expect(&TokenKind::Switch)?; 523 self.expect(&TokenKind::LParen)?; 524 let discriminant = self.parse_expression()?; 525 self.expect(&TokenKind::RParen)?; 526 self.expect(&TokenKind::LBrace)?; 527 let mut cases = Vec::new(); 528 while !self.at(&TokenKind::RBrace) && !self.at_eof() { 529 let case_start = self.start_span(); 530 let test = if self.eat(&TokenKind::Case) { 531 Some(self.parse_expression()?) 532 } else { 533 self.expect(&TokenKind::Default)?; 534 None 535 }; 536 self.expect(&TokenKind::Colon)?; 537 let mut consequent = Vec::new(); 538 while !matches!( 539 self.peek_kind(), 540 TokenKind::Case | TokenKind::Default | TokenKind::RBrace 541 ) && !self.at_eof() 542 { 543 consequent.push(self.parse_statement_list_item()?); 544 } 545 cases.push(SwitchCase { 546 test, 547 consequent, 548 span: self.span_from(case_start), 549 }); 550 } 551 self.expect(&TokenKind::RBrace)?; 552 Ok(Stmt { 553 kind: StmtKind::Switch { 554 discriminant, 555 cases, 556 }, 557 span: self.span_from(start), 558 }) 559 } 560 561 fn parse_try(&mut self) -> Result<Stmt, ParseError> { 562 let start = self.start_span(); 563 self.expect(&TokenKind::Try)?; 564 let block = self.parse_block_body()?; 565 566 let handler = if self.eat(&TokenKind::Catch) { 567 let catch_start = self.start_span(); 568 let param = if self.eat(&TokenKind::LParen) { 569 let pat = self.parse_binding_pattern()?; 570 self.expect(&TokenKind::RParen)?; 571 Some(pat) 572 } else { 573 None 574 }; 575 let body = self.parse_block_body()?; 576 Some(CatchClause { 577 param, 578 body, 579 span: self.span_from(catch_start), 580 }) 581 } else { 582 None 583 }; 584 585 let finalizer = if self.eat(&TokenKind::Finally) { 586 Some(self.parse_block_body()?) 587 } else { 588 None 589 }; 590 591 if handler.is_none() && finalizer.is_none() { 592 return Err(self.error("try requires catch or finally".into())); 593 } 594 595 Ok(Stmt { 596 kind: StmtKind::Try { 597 block, 598 handler, 599 finalizer, 600 }, 601 span: self.span_from(start), 602 }) 603 } 604 605 fn parse_return(&mut self) -> Result<Stmt, ParseError> { 606 let start = self.start_span(); 607 self.expect(&TokenKind::Return)?; 608 // Restricted production: newline after return inserts semicolon 609 let argument = if matches!( 610 self.peek_kind(), 611 TokenKind::Semicolon | TokenKind::RBrace | TokenKind::Eof 612 ) || self.peek().preceded_by_newline 613 { 614 None 615 } else { 616 Some(self.parse_expression()?) 617 }; 618 self.expect_semicolon()?; 619 Ok(Stmt { 620 kind: StmtKind::Return(argument), 621 span: self.span_from(start), 622 }) 623 } 624 625 fn parse_throw(&mut self) -> Result<Stmt, ParseError> { 626 let start = self.start_span(); 627 self.expect(&TokenKind::Throw)?; 628 if self.peek().preceded_by_newline { 629 return Err(ParseError { 630 message: "newline not allowed after throw".into(), 631 pos: self.peek().span.start, 632 }); 633 } 634 let argument = self.parse_expression()?; 635 self.expect_semicolon()?; 636 Ok(Stmt { 637 kind: StmtKind::Throw(argument), 638 span: self.span_from(start), 639 }) 640 } 641 642 fn parse_break(&mut self) -> Result<Stmt, ParseError> { 643 let start = self.start_span(); 644 self.expect(&TokenKind::Break)?; 645 let label = if !self.peek().preceded_by_newline { 646 if let TokenKind::Identifier(name) = self.peek_kind().clone() { 647 self.advance(); 648 Some(name) 649 } else { 650 None 651 } 652 } else { 653 None 654 }; 655 self.expect_semicolon()?; 656 Ok(Stmt { 657 kind: StmtKind::Break(label), 658 span: self.span_from(start), 659 }) 660 } 661 662 fn parse_continue(&mut self) -> Result<Stmt, ParseError> { 663 let start = self.start_span(); 664 self.expect(&TokenKind::Continue)?; 665 let label = if !self.peek().preceded_by_newline { 666 if let TokenKind::Identifier(name) = self.peek_kind().clone() { 667 self.advance(); 668 Some(name) 669 } else { 670 None 671 } 672 } else { 673 None 674 }; 675 self.expect_semicolon()?; 676 Ok(Stmt { 677 kind: StmtKind::Continue(label), 678 span: self.span_from(start), 679 }) 680 } 681 682 fn parse_labeled(&mut self) -> Result<Stmt, ParseError> { 683 let start = self.start_span(); 684 let label = self.expect_identifier()?; 685 self.expect(&TokenKind::Colon)?; 686 let body = Box::new(self.parse_statement()?); 687 Ok(Stmt { 688 kind: StmtKind::Labeled { label, body }, 689 span: self.span_from(start), 690 }) 691 } 692 693 fn parse_with(&mut self) -> Result<Stmt, ParseError> { 694 let start = self.start_span(); 695 self.expect(&TokenKind::With)?; 696 self.expect(&TokenKind::LParen)?; 697 let object = self.parse_expression()?; 698 self.expect(&TokenKind::RParen)?; 699 let body = Box::new(self.parse_statement()?); 700 Ok(Stmt { 701 kind: StmtKind::With { object, body }, 702 span: self.span_from(start), 703 }) 704 } 705 706 // ── Variable declarations ─────────────────────────────── 707 708 fn parse_variable_declaration_stmt(&mut self) -> Result<Stmt, ParseError> { 709 let start = self.start_span(); 710 let kind = match self.peek_kind() { 711 TokenKind::Var => VarKind::Var, 712 TokenKind::Let => VarKind::Let, 713 TokenKind::Const => VarKind::Const, 714 _ => return Err(self.error("expected var, let, or const".into())), 715 }; 716 self.advance(); 717 let mut declarators = vec![self.parse_var_declarator()?]; 718 while self.eat(&TokenKind::Comma) { 719 declarators.push(self.parse_var_declarator()?); 720 } 721 self.expect_semicolon()?; 722 Ok(Stmt { 723 kind: StmtKind::VarDecl { kind, declarators }, 724 span: self.span_from(start), 725 }) 726 } 727 728 fn parse_var_declarator(&mut self) -> Result<VarDeclarator, ParseError> { 729 let start = self.start_span(); 730 let pattern = self.parse_binding_pattern()?; 731 let init = if self.eat(&TokenKind::Assign) { 732 Some(self.parse_assignment_expression()?) 733 } else { 734 None 735 }; 736 Ok(VarDeclarator { 737 pattern, 738 init, 739 span: self.span_from(start), 740 }) 741 } 742 743 fn parse_var_declarator_no_in(&mut self) -> Result<VarDeclarator, ParseError> { 744 let start = self.start_span(); 745 let pattern = self.parse_binding_pattern()?; 746 let init = if self.eat(&TokenKind::Assign) { 747 Some(self.parse_assignment_expression_no_in()?) 748 } else { 749 None 750 }; 751 Ok(VarDeclarator { 752 pattern, 753 init, 754 span: self.span_from(start), 755 }) 756 } 757 758 // ── Binding patterns (destructuring) ──────────────────── 759 760 fn parse_binding_pattern(&mut self) -> Result<Pattern, ParseError> { 761 match self.peek_kind() { 762 TokenKind::LBracket => self.parse_array_pattern(), 763 TokenKind::LBrace => self.parse_object_pattern(), 764 _ => { 765 let start = self.start_span(); 766 let name = self.expect_identifier()?; 767 Ok(Pattern { 768 kind: PatternKind::Identifier(name), 769 span: self.span_from(start), 770 }) 771 } 772 } 773 } 774 775 fn parse_array_pattern(&mut self) -> Result<Pattern, ParseError> { 776 let start = self.start_span(); 777 self.expect(&TokenKind::LBracket)?; 778 let mut elements = Vec::new(); 779 let mut rest = None; 780 while !self.at(&TokenKind::RBracket) && !self.at_eof() { 781 if self.eat(&TokenKind::Comma) { 782 elements.push(None); 783 continue; 784 } 785 if self.at(&TokenKind::Ellipsis) { 786 self.advance(); 787 rest = Some(Box::new(self.parse_binding_pattern()?)); 788 self.eat(&TokenKind::Comma); // trailing comma after rest 789 break; 790 } 791 let mut pat = self.parse_binding_pattern()?; 792 if self.eat(&TokenKind::Assign) { 793 let right = self.parse_assignment_expression()?; 794 let span = Span { 795 start: pat.span.start, 796 end: right.span.end, 797 }; 798 pat = Pattern { 799 kind: PatternKind::Assign { 800 left: Box::new(pat), 801 right: Box::new(right), 802 }, 803 span, 804 }; 805 } 806 elements.push(Some(pat)); 807 if !self.eat(&TokenKind::Comma) { 808 break; 809 } 810 } 811 self.expect(&TokenKind::RBracket)?; 812 Ok(Pattern { 813 kind: PatternKind::Array { elements, rest }, 814 span: self.span_from(start), 815 }) 816 } 817 818 fn parse_object_pattern(&mut self) -> Result<Pattern, ParseError> { 819 let start = self.start_span(); 820 self.expect(&TokenKind::LBrace)?; 821 let mut properties = Vec::new(); 822 let mut rest = None; 823 while !self.at(&TokenKind::RBrace) && !self.at_eof() { 824 if self.at(&TokenKind::Ellipsis) { 825 self.advance(); 826 rest = Some(Box::new(self.parse_binding_pattern()?)); 827 self.eat(&TokenKind::Comma); 828 break; 829 } 830 let prop_start = self.start_span(); 831 let (key, computed) = self.parse_property_name()?; 832 if self.eat(&TokenKind::Colon) { 833 // { key: pattern } 834 let mut value = self.parse_binding_pattern()?; 835 if self.eat(&TokenKind::Assign) { 836 let right = self.parse_assignment_expression()?; 837 let span = Span { 838 start: value.span.start, 839 end: right.span.end, 840 }; 841 value = Pattern { 842 kind: PatternKind::Assign { 843 left: Box::new(value), 844 right: Box::new(right), 845 }, 846 span, 847 }; 848 } 849 properties.push(ObjectPatternProp { 850 key, 851 value, 852 computed, 853 shorthand: false, 854 span: self.span_from(prop_start), 855 }); 856 } else { 857 // Shorthand: { name } or { name = default } 858 let name = match &key { 859 PropertyKey::Identifier(n) => n.clone(), 860 _ => return Err(self.error("shorthand properties require identifier".into())), 861 }; 862 let ident_span = self.span_from(prop_start); 863 let mut value = Pattern { 864 kind: PatternKind::Identifier(name.clone()), 865 span: ident_span, 866 }; 867 if self.eat(&TokenKind::Assign) { 868 let right = self.parse_assignment_expression()?; 869 let span = Span { 870 start: value.span.start, 871 end: right.span.end, 872 }; 873 value = Pattern { 874 kind: PatternKind::Assign { 875 left: Box::new(value), 876 right: Box::new(right), 877 }, 878 span, 879 }; 880 } 881 properties.push(ObjectPatternProp { 882 key, 883 value, 884 computed, 885 shorthand: true, 886 span: self.span_from(prop_start), 887 }); 888 } 889 if !self.eat(&TokenKind::Comma) { 890 break; 891 } 892 } 893 self.expect(&TokenKind::RBrace)?; 894 Ok(Pattern { 895 kind: PatternKind::Object { properties, rest }, 896 span: self.span_from(start), 897 }) 898 } 899 900 // ── Function declarations ─────────────────────────────── 901 902 fn parse_function_declaration(&mut self) -> Result<Stmt, ParseError> { 903 let start = self.start_span(); 904 self.expect(&TokenKind::Function)?; 905 let is_generator = self.eat(&TokenKind::Star); 906 let id = Some(self.expect_identifier()?); 907 let (params, body) = self.parse_function_params_and_body()?; 908 Ok(Stmt { 909 kind: StmtKind::FunctionDecl(FunctionDef { 910 id, 911 params, 912 body, 913 is_async: false, 914 is_generator, 915 }), 916 span: self.span_from(start), 917 }) 918 } 919 920 fn parse_async_function_declaration(&mut self) -> Result<Stmt, ParseError> { 921 let start = self.start_span(); 922 self.expect(&TokenKind::Async)?; 923 self.expect(&TokenKind::Function)?; 924 let is_generator = self.eat(&TokenKind::Star); 925 let id = Some(self.expect_identifier()?); 926 let (params, body) = self.parse_function_params_and_body()?; 927 Ok(Stmt { 928 kind: StmtKind::FunctionDecl(FunctionDef { 929 id, 930 params, 931 body, 932 is_async: true, 933 is_generator, 934 }), 935 span: self.span_from(start), 936 }) 937 } 938 939 fn parse_function_params_and_body(&mut self) -> Result<(Vec<Pattern>, Vec<Stmt>), ParseError> { 940 self.expect(&TokenKind::LParen)?; 941 let params = self.parse_formal_parameters()?; 942 self.expect(&TokenKind::RParen)?; 943 let body = self.parse_block_body()?; 944 Ok((params, body)) 945 } 946 947 fn parse_formal_parameters(&mut self) -> Result<Vec<Pattern>, ParseError> { 948 let mut params = Vec::new(); 949 while !self.at(&TokenKind::RParen) && !self.at_eof() { 950 if self.at(&TokenKind::Ellipsis) { 951 self.advance(); 952 params.push(self.parse_binding_pattern()?); 953 self.eat(&TokenKind::Comma); 954 break; 955 } 956 let mut pat = self.parse_binding_pattern()?; 957 if self.eat(&TokenKind::Assign) { 958 let right = self.parse_assignment_expression()?; 959 let span = Span { 960 start: pat.span.start, 961 end: right.span.end, 962 }; 963 pat = Pattern { 964 kind: PatternKind::Assign { 965 left: Box::new(pat), 966 right: Box::new(right), 967 }, 968 span, 969 }; 970 } 971 params.push(pat); 972 if !self.eat(&TokenKind::Comma) { 973 break; 974 } 975 } 976 Ok(params) 977 } 978 979 // ── Class declarations ────────────────────────────────── 980 981 fn parse_class_declaration(&mut self) -> Result<Stmt, ParseError> { 982 let start = self.start_span(); 983 let class_def = self.parse_class(true)?; 984 Ok(Stmt { 985 kind: StmtKind::ClassDecl(class_def), 986 span: self.span_from(start), 987 }) 988 } 989 990 fn parse_class(&mut self, require_name: bool) -> Result<ClassDef, ParseError> { 991 self.expect(&TokenKind::Class)?; 992 let id = if require_name { 993 Some(self.expect_identifier()?) 994 } else if let TokenKind::Identifier(_) = self.peek_kind() { 995 Some(self.expect_identifier()?) 996 } else { 997 None 998 }; 999 let super_class = if self.eat(&TokenKind::Extends) { 1000 Some(Box::new(self.parse_left_hand_side_expression()?)) 1001 } else { 1002 None 1003 }; 1004 let body = self.parse_class_body()?; 1005 Ok(ClassDef { 1006 id, 1007 super_class, 1008 body, 1009 }) 1010 } 1011 1012 fn parse_class_body(&mut self) -> Result<Vec<ClassMember>, ParseError> { 1013 self.expect(&TokenKind::LBrace)?; 1014 let mut members = Vec::new(); 1015 while !self.at(&TokenKind::RBrace) && !self.at_eof() { 1016 if self.eat(&TokenKind::Semicolon) { 1017 continue; 1018 } 1019 members.push(self.parse_class_member()?); 1020 } 1021 self.expect(&TokenKind::RBrace)?; 1022 Ok(members) 1023 } 1024 1025 fn parse_class_member(&mut self) -> Result<ClassMember, ParseError> { 1026 let start = self.start_span(); 1027 let is_static = self.eat(&TokenKind::Static); 1028 1029 // Check for getter/setter 1030 if let TokenKind::Identifier(ref name) = self.peek_kind().clone() { 1031 if (name == "get" || name == "set") 1032 && !matches!( 1033 self.peek_ahead(1), 1034 TokenKind::LParen | TokenKind::Assign | TokenKind::Semicolon 1035 ) 1036 { 1037 let kind = if name == "get" { 1038 MethodKind::Get 1039 } else { 1040 MethodKind::Set 1041 }; 1042 self.advance(); 1043 let (key, computed) = self.parse_property_name()?; 1044 let (params, body) = self.parse_function_params_and_body()?; 1045 return Ok(ClassMember { 1046 kind: ClassMemberKind::Method { 1047 key, 1048 value: FunctionDef { 1049 id: None, 1050 params, 1051 body, 1052 is_async: false, 1053 is_generator: false, 1054 }, 1055 kind, 1056 is_static, 1057 computed, 1058 }, 1059 span: self.span_from(start), 1060 }); 1061 } 1062 } 1063 1064 // Generator method 1065 let is_generator = self.eat(&TokenKind::Star); 1066 1067 // Async method 1068 let is_async = if !is_generator 1069 && matches!(self.peek_kind(), TokenKind::Async) 1070 && !matches!( 1071 self.peek_ahead(1), 1072 TokenKind::LParen | TokenKind::Assign | TokenKind::Semicolon 1073 ) { 1074 self.advance(); 1075 true 1076 } else { 1077 false 1078 }; 1079 1080 let is_generator = is_generator || (is_async && self.eat(&TokenKind::Star)); 1081 1082 let (key, computed) = self.parse_property_name()?; 1083 1084 // Check for constructor 1085 let method_kind = 1086 if !is_static && !computed && key == PropertyKey::Identifier("constructor".into()) { 1087 MethodKind::Constructor 1088 } else { 1089 MethodKind::Method 1090 }; 1091 1092 if self.at(&TokenKind::LParen) { 1093 let (params, body) = self.parse_function_params_and_body()?; 1094 Ok(ClassMember { 1095 kind: ClassMemberKind::Method { 1096 key, 1097 value: FunctionDef { 1098 id: None, 1099 params, 1100 body, 1101 is_async, 1102 is_generator, 1103 }, 1104 kind: method_kind, 1105 is_static, 1106 computed, 1107 }, 1108 span: self.span_from(start), 1109 }) 1110 } else { 1111 // Class field 1112 let value = if self.eat(&TokenKind::Assign) { 1113 Some(self.parse_assignment_expression()?) 1114 } else { 1115 None 1116 }; 1117 self.expect_semicolon()?; 1118 Ok(ClassMember { 1119 kind: ClassMemberKind::Property { 1120 key, 1121 value, 1122 is_static, 1123 computed, 1124 }, 1125 span: self.span_from(start), 1126 }) 1127 } 1128 } 1129 1130 // ── Import / Export ───────────────────────────────────── 1131 1132 fn parse_import_declaration(&mut self) -> Result<Stmt, ParseError> { 1133 let start = self.start_span(); 1134 self.expect(&TokenKind::Import)?; 1135 1136 // `import "source"` — side-effect import 1137 if let TokenKind::String(source) = self.peek_kind().clone() { 1138 self.advance(); 1139 self.expect_semicolon()?; 1140 return Ok(Stmt { 1141 kind: StmtKind::Import { 1142 specifiers: vec![], 1143 source, 1144 }, 1145 span: self.span_from(start), 1146 }); 1147 } 1148 1149 let mut specifiers = Vec::new(); 1150 1151 // `import * as ns from "source"` 1152 if self.eat(&TokenKind::Star) { 1153 self.expect_identifier_matching("as")?; 1154 let local = self.expect_identifier()?; 1155 specifiers.push(ImportSpecifier::Namespace(local)); 1156 } 1157 // `import { a, b as c } from "source"` 1158 else if self.at(&TokenKind::LBrace) { 1159 self.advance(); 1160 while !self.at(&TokenKind::RBrace) && !self.at_eof() { 1161 let imported = self.expect_identifier()?; 1162 let local = if self.eat_identifier_matching("as") { 1163 self.expect_identifier()? 1164 } else { 1165 imported.clone() 1166 }; 1167 specifiers.push(ImportSpecifier::Named { imported, local }); 1168 if !self.eat(&TokenKind::Comma) { 1169 break; 1170 } 1171 } 1172 self.expect(&TokenKind::RBrace)?; 1173 } 1174 // `import defaultExport from "source"` or `import defaultExport, { ... } from "source"` 1175 else { 1176 let default_name = self.expect_identifier()?; 1177 specifiers.push(ImportSpecifier::Default(default_name)); 1178 1179 if self.eat(&TokenKind::Comma) { 1180 if self.eat(&TokenKind::Star) { 1181 self.expect_identifier_matching("as")?; 1182 let local = self.expect_identifier()?; 1183 specifiers.push(ImportSpecifier::Namespace(local)); 1184 } else { 1185 self.expect(&TokenKind::LBrace)?; 1186 while !self.at(&TokenKind::RBrace) && !self.at_eof() { 1187 let imported = self.expect_identifier()?; 1188 let local = if self.eat_identifier_matching("as") { 1189 self.expect_identifier()? 1190 } else { 1191 imported.clone() 1192 }; 1193 specifiers.push(ImportSpecifier::Named { imported, local }); 1194 if !self.eat(&TokenKind::Comma) { 1195 break; 1196 } 1197 } 1198 self.expect(&TokenKind::RBrace)?; 1199 } 1200 } 1201 } 1202 1203 self.expect_identifier_matching("from")?; 1204 let source = match self.peek_kind().clone() { 1205 TokenKind::String(s) => { 1206 self.advance(); 1207 s 1208 } 1209 _ => return Err(self.error("expected module source string".into())), 1210 }; 1211 self.expect_semicolon()?; 1212 Ok(Stmt { 1213 kind: StmtKind::Import { specifiers, source }, 1214 span: self.span_from(start), 1215 }) 1216 } 1217 1218 fn parse_export_declaration(&mut self) -> Result<Stmt, ParseError> { 1219 let start = self.start_span(); 1220 self.expect(&TokenKind::Export)?; 1221 1222 // `export default ...` 1223 if self.eat(&TokenKind::Default) { 1224 if matches!(self.peek_kind(), TokenKind::Function) { 1225 // Named function → declaration, anonymous → default expression 1226 let has_name = matches!(self.peek_ahead(1), TokenKind::Identifier(_)) 1227 || (matches!(self.peek_ahead(1), TokenKind::Star) 1228 && matches!(self.peek_ahead(2), TokenKind::Identifier(_))); 1229 if has_name { 1230 let decl = self.parse_function_declaration()?; 1231 return Ok(Stmt { 1232 kind: StmtKind::Export(ExportDecl::Declaration(Box::new(decl))), 1233 span: self.span_from(start), 1234 }); 1235 } 1236 let expr = self.parse_function_expression()?; 1237 return Ok(Stmt { 1238 kind: StmtKind::Export(ExportDecl::Default(expr)), 1239 span: self.span_from(start), 1240 }); 1241 } 1242 if matches!(self.peek_kind(), TokenKind::Class) { 1243 // Named class → declaration, anonymous → default expression 1244 if matches!(self.peek_ahead(1), TokenKind::Identifier(_)) { 1245 let decl = self.parse_class_declaration()?; 1246 return Ok(Stmt { 1247 kind: StmtKind::Export(ExportDecl::Declaration(Box::new(decl))), 1248 span: self.span_from(start), 1249 }); 1250 } 1251 let expr = self.parse_class_expression()?; 1252 return Ok(Stmt { 1253 kind: StmtKind::Export(ExportDecl::Default(expr)), 1254 span: self.span_from(start), 1255 }); 1256 } 1257 let expr = self.parse_assignment_expression()?; 1258 self.expect_semicolon()?; 1259 return Ok(Stmt { 1260 kind: StmtKind::Export(ExportDecl::Default(expr)), 1261 span: self.span_from(start), 1262 }); 1263 } 1264 1265 // `export * from "source"` 1266 if self.eat(&TokenKind::Star) { 1267 self.expect_identifier_matching("from")?; 1268 let source = match self.peek_kind().clone() { 1269 TokenKind::String(s) => { 1270 self.advance(); 1271 s 1272 } 1273 _ => return Err(self.error("expected module source string".into())), 1274 }; 1275 self.expect_semicolon()?; 1276 return Ok(Stmt { 1277 kind: StmtKind::Export(ExportDecl::AllFrom(source)), 1278 span: self.span_from(start), 1279 }); 1280 } 1281 1282 // `export { a, b as c } [from "source"]` 1283 if self.at(&TokenKind::LBrace) { 1284 self.advance(); 1285 let mut specifiers = Vec::new(); 1286 while !self.at(&TokenKind::RBrace) && !self.at_eof() { 1287 let local = self.expect_identifier()?; 1288 let exported = if self.eat_identifier_matching("as") { 1289 self.expect_identifier()? 1290 } else { 1291 local.clone() 1292 }; 1293 specifiers.push(ExportSpecifier { local, exported }); 1294 if !self.eat(&TokenKind::Comma) { 1295 break; 1296 } 1297 } 1298 self.expect(&TokenKind::RBrace)?; 1299 let source = if self.eat_identifier_matching("from") { 1300 match self.peek_kind().clone() { 1301 TokenKind::String(s) => { 1302 self.advance(); 1303 Some(s) 1304 } 1305 _ => return Err(self.error("expected module source string".into())), 1306 } 1307 } else { 1308 None 1309 }; 1310 self.expect_semicolon()?; 1311 return Ok(Stmt { 1312 kind: StmtKind::Export(ExportDecl::Named { specifiers, source }), 1313 span: self.span_from(start), 1314 }); 1315 } 1316 1317 // `export var/let/const/function/class ...` 1318 let decl = self.parse_statement_list_item()?; 1319 Ok(Stmt { 1320 kind: StmtKind::Export(ExportDecl::Declaration(Box::new(decl))), 1321 span: self.span_from(start), 1322 }) 1323 } 1324 1325 // ── Helper for contextual keywords ────────────────────── 1326 1327 fn expect_identifier_matching(&mut self, expected: &str) -> Result<(), ParseError> { 1328 match self.peek_kind().clone() { 1329 TokenKind::Identifier(ref name) if name == expected => { 1330 self.advance(); 1331 Ok(()) 1332 } 1333 _ => Err(self.error(format!("expected '{}'", expected))), 1334 } 1335 } 1336 1337 fn eat_identifier_matching(&mut self, expected: &str) -> bool { 1338 if let TokenKind::Identifier(ref name) = self.peek_kind() { 1339 if name == expected { 1340 self.advance(); 1341 return true; 1342 } 1343 } 1344 false 1345 } 1346 1347 // ── Expressions ───────────────────────────────────────── 1348 1349 fn parse_expression(&mut self) -> Result<Expr, ParseError> { 1350 let start = self.start_span(); 1351 let expr = self.parse_assignment_expression()?; 1352 if !self.at(&TokenKind::Comma) { 1353 return Ok(expr); 1354 } 1355 let mut exprs = vec![expr]; 1356 while self.eat(&TokenKind::Comma) { 1357 exprs.push(self.parse_assignment_expression()?); 1358 } 1359 Ok(Expr { 1360 kind: ExprKind::Sequence(exprs), 1361 span: self.span_from(start), 1362 }) 1363 } 1364 1365 fn parse_assignment_expression(&mut self) -> Result<Expr, ParseError> { 1366 // Check for arrow function: `x => ...` or `async x => ...` 1367 if let TokenKind::Identifier(ref name) = self.peek_kind().clone() { 1368 if matches!(self.peek_ahead(1), TokenKind::Arrow) && !self.peek().preceded_by_newline { 1369 let param_start = self.start_span(); 1370 let name = name.clone(); 1371 self.advance(); // identifier 1372 self.advance(); // => 1373 let params = vec![Pattern { 1374 kind: PatternKind::Identifier(name), 1375 span: self.span_from(param_start), 1376 }]; 1377 return self.parse_arrow_body(param_start, params, false); 1378 } 1379 } 1380 1381 // Check for `async x => ...` or `async (...)` arrow 1382 if matches!(self.peek_kind(), TokenKind::Async) && !self.peek().preceded_by_newline { 1383 if let TokenKind::Identifier(_) = self.peek_ahead(1) { 1384 if matches!(self.peek_ahead(2), TokenKind::Arrow) { 1385 let start = self.start_span(); 1386 self.advance(); // async 1387 let param_start = self.start_span(); 1388 let name = self.expect_identifier()?; 1389 self.advance(); // => 1390 let params = vec![Pattern { 1391 kind: PatternKind::Identifier(name), 1392 span: self.span_from(param_start), 1393 }]; 1394 return self.parse_arrow_body(start, params, true); 1395 } 1396 } 1397 } 1398 1399 let start = self.start_span(); 1400 let left = self.parse_conditional_expression()?; 1401 1402 // Check for arrow function after parenthesized expr: `(a, b) => ...` 1403 if matches!(self.peek_kind(), TokenKind::Arrow) && !self.peek().preceded_by_newline { 1404 self.advance(); // => 1405 let params = self.expr_to_params(&left)?; 1406 return self.parse_arrow_body(start, params, false); 1407 } 1408 1409 // Assignment 1410 if let Some(op) = self.peek_assign_op() { 1411 self.advance(); 1412 let right = self.parse_assignment_expression()?; 1413 return Ok(Expr { 1414 span: self.span_from(start), 1415 kind: ExprKind::Assignment { 1416 op, 1417 left: Box::new(left), 1418 right: Box::new(right), 1419 }, 1420 }); 1421 } 1422 1423 Ok(left) 1424 } 1425 1426 fn parse_assignment_expression_no_in(&mut self) -> Result<Expr, ParseError> { 1427 let old = self.allow_in; 1428 self.allow_in = false; 1429 let result = self.parse_assignment_expression(); 1430 self.allow_in = old; 1431 result 1432 } 1433 1434 fn parse_arrow_body( 1435 &mut self, 1436 start: SourcePos, 1437 params: Vec<Pattern>, 1438 is_async: bool, 1439 ) -> Result<Expr, ParseError> { 1440 let body = if self.at(&TokenKind::LBrace) { 1441 ArrowBody::Block(self.parse_block_body()?) 1442 } else { 1443 ArrowBody::Expr(Box::new(self.parse_assignment_expression()?)) 1444 }; 1445 Ok(Expr { 1446 kind: ExprKind::Arrow { 1447 params, 1448 body, 1449 is_async, 1450 }, 1451 span: self.span_from(start), 1452 }) 1453 } 1454 1455 fn parse_conditional_expression(&mut self) -> Result<Expr, ParseError> { 1456 let start = self.start_span(); 1457 let expr = self.parse_binary_expression(0)?; 1458 if !self.eat(&TokenKind::Question) { 1459 return Ok(expr); 1460 } 1461 let consequent = self.parse_assignment_expression()?; 1462 self.expect(&TokenKind::Colon)?; 1463 let alternate = self.parse_assignment_expression()?; 1464 Ok(Expr { 1465 kind: ExprKind::Conditional { 1466 test: Box::new(expr), 1467 consequent: Box::new(consequent), 1468 alternate: Box::new(alternate), 1469 }, 1470 span: self.span_from(start), 1471 }) 1472 } 1473 1474 // ── Pratt expression parsing ──────────────────────────── 1475 1476 fn parse_binary_expression(&mut self, min_bp: u8) -> Result<Expr, ParseError> { 1477 let start = self.start_span(); 1478 let mut left = self.parse_unary_expression()?; 1479 1480 loop { 1481 let Some((op, left_bp, right_bp)) = self.peek_binary_op() else { 1482 break; 1483 }; 1484 if left_bp < min_bp { 1485 break; 1486 } 1487 self.advance(); 1488 1489 let right = self.parse_binary_expression(right_bp)?; 1490 let span = self.span_from(start); 1491 1492 left = match op { 1493 BinOrLogical::Binary(op) => Expr { 1494 kind: ExprKind::Binary { 1495 op, 1496 left: Box::new(left), 1497 right: Box::new(right), 1498 }, 1499 span, 1500 }, 1501 BinOrLogical::Logical(op) => Expr { 1502 kind: ExprKind::Logical { 1503 op, 1504 left: Box::new(left), 1505 right: Box::new(right), 1506 }, 1507 span, 1508 }, 1509 }; 1510 } 1511 1512 Ok(left) 1513 } 1514 1515 fn parse_unary_expression(&mut self) -> Result<Expr, ParseError> { 1516 let start = self.start_span(); 1517 match self.peek_kind() { 1518 TokenKind::Minus => { 1519 self.advance(); 1520 let arg = self.parse_unary_expression()?; 1521 Ok(Expr { 1522 kind: ExprKind::Unary { 1523 op: UnaryOp::Minus, 1524 argument: Box::new(arg), 1525 }, 1526 span: self.span_from(start), 1527 }) 1528 } 1529 TokenKind::Plus => { 1530 self.advance(); 1531 let arg = self.parse_unary_expression()?; 1532 Ok(Expr { 1533 kind: ExprKind::Unary { 1534 op: UnaryOp::Plus, 1535 argument: Box::new(arg), 1536 }, 1537 span: self.span_from(start), 1538 }) 1539 } 1540 TokenKind::Not => { 1541 self.advance(); 1542 let arg = self.parse_unary_expression()?; 1543 Ok(Expr { 1544 kind: ExprKind::Unary { 1545 op: UnaryOp::Not, 1546 argument: Box::new(arg), 1547 }, 1548 span: self.span_from(start), 1549 }) 1550 } 1551 TokenKind::Tilde => { 1552 self.advance(); 1553 let arg = self.parse_unary_expression()?; 1554 Ok(Expr { 1555 kind: ExprKind::Unary { 1556 op: UnaryOp::BitwiseNot, 1557 argument: Box::new(arg), 1558 }, 1559 span: self.span_from(start), 1560 }) 1561 } 1562 TokenKind::Typeof => { 1563 self.advance(); 1564 let arg = self.parse_unary_expression()?; 1565 Ok(Expr { 1566 kind: ExprKind::Unary { 1567 op: UnaryOp::Typeof, 1568 argument: Box::new(arg), 1569 }, 1570 span: self.span_from(start), 1571 }) 1572 } 1573 TokenKind::Void => { 1574 self.advance(); 1575 let arg = self.parse_unary_expression()?; 1576 Ok(Expr { 1577 kind: ExprKind::Unary { 1578 op: UnaryOp::Void, 1579 argument: Box::new(arg), 1580 }, 1581 span: self.span_from(start), 1582 }) 1583 } 1584 TokenKind::Delete => { 1585 self.advance(); 1586 let arg = self.parse_unary_expression()?; 1587 Ok(Expr { 1588 kind: ExprKind::Unary { 1589 op: UnaryOp::Delete, 1590 argument: Box::new(arg), 1591 }, 1592 span: self.span_from(start), 1593 }) 1594 } 1595 TokenKind::PlusPlus => { 1596 self.advance(); 1597 let arg = self.parse_unary_expression()?; 1598 Ok(Expr { 1599 kind: ExprKind::Update { 1600 op: UpdateOp::Increment, 1601 argument: Box::new(arg), 1602 prefix: true, 1603 }, 1604 span: self.span_from(start), 1605 }) 1606 } 1607 TokenKind::MinusMinus => { 1608 self.advance(); 1609 let arg = self.parse_unary_expression()?; 1610 Ok(Expr { 1611 kind: ExprKind::Update { 1612 op: UpdateOp::Decrement, 1613 argument: Box::new(arg), 1614 prefix: true, 1615 }, 1616 span: self.span_from(start), 1617 }) 1618 } 1619 TokenKind::Await => { 1620 self.advance(); 1621 let arg = self.parse_unary_expression()?; 1622 Ok(Expr { 1623 kind: ExprKind::Await(Box::new(arg)), 1624 span: self.span_from(start), 1625 }) 1626 } 1627 _ => self.parse_postfix_expression(), 1628 } 1629 } 1630 1631 fn parse_postfix_expression(&mut self) -> Result<Expr, ParseError> { 1632 let start = self.start_span(); 1633 let mut expr = self.parse_call_expression()?; 1634 1635 if !self.peek().preceded_by_newline { 1636 if matches!(self.peek_kind(), TokenKind::PlusPlus) { 1637 self.advance(); 1638 expr = Expr { 1639 kind: ExprKind::Update { 1640 op: UpdateOp::Increment, 1641 argument: Box::new(expr), 1642 prefix: false, 1643 }, 1644 span: self.span_from(start), 1645 }; 1646 } else if matches!(self.peek_kind(), TokenKind::MinusMinus) { 1647 self.advance(); 1648 expr = Expr { 1649 kind: ExprKind::Update { 1650 op: UpdateOp::Decrement, 1651 argument: Box::new(expr), 1652 prefix: false, 1653 }, 1654 span: self.span_from(start), 1655 }; 1656 } 1657 } 1658 1659 Ok(expr) 1660 } 1661 1662 fn parse_call_expression(&mut self) -> Result<Expr, ParseError> { 1663 let start = self.start_span(); 1664 1665 if matches!(self.peek_kind(), TokenKind::New) { 1666 return self.parse_new_expression(); 1667 } 1668 1669 let mut expr = self.parse_primary_expression()?; 1670 1671 loop { 1672 match self.peek_kind() { 1673 TokenKind::Dot => { 1674 self.advance(); 1675 let prop_start = self.start_span(); 1676 let name = self.expect_identifier()?; 1677 expr = Expr { 1678 kind: ExprKind::Member { 1679 object: Box::new(expr), 1680 property: Box::new(Expr { 1681 kind: ExprKind::Identifier(name), 1682 span: self.span_from(prop_start), 1683 }), 1684 computed: false, 1685 }, 1686 span: self.span_from(start), 1687 }; 1688 } 1689 TokenKind::LBracket => { 1690 self.advance(); 1691 let prop = self.parse_expression()?; 1692 self.expect(&TokenKind::RBracket)?; 1693 expr = Expr { 1694 kind: ExprKind::Member { 1695 object: Box::new(expr), 1696 property: Box::new(prop), 1697 computed: true, 1698 }, 1699 span: self.span_from(start), 1700 }; 1701 } 1702 TokenKind::LParen => { 1703 let arguments = self.parse_arguments()?; 1704 expr = Expr { 1705 kind: ExprKind::Call { 1706 callee: Box::new(expr), 1707 arguments, 1708 }, 1709 span: self.span_from(start), 1710 }; 1711 } 1712 TokenKind::QuestionDot => { 1713 self.advance(); 1714 // ?. can be followed by identifier, [expr], or (args) 1715 match self.peek_kind() { 1716 TokenKind::LBracket => { 1717 self.advance(); 1718 let prop = self.parse_expression()?; 1719 self.expect(&TokenKind::RBracket)?; 1720 expr = Expr { 1721 kind: ExprKind::Member { 1722 object: Box::new(Expr { 1723 kind: ExprKind::OptionalChain { 1724 base: Box::new(expr.clone()), 1725 }, 1726 span: self.span_from(start), 1727 }), 1728 property: Box::new(prop), 1729 computed: true, 1730 }, 1731 span: self.span_from(start), 1732 }; 1733 } 1734 TokenKind::LParen => { 1735 let arguments = self.parse_arguments()?; 1736 expr = Expr { 1737 kind: ExprKind::Call { 1738 callee: Box::new(Expr { 1739 kind: ExprKind::OptionalChain { 1740 base: Box::new(expr.clone()), 1741 }, 1742 span: self.span_from(start), 1743 }), 1744 arguments, 1745 }, 1746 span: self.span_from(start), 1747 }; 1748 } 1749 _ => { 1750 let prop_start = self.start_span(); 1751 let name = self.expect_identifier()?; 1752 expr = Expr { 1753 kind: ExprKind::Member { 1754 object: Box::new(Expr { 1755 kind: ExprKind::OptionalChain { 1756 base: Box::new(expr.clone()), 1757 }, 1758 span: self.span_from(start), 1759 }), 1760 property: Box::new(Expr { 1761 kind: ExprKind::Identifier(name), 1762 span: self.span_from(prop_start), 1763 }), 1764 computed: false, 1765 }, 1766 span: self.span_from(start), 1767 }; 1768 } 1769 } 1770 } 1771 TokenKind::TemplateFull(_) | TokenKind::TemplateHead(_) => { 1772 let quasi = self.parse_template_literal()?; 1773 expr = Expr { 1774 kind: ExprKind::TaggedTemplate { 1775 tag: Box::new(expr), 1776 quasi: Box::new(quasi), 1777 }, 1778 span: self.span_from(start), 1779 }; 1780 } 1781 _ => break, 1782 } 1783 } 1784 1785 Ok(expr) 1786 } 1787 1788 fn parse_new_expression(&mut self) -> Result<Expr, ParseError> { 1789 let start = self.start_span(); 1790 self.expect(&TokenKind::New)?; 1791 1792 // new new Foo() → new (new Foo()) 1793 if matches!(self.peek_kind(), TokenKind::New) { 1794 let callee = self.parse_new_expression()?; 1795 return Ok(Expr { 1796 kind: ExprKind::New { 1797 callee: Box::new(callee), 1798 arguments: vec![], 1799 }, 1800 span: self.span_from(start), 1801 }); 1802 } 1803 1804 let callee = self.parse_primary_expression()?; 1805 // Allow member access on the callee 1806 let callee = self.parse_member_chain(start, callee)?; 1807 let arguments = if self.at(&TokenKind::LParen) { 1808 self.parse_arguments()? 1809 } else { 1810 vec![] 1811 }; 1812 Ok(Expr { 1813 kind: ExprKind::New { 1814 callee: Box::new(callee), 1815 arguments, 1816 }, 1817 span: self.span_from(start), 1818 }) 1819 } 1820 1821 fn parse_member_chain(&mut self, start: SourcePos, mut expr: Expr) -> Result<Expr, ParseError> { 1822 loop { 1823 match self.peek_kind() { 1824 TokenKind::Dot => { 1825 self.advance(); 1826 let prop_start = self.start_span(); 1827 let name = self.expect_identifier()?; 1828 expr = Expr { 1829 kind: ExprKind::Member { 1830 object: Box::new(expr), 1831 property: Box::new(Expr { 1832 kind: ExprKind::Identifier(name), 1833 span: self.span_from(prop_start), 1834 }), 1835 computed: false, 1836 }, 1837 span: self.span_from(start), 1838 }; 1839 } 1840 TokenKind::LBracket => { 1841 self.advance(); 1842 let prop = self.parse_expression()?; 1843 self.expect(&TokenKind::RBracket)?; 1844 expr = Expr { 1845 kind: ExprKind::Member { 1846 object: Box::new(expr), 1847 property: Box::new(prop), 1848 computed: true, 1849 }, 1850 span: self.span_from(start), 1851 }; 1852 } 1853 _ => break, 1854 } 1855 } 1856 Ok(expr) 1857 } 1858 1859 fn parse_left_hand_side_expression(&mut self) -> Result<Expr, ParseError> { 1860 self.parse_call_expression() 1861 } 1862 1863 fn parse_arguments(&mut self) -> Result<Vec<Expr>, ParseError> { 1864 self.expect(&TokenKind::LParen)?; 1865 let mut args = Vec::new(); 1866 while !self.at(&TokenKind::RParen) && !self.at_eof() { 1867 if self.at(&TokenKind::Ellipsis) { 1868 let start = self.start_span(); 1869 self.advance(); 1870 let arg = self.parse_assignment_expression()?; 1871 args.push(Expr { 1872 kind: ExprKind::Spread(Box::new(arg)), 1873 span: self.span_from(start), 1874 }); 1875 } else { 1876 args.push(self.parse_assignment_expression()?); 1877 } 1878 if !self.eat(&TokenKind::Comma) { 1879 break; 1880 } 1881 } 1882 self.expect(&TokenKind::RParen)?; 1883 Ok(args) 1884 } 1885 1886 // ── Primary expressions ───────────────────────────────── 1887 1888 fn parse_primary_expression(&mut self) -> Result<Expr, ParseError> { 1889 let start = self.start_span(); 1890 match self.peek_kind().clone() { 1891 TokenKind::Number(n) => { 1892 self.advance(); 1893 Ok(Expr { 1894 kind: ExprKind::Number(n), 1895 span: self.span_from(start), 1896 }) 1897 } 1898 TokenKind::String(s) => { 1899 self.advance(); 1900 Ok(Expr { 1901 kind: ExprKind::String(s), 1902 span: self.span_from(start), 1903 }) 1904 } 1905 TokenKind::True => { 1906 self.advance(); 1907 Ok(Expr { 1908 kind: ExprKind::Bool(true), 1909 span: self.span_from(start), 1910 }) 1911 } 1912 TokenKind::False => { 1913 self.advance(); 1914 Ok(Expr { 1915 kind: ExprKind::Bool(false), 1916 span: self.span_from(start), 1917 }) 1918 } 1919 TokenKind::Null => { 1920 self.advance(); 1921 Ok(Expr { 1922 kind: ExprKind::Null, 1923 span: self.span_from(start), 1924 }) 1925 } 1926 TokenKind::This => { 1927 self.advance(); 1928 Ok(Expr { 1929 kind: ExprKind::This, 1930 span: self.span_from(start), 1931 }) 1932 } 1933 TokenKind::Identifier(name) => { 1934 self.advance(); 1935 Ok(Expr { 1936 kind: ExprKind::Identifier(name), 1937 span: self.span_from(start), 1938 }) 1939 } 1940 TokenKind::LParen => self.parse_parenthesized_expression(), 1941 TokenKind::LBracket => self.parse_array_expression(), 1942 TokenKind::LBrace => self.parse_object_expression(), 1943 TokenKind::Function => self.parse_function_expression(), 1944 TokenKind::Class => self.parse_class_expression(), 1945 TokenKind::Async => { 1946 // async function expression 1947 if matches!(self.peek_ahead(1), TokenKind::Function) 1948 && !self.tokens[self.pos + 1].preceded_by_newline 1949 { 1950 return self.parse_async_function_expression(); 1951 } 1952 // Otherwise treat 'async' as an identifier 1953 self.advance(); 1954 Ok(Expr { 1955 kind: ExprKind::Identifier("async".into()), 1956 span: self.span_from(start), 1957 }) 1958 } 1959 TokenKind::TemplateFull(_) | TokenKind::TemplateHead(_) => { 1960 self.parse_template_literal() 1961 } 1962 TokenKind::RegExp { pattern, flags } => { 1963 self.advance(); 1964 Ok(Expr { 1965 kind: ExprKind::RegExp { pattern, flags }, 1966 span: self.span_from(start), 1967 }) 1968 } 1969 TokenKind::Yield => { 1970 self.advance(); 1971 let delegate = self.eat(&TokenKind::Star); 1972 let argument = if !self.peek().preceded_by_newline 1973 && !matches!( 1974 self.peek_kind(), 1975 TokenKind::Semicolon 1976 | TokenKind::RBrace 1977 | TokenKind::RParen 1978 | TokenKind::RBracket 1979 | TokenKind::Colon 1980 | TokenKind::Comma 1981 | TokenKind::Eof 1982 ) { 1983 Some(Box::new(self.parse_assignment_expression()?)) 1984 } else { 1985 None 1986 }; 1987 Ok(Expr { 1988 kind: ExprKind::Yield { argument, delegate }, 1989 span: self.span_from(start), 1990 }) 1991 } 1992 TokenKind::Super => { 1993 self.advance(); 1994 Ok(Expr { 1995 kind: ExprKind::Identifier("super".into()), 1996 span: self.span_from(start), 1997 }) 1998 } 1999 TokenKind::Import => { 2000 // import() call expression 2001 self.advance(); 2002 Ok(Expr { 2003 kind: ExprKind::Identifier("import".into()), 2004 span: self.span_from(start), 2005 }) 2006 } 2007 _ => Err(self.error(format!("unexpected token {:?}", self.peek_kind()))), 2008 } 2009 } 2010 2011 fn parse_parenthesized_expression(&mut self) -> Result<Expr, ParseError> { 2012 let start = self.start_span(); 2013 self.expect(&TokenKind::LParen)?; 2014 2015 // Empty parens: `() => ...` 2016 if self.at(&TokenKind::RParen) { 2017 self.advance(); 2018 // Must be arrow 2019 if !matches!(self.peek_kind(), TokenKind::Arrow) { 2020 return Err(self.error("unexpected empty parentheses".into())); 2021 } 2022 // Arrow will be handled by caller 2023 return Ok(Expr { 2024 kind: ExprKind::Sequence(vec![]), 2025 span: self.span_from(start), 2026 }); 2027 } 2028 2029 // `(...rest) => ...` 2030 if self.at(&TokenKind::Ellipsis) { 2031 // This must be an arrow parameter list with rest 2032 let rest_start = self.start_span(); 2033 self.advance(); 2034 let rest_pat = self.parse_binding_pattern()?; 2035 self.expect(&TokenKind::RParen)?; 2036 // Must be followed by => 2037 if !matches!(self.peek_kind(), TokenKind::Arrow) { 2038 return Err(self.error("expected '=>'".into())); 2039 } 2040 let _ = rest_pat; // Will be handled as pattern 2041 // Return a marker that the arrow handler will convert 2042 return Ok(Expr { 2043 kind: ExprKind::Spread(Box::new(Expr { 2044 kind: match rest_pat.kind { 2045 PatternKind::Identifier(name) => ExprKind::Identifier(name), 2046 _ => { 2047 return Err(ParseError { 2048 message: "complex rest pattern in arrow".into(), 2049 pos: rest_start, 2050 }) 2051 } 2052 }, 2053 span: rest_pat.span, 2054 })), 2055 span: self.span_from(start), 2056 }); 2057 } 2058 2059 let expr = self.parse_expression()?; 2060 self.expect(&TokenKind::RParen)?; 2061 Ok(expr) 2062 } 2063 2064 fn parse_array_expression(&mut self) -> Result<Expr, ParseError> { 2065 let start = self.start_span(); 2066 self.expect(&TokenKind::LBracket)?; 2067 let mut elements = Vec::new(); 2068 while !self.at(&TokenKind::RBracket) && !self.at_eof() { 2069 if self.eat(&TokenKind::Comma) { 2070 elements.push(None); 2071 continue; 2072 } 2073 if self.at(&TokenKind::Ellipsis) { 2074 let spread_start = self.start_span(); 2075 self.advance(); 2076 let arg = self.parse_assignment_expression()?; 2077 elements.push(Some(ArrayElement::Spread(Expr { 2078 kind: ExprKind::Spread(Box::new(arg)), 2079 span: self.span_from(spread_start), 2080 }))); 2081 } else { 2082 let elem = self.parse_assignment_expression()?; 2083 elements.push(Some(ArrayElement::Expr(elem))); 2084 } 2085 if !self.eat(&TokenKind::Comma) { 2086 break; 2087 } 2088 } 2089 self.expect(&TokenKind::RBracket)?; 2090 Ok(Expr { 2091 kind: ExprKind::Array(elements), 2092 span: self.span_from(start), 2093 }) 2094 } 2095 2096 fn parse_object_expression(&mut self) -> Result<Expr, ParseError> { 2097 let start = self.start_span(); 2098 self.expect(&TokenKind::LBrace)?; 2099 let mut properties = Vec::new(); 2100 while !self.at(&TokenKind::RBrace) && !self.at_eof() { 2101 let prop = self.parse_object_property()?; 2102 properties.push(prop); 2103 if !self.eat(&TokenKind::Comma) { 2104 break; 2105 } 2106 } 2107 self.expect(&TokenKind::RBrace)?; 2108 Ok(Expr { 2109 kind: ExprKind::Object(properties), 2110 span: self.span_from(start), 2111 }) 2112 } 2113 2114 fn parse_object_property(&mut self) -> Result<Property, ParseError> { 2115 let prop_start = self.start_span(); 2116 2117 // Spread: `...expr` 2118 if self.at(&TokenKind::Ellipsis) { 2119 self.advance(); 2120 let arg = self.parse_assignment_expression()?; 2121 return Ok(Property { 2122 key: PropertyKey::Identifier("".into()), 2123 value: Some(arg), 2124 kind: PropertyKind::Init, 2125 computed: false, 2126 shorthand: false, 2127 method: false, 2128 span: self.span_from(prop_start), 2129 }); 2130 } 2131 2132 // Getter/setter: `get name() {}` or `set name(v) {}` 2133 if let TokenKind::Identifier(ref name) = self.peek_kind().clone() { 2134 if (name == "get" || name == "set") 2135 && !matches!( 2136 self.peek_ahead(1), 2137 TokenKind::Colon 2138 | TokenKind::Comma 2139 | TokenKind::RBrace 2140 | TokenKind::LParen 2141 | TokenKind::Assign 2142 ) 2143 { 2144 let kind = if name == "get" { 2145 PropertyKind::Get 2146 } else { 2147 PropertyKind::Set 2148 }; 2149 self.advance(); 2150 let (key, computed) = self.parse_property_name()?; 2151 let (params, body) = self.parse_function_params_and_body()?; 2152 return Ok(Property { 2153 key, 2154 value: Some(Expr { 2155 kind: ExprKind::Function(FunctionDef { 2156 id: None, 2157 params, 2158 body, 2159 is_async: false, 2160 is_generator: false, 2161 }), 2162 span: self.span_from(prop_start), 2163 }), 2164 kind, 2165 computed, 2166 shorthand: false, 2167 method: true, 2168 span: self.span_from(prop_start), 2169 }); 2170 } 2171 } 2172 2173 // Generator method: `*name() {}` 2174 if self.eat(&TokenKind::Star) { 2175 let (key, computed) = self.parse_property_name()?; 2176 let (params, body) = self.parse_function_params_and_body()?; 2177 return Ok(Property { 2178 key, 2179 value: Some(Expr { 2180 kind: ExprKind::Function(FunctionDef { 2181 id: None, 2182 params, 2183 body, 2184 is_async: false, 2185 is_generator: true, 2186 }), 2187 span: self.span_from(prop_start), 2188 }), 2189 kind: PropertyKind::Init, 2190 computed, 2191 shorthand: false, 2192 method: true, 2193 span: self.span_from(prop_start), 2194 }); 2195 } 2196 2197 // Async method: `async name() {}` 2198 let is_async = if matches!(self.peek_kind(), TokenKind::Async) 2199 && !matches!( 2200 self.peek_ahead(1), 2201 TokenKind::Colon | TokenKind::Comma | TokenKind::RBrace | TokenKind::Assign 2202 ) 2203 && !self 2204 .tokens 2205 .get(self.pos + 1) 2206 .is_none_or(|t| t.preceded_by_newline) 2207 { 2208 self.advance(); 2209 true 2210 } else { 2211 false 2212 }; 2213 2214 let is_generator = is_async && self.eat(&TokenKind::Star); 2215 2216 let (key, computed) = self.parse_property_name()?; 2217 2218 // Method shorthand: `name() {}` or `name(params) {}` 2219 if self.at(&TokenKind::LParen) { 2220 let (params, body) = self.parse_function_params_and_body()?; 2221 return Ok(Property { 2222 key, 2223 value: Some(Expr { 2224 kind: ExprKind::Function(FunctionDef { 2225 id: None, 2226 params, 2227 body, 2228 is_async, 2229 is_generator, 2230 }), 2231 span: self.span_from(prop_start), 2232 }), 2233 kind: PropertyKind::Init, 2234 computed, 2235 shorthand: false, 2236 method: true, 2237 span: self.span_from(prop_start), 2238 }); 2239 } 2240 2241 // Shorthand: `{ name }` or `{ name = default }` 2242 if !computed 2243 && matches!( 2244 self.peek_kind(), 2245 TokenKind::Comma | TokenKind::RBrace | TokenKind::Assign 2246 ) 2247 { 2248 let name = match &key { 2249 PropertyKey::Identifier(n) => n.clone(), 2250 _ => return Err(self.error("expected identifier for shorthand property".into())), 2251 }; 2252 let value = if self.eat(&TokenKind::Assign) { 2253 let default = self.parse_assignment_expression()?; 2254 Some(Expr { 2255 kind: ExprKind::Assignment { 2256 op: AssignOp::Assign, 2257 left: Box::new(Expr { 2258 kind: ExprKind::Identifier(name.clone()), 2259 span: self.span_from(prop_start), 2260 }), 2261 right: Box::new(default), 2262 }, 2263 span: self.span_from(prop_start), 2264 }) 2265 } else { 2266 Some(Expr { 2267 kind: ExprKind::Identifier(name), 2268 span: self.span_from(prop_start), 2269 }) 2270 }; 2271 return Ok(Property { 2272 key, 2273 value, 2274 kind: PropertyKind::Init, 2275 computed, 2276 shorthand: true, 2277 method: false, 2278 span: self.span_from(prop_start), 2279 }); 2280 } 2281 2282 // Regular: `key: value` 2283 self.expect(&TokenKind::Colon)?; 2284 let value = self.parse_assignment_expression()?; 2285 Ok(Property { 2286 key, 2287 value: Some(value), 2288 kind: PropertyKind::Init, 2289 computed, 2290 shorthand: false, 2291 method: false, 2292 span: self.span_from(prop_start), 2293 }) 2294 } 2295 2296 fn parse_property_name(&mut self) -> Result<(PropertyKey, bool), ParseError> { 2297 match self.peek_kind().clone() { 2298 TokenKind::Identifier(name) => { 2299 self.advance(); 2300 Ok((PropertyKey::Identifier(name), false)) 2301 } 2302 TokenKind::String(s) => { 2303 self.advance(); 2304 Ok((PropertyKey::String(s), false)) 2305 } 2306 TokenKind::Number(n) => { 2307 self.advance(); 2308 Ok((PropertyKey::Number(n), false)) 2309 } 2310 TokenKind::LBracket => { 2311 self.advance(); 2312 let expr = self.parse_assignment_expression()?; 2313 self.expect(&TokenKind::RBracket)?; 2314 Ok((PropertyKey::Computed(expr), true)) 2315 } 2316 // Keywords can also be property names 2317 _ if is_keyword(self.peek_kind()) => { 2318 let name = format!("{}", self.peek_kind()); 2319 self.advance(); 2320 Ok((PropertyKey::Identifier(name), false)) 2321 } 2322 _ => Err(self.error(format!( 2323 "expected property name, found {:?}", 2324 self.peek_kind() 2325 ))), 2326 } 2327 } 2328 2329 fn parse_function_expression(&mut self) -> Result<Expr, ParseError> { 2330 let start = self.start_span(); 2331 self.expect(&TokenKind::Function)?; 2332 let is_generator = self.eat(&TokenKind::Star); 2333 let id = if let TokenKind::Identifier(_) = self.peek_kind() { 2334 Some(self.expect_identifier()?) 2335 } else { 2336 None 2337 }; 2338 let (params, body) = self.parse_function_params_and_body()?; 2339 Ok(Expr { 2340 kind: ExprKind::Function(FunctionDef { 2341 id, 2342 params, 2343 body, 2344 is_async: false, 2345 is_generator, 2346 }), 2347 span: self.span_from(start), 2348 }) 2349 } 2350 2351 fn parse_async_function_expression(&mut self) -> Result<Expr, ParseError> { 2352 let start = self.start_span(); 2353 self.expect(&TokenKind::Async)?; 2354 self.expect(&TokenKind::Function)?; 2355 let is_generator = self.eat(&TokenKind::Star); 2356 let id = if let TokenKind::Identifier(_) = self.peek_kind() { 2357 Some(self.expect_identifier()?) 2358 } else { 2359 None 2360 }; 2361 let (params, body) = self.parse_function_params_and_body()?; 2362 Ok(Expr { 2363 kind: ExprKind::Function(FunctionDef { 2364 id, 2365 params, 2366 body, 2367 is_async: true, 2368 is_generator, 2369 }), 2370 span: self.span_from(start), 2371 }) 2372 } 2373 2374 fn parse_class_expression(&mut self) -> Result<Expr, ParseError> { 2375 let start = self.start_span(); 2376 let class_def = self.parse_class(false)?; 2377 Ok(Expr { 2378 kind: ExprKind::Class(class_def), 2379 span: self.span_from(start), 2380 }) 2381 } 2382 2383 fn parse_template_literal(&mut self) -> Result<Expr, ParseError> { 2384 let start = self.start_span(); 2385 match self.peek_kind().clone() { 2386 TokenKind::TemplateFull(s) => { 2387 self.advance(); 2388 Ok(Expr { 2389 kind: ExprKind::TemplateLiteral { 2390 quasis: vec![s], 2391 expressions: vec![], 2392 }, 2393 span: self.span_from(start), 2394 }) 2395 } 2396 TokenKind::TemplateHead(s) => { 2397 self.advance(); 2398 let mut quasis = vec![s]; 2399 let mut expressions = Vec::new(); 2400 loop { 2401 expressions.push(self.parse_expression()?); 2402 match self.peek_kind().clone() { 2403 TokenKind::TemplateMiddle(s) => { 2404 self.advance(); 2405 quasis.push(s); 2406 } 2407 TokenKind::TemplateTail(s) => { 2408 self.advance(); 2409 quasis.push(s); 2410 break; 2411 } 2412 _ => { 2413 return Err(self.error("expected template continuation or tail".into())); 2414 } 2415 } 2416 } 2417 Ok(Expr { 2418 kind: ExprKind::TemplateLiteral { 2419 quasis, 2420 expressions, 2421 }, 2422 span: self.span_from(start), 2423 }) 2424 } 2425 _ => Err(self.error("expected template literal".into())), 2426 } 2427 } 2428 2429 // ── Operator tables ───────────────────────────────────── 2430 2431 fn peek_binary_op(&self) -> Option<(BinOrLogical, u8, u8)> { 2432 let kind = self.peek_kind(); 2433 let (op, left_bp, right_bp) = match kind { 2434 TokenKind::Or => (BinOrLogical::Logical(LogicalOp::Or), 2, 3), 2435 TokenKind::And => (BinOrLogical::Logical(LogicalOp::And), 4, 5), 2436 TokenKind::Nullish => (BinOrLogical::Logical(LogicalOp::Nullish), 6, 7), 2437 TokenKind::Pipe => (BinOrLogical::Binary(BinaryOp::BitOr), 8, 9), 2438 TokenKind::Caret => (BinOrLogical::Binary(BinaryOp::BitXor), 10, 11), 2439 TokenKind::Amp => (BinOrLogical::Binary(BinaryOp::BitAnd), 12, 13), 2440 TokenKind::Eq => (BinOrLogical::Binary(BinaryOp::Eq), 14, 15), 2441 TokenKind::Ne => (BinOrLogical::Binary(BinaryOp::Ne), 14, 15), 2442 TokenKind::StrictEq => (BinOrLogical::Binary(BinaryOp::StrictEq), 14, 15), 2443 TokenKind::StrictNe => (BinOrLogical::Binary(BinaryOp::StrictNe), 14, 15), 2444 TokenKind::Lt => (BinOrLogical::Binary(BinaryOp::Lt), 16, 17), 2445 TokenKind::Gt => (BinOrLogical::Binary(BinaryOp::Gt), 16, 17), 2446 TokenKind::Le => (BinOrLogical::Binary(BinaryOp::Le), 16, 17), 2447 TokenKind::Ge => (BinOrLogical::Binary(BinaryOp::Ge), 16, 17), 2448 TokenKind::Instanceof => (BinOrLogical::Binary(BinaryOp::Instanceof), 16, 17), 2449 TokenKind::In if self.allow_in => (BinOrLogical::Binary(BinaryOp::In), 16, 17), 2450 TokenKind::Shl => (BinOrLogical::Binary(BinaryOp::Shl), 18, 19), 2451 TokenKind::Shr => (BinOrLogical::Binary(BinaryOp::Shr), 18, 19), 2452 TokenKind::Ushr => (BinOrLogical::Binary(BinaryOp::Ushr), 18, 19), 2453 TokenKind::Plus => (BinOrLogical::Binary(BinaryOp::Add), 20, 21), 2454 TokenKind::Minus => (BinOrLogical::Binary(BinaryOp::Sub), 20, 21), 2455 TokenKind::Star => (BinOrLogical::Binary(BinaryOp::Mul), 22, 23), 2456 TokenKind::Slash => (BinOrLogical::Binary(BinaryOp::Div), 22, 23), 2457 TokenKind::Percent => (BinOrLogical::Binary(BinaryOp::Rem), 22, 23), 2458 TokenKind::Exp => (BinOrLogical::Binary(BinaryOp::Exp), 25, 24), // right-assoc 2459 _ => return None, 2460 }; 2461 Some((op, left_bp, right_bp)) 2462 } 2463 2464 fn peek_assign_op(&self) -> Option<AssignOp> { 2465 match self.peek_kind() { 2466 TokenKind::Assign => Some(AssignOp::Assign), 2467 TokenKind::PlusAssign => Some(AssignOp::AddAssign), 2468 TokenKind::MinusAssign => Some(AssignOp::SubAssign), 2469 TokenKind::StarAssign => Some(AssignOp::MulAssign), 2470 TokenKind::SlashAssign => Some(AssignOp::DivAssign), 2471 TokenKind::PercentAssign => Some(AssignOp::RemAssign), 2472 TokenKind::ExpAssign => Some(AssignOp::ExpAssign), 2473 TokenKind::ShlAssign => Some(AssignOp::ShlAssign), 2474 TokenKind::ShrAssign => Some(AssignOp::ShrAssign), 2475 TokenKind::UshrAssign => Some(AssignOp::UshrAssign), 2476 TokenKind::AmpAssign => Some(AssignOp::BitAndAssign), 2477 TokenKind::PipeAssign => Some(AssignOp::BitOrAssign), 2478 TokenKind::CaretAssign => Some(AssignOp::BitXorAssign), 2479 TokenKind::AndAssign => Some(AssignOp::AndAssign), 2480 TokenKind::OrAssign => Some(AssignOp::OrAssign), 2481 TokenKind::NullishAssign => Some(AssignOp::NullishAssign), 2482 _ => None, 2483 } 2484 } 2485 2486 // ── Expression ↔ Pattern conversion ───────────────────── 2487 2488 fn expr_to_pattern(&self, expr: &Expr) -> Result<Pattern, ParseError> { 2489 let span = expr.span; 2490 match &expr.kind { 2491 ExprKind::Identifier(name) => Ok(Pattern { 2492 kind: PatternKind::Identifier(name.clone()), 2493 span, 2494 }), 2495 ExprKind::Array(elements) => { 2496 let mut pats = Vec::new(); 2497 let mut rest = None; 2498 for elem in elements { 2499 match elem { 2500 None => pats.push(None), 2501 Some(ArrayElement::Spread(e)) => { 2502 if let ExprKind::Spread(inner) = &e.kind { 2503 rest = Some(Box::new(self.expr_to_pattern(inner)?)); 2504 } else { 2505 rest = Some(Box::new(self.expr_to_pattern(e)?)); 2506 } 2507 } 2508 Some(ArrayElement::Expr(e)) => { 2509 pats.push(Some(self.expr_to_pattern(e)?)); 2510 } 2511 } 2512 } 2513 Ok(Pattern { 2514 kind: PatternKind::Array { 2515 elements: pats, 2516 rest, 2517 }, 2518 span, 2519 }) 2520 } 2521 ExprKind::Object(properties) => { 2522 let mut pats = Vec::new(); 2523 let mut rest = None; 2524 for prop in properties { 2525 if prop.key == PropertyKey::Identifier("".into()) { 2526 if let Some(val) = &prop.value { 2527 // Spread property 2528 rest = Some(Box::new(self.expr_to_pattern(val)?)); 2529 } 2530 continue; 2531 } 2532 let value = if let Some(val) = &prop.value { 2533 self.expr_to_pattern(val)? 2534 } else { 2535 continue; 2536 }; 2537 pats.push(ObjectPatternProp { 2538 key: prop.key.clone(), 2539 value, 2540 computed: prop.computed, 2541 shorthand: prop.shorthand, 2542 span: prop.span, 2543 }); 2544 } 2545 Ok(Pattern { 2546 kind: PatternKind::Object { 2547 properties: pats, 2548 rest, 2549 }, 2550 span, 2551 }) 2552 } 2553 ExprKind::Assignment { 2554 op: AssignOp::Assign, 2555 left, 2556 right, 2557 } => { 2558 let left_pat = self.expr_to_pattern(left)?; 2559 Ok(Pattern { 2560 kind: PatternKind::Assign { 2561 left: Box::new(left_pat), 2562 right: right.clone(), 2563 }, 2564 span, 2565 }) 2566 } 2567 ExprKind::Spread(inner) => self.expr_to_pattern(inner), 2568 _ => Err(ParseError { 2569 message: "invalid destructuring pattern".into(), 2570 pos: span.start, 2571 }), 2572 } 2573 } 2574 2575 fn expr_to_params(&self, expr: &Expr) -> Result<Vec<Pattern>, ParseError> { 2576 match &expr.kind { 2577 ExprKind::Sequence(exprs) if exprs.is_empty() => Ok(vec![]), 2578 ExprKind::Sequence(exprs) => { 2579 let mut params = Vec::new(); 2580 for e in exprs { 2581 params.push(self.expr_to_pattern(e)?); 2582 } 2583 Ok(params) 2584 } 2585 ExprKind::Spread(inner) => { 2586 let pat = self.expr_to_pattern(inner)?; 2587 Ok(vec![pat]) 2588 } 2589 _ => { 2590 // Single expression as single parameter 2591 Ok(vec![self.expr_to_pattern(expr)?]) 2592 } 2593 } 2594 } 2595} 2596 2597// ── Helpers ───────────────────────────────────────────────── 2598 2599/// Distinguishes binary operators from logical operators in Pratt parsing. 2600enum BinOrLogical { 2601 Binary(BinaryOp), 2602 Logical(LogicalOp), 2603} 2604 2605/// Returns true if the token kind is a keyword (used for property name parsing). 2606fn is_keyword(kind: &TokenKind) -> bool { 2607 matches!( 2608 kind, 2609 TokenKind::Await 2610 | TokenKind::Break 2611 | TokenKind::Case 2612 | TokenKind::Catch 2613 | TokenKind::Class 2614 | TokenKind::Const 2615 | TokenKind::Continue 2616 | TokenKind::Debugger 2617 | TokenKind::Default 2618 | TokenKind::Delete 2619 | TokenKind::Do 2620 | TokenKind::Else 2621 | TokenKind::Export 2622 | TokenKind::Extends 2623 | TokenKind::Finally 2624 | TokenKind::For 2625 | TokenKind::Function 2626 | TokenKind::If 2627 | TokenKind::Import 2628 | TokenKind::In 2629 | TokenKind::Instanceof 2630 | TokenKind::Let 2631 | TokenKind::New 2632 | TokenKind::Of 2633 | TokenKind::Return 2634 | TokenKind::Static 2635 | TokenKind::Super 2636 | TokenKind::Switch 2637 | TokenKind::This 2638 | TokenKind::Throw 2639 | TokenKind::Try 2640 | TokenKind::Typeof 2641 | TokenKind::Var 2642 | TokenKind::Void 2643 | TokenKind::While 2644 | TokenKind::With 2645 | TokenKind::Yield 2646 | TokenKind::Async 2647 | TokenKind::True 2648 | TokenKind::False 2649 | TokenKind::Null 2650 ) 2651} 2652 2653// ── Tests ─────────────────────────────────────────────────── 2654 2655#[cfg(test)] 2656mod tests { 2657 use super::*; 2658 2659 fn parse(src: &str) -> Program { 2660 Parser::parse(src).unwrap() 2661 } 2662 2663 fn parse_expr(src: &str) -> Expr { 2664 let prog = parse(src); 2665 match &prog.body[0].kind { 2666 StmtKind::Expr(e) => e.clone(), 2667 _ => panic!("expected expression statement, got {:?}", prog.body[0].kind), 2668 } 2669 } 2670 2671 fn parse_stmt(src: &str) -> Stmt { 2672 let prog = parse(src); 2673 prog.body[0].clone() 2674 } 2675 2676 // ── Literals ──────────────────────────────────────── 2677 2678 #[test] 2679 fn test_number_literal() { 2680 let expr = parse_expr("42"); 2681 assert_eq!(expr.kind, ExprKind::Number(42.0)); 2682 } 2683 2684 #[test] 2685 fn test_string_literal() { 2686 let expr = parse_expr("\"hello\""); 2687 assert_eq!(expr.kind, ExprKind::String("hello".into())); 2688 } 2689 2690 #[test] 2691 fn test_boolean_literals() { 2692 assert_eq!(parse_expr("true").kind, ExprKind::Bool(true)); 2693 assert_eq!(parse_expr("false").kind, ExprKind::Bool(false)); 2694 } 2695 2696 #[test] 2697 fn test_null_literal() { 2698 assert_eq!(parse_expr("null").kind, ExprKind::Null); 2699 } 2700 2701 #[test] 2702 fn test_this() { 2703 assert_eq!(parse_expr("this").kind, ExprKind::This); 2704 } 2705 2706 #[test] 2707 fn test_identifier() { 2708 assert_eq!(parse_expr("foo").kind, ExprKind::Identifier("foo".into())); 2709 } 2710 2711 #[test] 2712 fn test_regexp() { 2713 let expr = parse_expr("x = /test/gi"); 2714 match &expr.kind { 2715 ExprKind::Assignment { right, .. } => { 2716 assert_eq!( 2717 right.kind, 2718 ExprKind::RegExp { 2719 pattern: "test".into(), 2720 flags: "gi".into() 2721 } 2722 ); 2723 } 2724 _ => panic!("expected assignment"), 2725 } 2726 } 2727 2728 // ── Binary expressions ────────────────────────────── 2729 2730 #[test] 2731 fn test_addition() { 2732 let expr = parse_expr("1 + 2"); 2733 match expr.kind { 2734 ExprKind::Binary { op, left, right } => { 2735 assert_eq!(op, BinaryOp::Add); 2736 assert_eq!(left.kind, ExprKind::Number(1.0)); 2737 assert_eq!(right.kind, ExprKind::Number(2.0)); 2738 } 2739 _ => panic!("expected binary"), 2740 } 2741 } 2742 2743 #[test] 2744 fn test_precedence() { 2745 // 1 + 2 * 3 should be 1 + (2 * 3) 2746 let expr = parse_expr("1 + 2 * 3"); 2747 match expr.kind { 2748 ExprKind::Binary { 2749 op: BinaryOp::Add, 2750 left, 2751 right, 2752 } => { 2753 assert_eq!(left.kind, ExprKind::Number(1.0)); 2754 match right.kind { 2755 ExprKind::Binary { 2756 op: BinaryOp::Mul, .. 2757 } => {} 2758 _ => panic!("expected multiply on right"), 2759 } 2760 } 2761 _ => panic!("expected binary add"), 2762 } 2763 } 2764 2765 #[test] 2766 fn test_exponentiation_right_assoc() { 2767 // 2 ** 3 ** 2 should be 2 ** (3 ** 2) 2768 let expr = parse_expr("2 ** 3 ** 2"); 2769 match expr.kind { 2770 ExprKind::Binary { 2771 op: BinaryOp::Exp, 2772 left, 2773 right, 2774 } => { 2775 assert_eq!(left.kind, ExprKind::Number(2.0)); 2776 match right.kind { 2777 ExprKind::Binary { 2778 op: BinaryOp::Exp, .. 2779 } => {} 2780 _ => panic!("expected exp on right"), 2781 } 2782 } 2783 _ => panic!("expected binary exp"), 2784 } 2785 } 2786 2787 #[test] 2788 fn test_comparison() { 2789 let expr = parse_expr("a === b"); 2790 match expr.kind { 2791 ExprKind::Binary { 2792 op: BinaryOp::StrictEq, 2793 .. 2794 } => {} 2795 _ => panic!("expected strict eq"), 2796 } 2797 } 2798 2799 #[test] 2800 fn test_logical_operators() { 2801 let expr = parse_expr("a && b || c"); 2802 // Should be (a && b) || c because && has higher precedence 2803 match expr.kind { 2804 ExprKind::Logical { 2805 op: LogicalOp::Or, .. 2806 } => {} 2807 _ => panic!("expected logical or"), 2808 } 2809 } 2810 2811 // ── Unary expressions ─────────────────────────────── 2812 2813 #[test] 2814 fn test_unary_minus() { 2815 let expr = parse_expr("-x"); 2816 match expr.kind { 2817 ExprKind::Unary { 2818 op: UnaryOp::Minus, 2819 argument, 2820 } => { 2821 assert_eq!(argument.kind, ExprKind::Identifier("x".into())); 2822 } 2823 _ => panic!("expected unary minus"), 2824 } 2825 } 2826 2827 #[test] 2828 fn test_typeof() { 2829 let expr = parse_expr("typeof x"); 2830 match expr.kind { 2831 ExprKind::Unary { 2832 op: UnaryOp::Typeof, 2833 .. 2834 } => {} 2835 _ => panic!("expected typeof"), 2836 } 2837 } 2838 2839 #[test] 2840 fn test_prefix_increment() { 2841 let expr = parse_expr("++x"); 2842 match expr.kind { 2843 ExprKind::Update { 2844 op: UpdateOp::Increment, 2845 prefix: true, 2846 .. 2847 } => {} 2848 _ => panic!("expected prefix increment"), 2849 } 2850 } 2851 2852 #[test] 2853 fn test_postfix_decrement() { 2854 let expr = parse_expr("x--"); 2855 match expr.kind { 2856 ExprKind::Update { 2857 op: UpdateOp::Decrement, 2858 prefix: false, 2859 .. 2860 } => {} 2861 _ => panic!("expected postfix decrement"), 2862 } 2863 } 2864 2865 // ── Conditional expression ────────────────────────── 2866 2867 #[test] 2868 fn test_ternary() { 2869 let expr = parse_expr("a ? b : c"); 2870 match expr.kind { 2871 ExprKind::Conditional { 2872 test, 2873 consequent, 2874 alternate, 2875 } => { 2876 assert_eq!(test.kind, ExprKind::Identifier("a".into())); 2877 assert_eq!(consequent.kind, ExprKind::Identifier("b".into())); 2878 assert_eq!(alternate.kind, ExprKind::Identifier("c".into())); 2879 } 2880 _ => panic!("expected conditional"), 2881 } 2882 } 2883 2884 // ── Assignment ────────────────────────────────────── 2885 2886 #[test] 2887 fn test_assignment() { 2888 let expr = parse_expr("x = 42"); 2889 match expr.kind { 2890 ExprKind::Assignment { 2891 op: AssignOp::Assign, 2892 left, 2893 right, 2894 } => { 2895 assert_eq!(left.kind, ExprKind::Identifier("x".into())); 2896 assert_eq!(right.kind, ExprKind::Number(42.0)); 2897 } 2898 _ => panic!("expected assignment"), 2899 } 2900 } 2901 2902 #[test] 2903 fn test_compound_assignment() { 2904 let expr = parse_expr("x += 1"); 2905 match expr.kind { 2906 ExprKind::Assignment { 2907 op: AssignOp::AddAssign, 2908 .. 2909 } => {} 2910 _ => panic!("expected add-assign"), 2911 } 2912 } 2913 2914 // ── Member expressions ────────────────────────────── 2915 2916 #[test] 2917 fn test_dot_access() { 2918 let expr = parse_expr("a.b"); 2919 match expr.kind { 2920 ExprKind::Member { 2921 computed: false, .. 2922 } => {} 2923 _ => panic!("expected member access"), 2924 } 2925 } 2926 2927 #[test] 2928 fn test_bracket_access() { 2929 let expr = parse_expr("a[0]"); 2930 match expr.kind { 2931 ExprKind::Member { computed: true, .. } => {} 2932 _ => panic!("expected computed member"), 2933 } 2934 } 2935 2936 // ── Call expressions ──────────────────────────────── 2937 2938 #[test] 2939 fn test_function_call() { 2940 let expr = parse_expr("foo(1, 2)"); 2941 match expr.kind { 2942 ExprKind::Call { 2943 callee, arguments, .. 2944 } => { 2945 assert_eq!(callee.kind, ExprKind::Identifier("foo".into())); 2946 assert_eq!(arguments.len(), 2); 2947 } 2948 _ => panic!("expected call"), 2949 } 2950 } 2951 2952 #[test] 2953 fn test_method_call() { 2954 let expr = parse_expr("obj.method()"); 2955 match expr.kind { 2956 ExprKind::Call { callee, .. } => match callee.kind { 2957 ExprKind::Member { .. } => {} 2958 _ => panic!("expected member callee"), 2959 }, 2960 _ => panic!("expected call"), 2961 } 2962 } 2963 2964 #[test] 2965 fn test_new_expression() { 2966 let expr = parse_expr("new Foo(1)"); 2967 match expr.kind { 2968 ExprKind::New { 2969 callee, arguments, .. 2970 } => { 2971 assert_eq!(callee.kind, ExprKind::Identifier("Foo".into())); 2972 assert_eq!(arguments.len(), 1); 2973 } 2974 _ => panic!("expected new"), 2975 } 2976 } 2977 2978 // ── Array and object literals ─────────────────────── 2979 2980 #[test] 2981 fn test_array_literal() { 2982 let expr = parse_expr("[1, 2, 3]"); 2983 match expr.kind { 2984 ExprKind::Array(elements) => { 2985 assert_eq!(elements.len(), 3); 2986 } 2987 _ => panic!("expected array"), 2988 } 2989 } 2990 2991 #[test] 2992 fn test_object_literal() { 2993 let expr = parse_expr("({a: 1, b: 2})"); 2994 match expr.kind { 2995 ExprKind::Object(props) => { 2996 assert_eq!(props.len(), 2); 2997 assert_eq!(props[0].key, PropertyKey::Identifier("a".into())); 2998 } 2999 _ => panic!("expected object"), 3000 } 3001 } 3002 3003 #[test] 3004 fn test_shorthand_property() { 3005 let expr = parse_expr("({x, y})"); 3006 match expr.kind { 3007 ExprKind::Object(props) => { 3008 assert!(props[0].shorthand); 3009 assert!(props[1].shorthand); 3010 } 3011 _ => panic!("expected object"), 3012 } 3013 } 3014 3015 #[test] 3016 fn test_computed_property() { 3017 let expr = parse_expr("({[key]: value})"); 3018 match expr.kind { 3019 ExprKind::Object(props) => { 3020 assert!(props[0].computed); 3021 } 3022 _ => panic!("expected object"), 3023 } 3024 } 3025 3026 // ── Arrow functions ───────────────────────────────── 3027 3028 #[test] 3029 fn test_arrow_single_param() { 3030 let expr = parse_expr("x => x + 1"); 3031 match expr.kind { 3032 ExprKind::Arrow { 3033 params, 3034 body: ArrowBody::Expr(_), 3035 is_async: false, 3036 } => { 3037 assert_eq!(params.len(), 1); 3038 } 3039 _ => panic!("expected arrow"), 3040 } 3041 } 3042 3043 #[test] 3044 fn test_arrow_multi_param() { 3045 let expr = parse_expr("(a, b) => a + b"); 3046 match expr.kind { 3047 ExprKind::Arrow { params, .. } => { 3048 assert_eq!(params.len(), 2); 3049 } 3050 _ => panic!("expected arrow"), 3051 } 3052 } 3053 3054 #[test] 3055 fn test_arrow_body_block() { 3056 let expr = parse_expr("() => { return 1; }"); 3057 match expr.kind { 3058 ExprKind::Arrow { 3059 body: ArrowBody::Block(stmts), 3060 .. 3061 } => { 3062 assert_eq!(stmts.len(), 1); 3063 } 3064 _ => panic!("expected arrow with block body"), 3065 } 3066 } 3067 3068 // ── Template literals ─────────────────────────────── 3069 3070 #[test] 3071 fn test_template_no_subst() { 3072 let expr = parse_expr("`hello`"); 3073 match expr.kind { 3074 ExprKind::TemplateLiteral { 3075 quasis, 3076 expressions, 3077 } => { 3078 assert_eq!(quasis, vec!["hello"]); 3079 assert!(expressions.is_empty()); 3080 } 3081 _ => panic!("expected template literal"), 3082 } 3083 } 3084 3085 #[test] 3086 fn test_template_with_subst() { 3087 let expr = parse_expr("`hello ${name}!`"); 3088 match expr.kind { 3089 ExprKind::TemplateLiteral { 3090 quasis, 3091 expressions, 3092 } => { 3093 assert_eq!(quasis, vec!["hello ", "!"]); 3094 assert_eq!(expressions.len(), 1); 3095 } 3096 _ => panic!("expected template literal"), 3097 } 3098 } 3099 3100 // ── Spread ────────────────────────────────────────── 3101 3102 #[test] 3103 fn test_spread_in_call() { 3104 let expr = parse_expr("foo(...args)"); 3105 match expr.kind { 3106 ExprKind::Call { arguments, .. } => { 3107 assert_eq!(arguments.len(), 1); 3108 assert!(matches!(arguments[0].kind, ExprKind::Spread(_))); 3109 } 3110 _ => panic!("expected call"), 3111 } 3112 } 3113 3114 // ── Variable declarations ─────────────────────────── 3115 3116 #[test] 3117 fn test_var_decl() { 3118 let stmt = parse_stmt("var x = 42;"); 3119 match stmt.kind { 3120 StmtKind::VarDecl { kind, declarators } => { 3121 assert_eq!(kind, VarKind::Var); 3122 assert_eq!(declarators.len(), 1); 3123 assert!(matches!( 3124 declarators[0].pattern.kind, 3125 PatternKind::Identifier(ref n) if n == "x" 3126 )); 3127 assert!(declarators[0].init.is_some()); 3128 } 3129 _ => panic!("expected var decl"), 3130 } 3131 } 3132 3133 #[test] 3134 fn test_const_decl() { 3135 let stmt = parse_stmt("const [a, b] = arr;"); 3136 match stmt.kind { 3137 StmtKind::VarDecl { 3138 kind: VarKind::Const, 3139 declarators, 3140 } => { 3141 assert!(matches!( 3142 declarators[0].pattern.kind, 3143 PatternKind::Array { .. } 3144 )); 3145 } 3146 _ => panic!("expected const decl"), 3147 } 3148 } 3149 3150 #[test] 3151 fn test_destructuring_object() { 3152 let stmt = parse_stmt("let { a, b: c } = obj;"); 3153 match stmt.kind { 3154 StmtKind::VarDecl { declarators, .. } => match &declarators[0].pattern.kind { 3155 PatternKind::Object { properties, .. } => { 3156 assert_eq!(properties.len(), 2); 3157 assert!(properties[0].shorthand); 3158 assert!(!properties[1].shorthand); 3159 } 3160 _ => panic!("expected object pattern"), 3161 }, 3162 _ => panic!("expected var decl"), 3163 } 3164 } 3165 3166 // ── Function declaration ──────────────────────────── 3167 3168 #[test] 3169 fn test_function_decl() { 3170 let stmt = parse_stmt("function add(a, b) { return a + b; }"); 3171 match stmt.kind { 3172 StmtKind::FunctionDecl(def) => { 3173 assert_eq!(def.id, Some("add".into())); 3174 assert_eq!(def.params.len(), 2); 3175 assert!(!def.is_async); 3176 assert!(!def.is_generator); 3177 assert_eq!(def.body.len(), 1); 3178 } 3179 _ => panic!("expected function decl"), 3180 } 3181 } 3182 3183 #[test] 3184 fn test_generator_function() { 3185 let stmt = parse_stmt("function* gen() { yield 1; }"); 3186 match stmt.kind { 3187 StmtKind::FunctionDecl(def) => { 3188 assert!(def.is_generator); 3189 } 3190 _ => panic!("expected function decl"), 3191 } 3192 } 3193 3194 #[test] 3195 fn test_async_function() { 3196 let stmt = parse_stmt("async function fetch() { await get(); }"); 3197 match stmt.kind { 3198 StmtKind::FunctionDecl(def) => { 3199 assert!(def.is_async); 3200 } 3201 _ => panic!("expected function decl"), 3202 } 3203 } 3204 3205 #[test] 3206 fn test_default_params() { 3207 let stmt = parse_stmt("function f(a, b = 10) {}"); 3208 match stmt.kind { 3209 StmtKind::FunctionDecl(def) => { 3210 assert_eq!(def.params.len(), 2); 3211 assert!(matches!(def.params[1].kind, PatternKind::Assign { .. })); 3212 } 3213 _ => panic!("expected function decl"), 3214 } 3215 } 3216 3217 #[test] 3218 fn test_rest_params() { 3219 let stmt = parse_stmt("function f(...args) {}"); 3220 match stmt.kind { 3221 StmtKind::FunctionDecl(def) => { 3222 assert_eq!(def.params.len(), 1); 3223 assert!(matches!( 3224 def.params[0].kind, 3225 PatternKind::Identifier(ref n) if n == "args" 3226 )); 3227 } 3228 _ => panic!("expected function decl"), 3229 } 3230 } 3231 3232 // ── Class declaration ─────────────────────────────── 3233 3234 #[test] 3235 fn test_class_decl() { 3236 let stmt = parse_stmt("class Foo { constructor() {} method() {} }"); 3237 match stmt.kind { 3238 StmtKind::ClassDecl(def) => { 3239 assert_eq!(def.id, Some("Foo".into())); 3240 assert_eq!(def.body.len(), 2); 3241 } 3242 _ => panic!("expected class decl"), 3243 } 3244 } 3245 3246 #[test] 3247 fn test_class_extends() { 3248 let stmt = parse_stmt("class Bar extends Foo {}"); 3249 match stmt.kind { 3250 StmtKind::ClassDecl(def) => { 3251 assert!(def.super_class.is_some()); 3252 } 3253 _ => panic!("expected class decl"), 3254 } 3255 } 3256 3257 #[test] 3258 fn test_class_getter_setter() { 3259 let stmt = parse_stmt("class C { get x() { return 1; } set x(v) {} }"); 3260 match stmt.kind { 3261 StmtKind::ClassDecl(def) => { 3262 assert_eq!(def.body.len(), 2); 3263 match &def.body[0].kind { 3264 ClassMemberKind::Method { kind, .. } => { 3265 assert_eq!(*kind, MethodKind::Get); 3266 } 3267 _ => panic!("expected getter"), 3268 } 3269 } 3270 _ => panic!("expected class decl"), 3271 } 3272 } 3273 3274 // ── Control flow statements ───────────────────────── 3275 3276 #[test] 3277 fn test_if_else() { 3278 let stmt = parse_stmt("if (x) { a(); } else { b(); }"); 3279 match stmt.kind { 3280 StmtKind::If { alternate, .. } => { 3281 assert!(alternate.is_some()); 3282 } 3283 _ => panic!("expected if"), 3284 } 3285 } 3286 3287 #[test] 3288 fn test_for_loop() { 3289 let stmt = parse_stmt("for (let i = 0; i < 10; i++) {}"); 3290 match stmt.kind { 3291 StmtKind::For { 3292 init, test, update, .. 3293 } => { 3294 assert!(init.is_some()); 3295 assert!(test.is_some()); 3296 assert!(update.is_some()); 3297 } 3298 _ => panic!("expected for"), 3299 } 3300 } 3301 3302 #[test] 3303 fn test_for_in() { 3304 let stmt = parse_stmt("for (const key in obj) {}"); 3305 assert!(matches!(stmt.kind, StmtKind::ForIn { .. })); 3306 } 3307 3308 #[test] 3309 fn test_for_of() { 3310 let stmt = parse_stmt("for (const item of arr) {}"); 3311 assert!(matches!(stmt.kind, StmtKind::ForOf { .. })); 3312 } 3313 3314 #[test] 3315 fn test_while_loop() { 3316 let stmt = parse_stmt("while (true) {}"); 3317 assert!(matches!(stmt.kind, StmtKind::While { .. })); 3318 } 3319 3320 #[test] 3321 fn test_do_while() { 3322 let stmt = parse_stmt("do {} while (true);"); 3323 assert!(matches!(stmt.kind, StmtKind::DoWhile { .. })); 3324 } 3325 3326 #[test] 3327 fn test_switch() { 3328 let stmt = parse_stmt("switch (x) { case 1: break; default: break; }"); 3329 match stmt.kind { 3330 StmtKind::Switch { cases, .. } => { 3331 assert_eq!(cases.len(), 2); 3332 assert!(cases[0].test.is_some()); 3333 assert!(cases[1].test.is_none()); // default 3334 } 3335 _ => panic!("expected switch"), 3336 } 3337 } 3338 3339 #[test] 3340 fn test_try_catch() { 3341 let stmt = parse_stmt("try { f(); } catch (e) { g(); }"); 3342 match stmt.kind { 3343 StmtKind::Try { 3344 handler, finalizer, .. 3345 } => { 3346 assert!(handler.is_some()); 3347 assert!(finalizer.is_none()); 3348 } 3349 _ => panic!("expected try"), 3350 } 3351 } 3352 3353 #[test] 3354 fn test_try_catch_finally() { 3355 let stmt = parse_stmt("try {} catch (e) {} finally {}"); 3356 match stmt.kind { 3357 StmtKind::Try { 3358 handler, finalizer, .. 3359 } => { 3360 assert!(handler.is_some()); 3361 assert!(finalizer.is_some()); 3362 } 3363 _ => panic!("expected try"), 3364 } 3365 } 3366 3367 #[test] 3368 fn test_return() { 3369 let stmt = parse_stmt("function f() { return 42; }"); 3370 match stmt.kind { 3371 StmtKind::FunctionDecl(def) => match &def.body[0].kind { 3372 StmtKind::Return(Some(expr)) => { 3373 assert_eq!(expr.kind, ExprKind::Number(42.0)); 3374 } 3375 _ => panic!("expected return"), 3376 }, 3377 _ => panic!("expected function"), 3378 } 3379 } 3380 3381 #[test] 3382 fn test_throw() { 3383 let stmt = parse_stmt("function f() { throw new Error(); }"); 3384 match stmt.kind { 3385 StmtKind::FunctionDecl(def) => { 3386 assert!(matches!(def.body[0].kind, StmtKind::Throw(_))); 3387 } 3388 _ => panic!("expected function"), 3389 } 3390 } 3391 3392 #[test] 3393 fn test_break_continue() { 3394 let prog = parse("while (true) { break; continue; }"); 3395 let while_stmt = &prog.body[0]; 3396 match &while_stmt.kind { 3397 StmtKind::While { body, .. } => match &body.kind { 3398 StmtKind::Block(stmts) => { 3399 assert!(matches!(stmts[0].kind, StmtKind::Break(None))); 3400 assert!(matches!(stmts[1].kind, StmtKind::Continue(None))); 3401 } 3402 _ => panic!("expected block"), 3403 }, 3404 _ => panic!("expected while"), 3405 } 3406 } 3407 3408 #[test] 3409 fn test_labeled_statement() { 3410 let stmt = parse_stmt("outer: for (;;) {}"); 3411 match stmt.kind { 3412 StmtKind::Labeled { label, .. } => { 3413 assert_eq!(label, "outer"); 3414 } 3415 _ => panic!("expected labeled"), 3416 } 3417 } 3418 3419 // ── Import / Export ───────────────────────────────── 3420 3421 #[test] 3422 fn test_import_default() { 3423 let stmt = parse_stmt("import foo from \"mod\";"); 3424 match stmt.kind { 3425 StmtKind::Import { specifiers, source } => { 3426 assert_eq!(source, "mod"); 3427 assert_eq!(specifiers.len(), 1); 3428 assert!(matches!(&specifiers[0], ImportSpecifier::Default(n) if n == "foo")); 3429 } 3430 _ => panic!("expected import"), 3431 } 3432 } 3433 3434 #[test] 3435 fn test_import_named() { 3436 let prog = Parser::parse_module("import { a, b as c } from \"mod\";").unwrap(); 3437 match &prog.body[0].kind { 3438 StmtKind::Import { specifiers, .. } => { 3439 assert_eq!(specifiers.len(), 2); 3440 } 3441 _ => panic!("expected import"), 3442 } 3443 } 3444 3445 #[test] 3446 fn test_import_namespace() { 3447 let prog = Parser::parse_module("import * as ns from \"mod\";").unwrap(); 3448 match &prog.body[0].kind { 3449 StmtKind::Import { specifiers, .. } => { 3450 assert!(matches!(&specifiers[0], ImportSpecifier::Namespace(n) if n == "ns")); 3451 } 3452 _ => panic!("expected import"), 3453 } 3454 } 3455 3456 #[test] 3457 fn test_export_default() { 3458 let prog = Parser::parse_module("export default 42;").unwrap(); 3459 match &prog.body[0].kind { 3460 StmtKind::Export(ExportDecl::Default(expr)) => { 3461 assert_eq!(expr.kind, ExprKind::Number(42.0)); 3462 } 3463 _ => panic!("expected export default"), 3464 } 3465 } 3466 3467 #[test] 3468 fn test_export_named() { 3469 let prog = Parser::parse_module("export { a, b as c };").unwrap(); 3470 match &prog.body[0].kind { 3471 StmtKind::Export(ExportDecl::Named { specifiers, .. }) => { 3472 assert_eq!(specifiers.len(), 2); 3473 } 3474 _ => panic!("expected export named"), 3475 } 3476 } 3477 3478 #[test] 3479 fn test_export_declaration() { 3480 let prog = Parser::parse_module("export const x = 1;").unwrap(); 3481 match &prog.body[0].kind { 3482 StmtKind::Export(ExportDecl::Declaration(_)) => {} 3483 _ => panic!("expected export declaration"), 3484 } 3485 } 3486 3487 #[test] 3488 fn test_export_default_anonymous_function() { 3489 let prog = Parser::parse_module("export default function() {}").unwrap(); 3490 match &prog.body[0].kind { 3491 StmtKind::Export(ExportDecl::Default(expr)) => { 3492 assert!(matches!(expr.kind, ExprKind::Function(ref def) if def.id.is_none())); 3493 } 3494 _ => panic!("expected export default anonymous function"), 3495 } 3496 } 3497 3498 #[test] 3499 fn test_export_default_anonymous_class() { 3500 let prog = Parser::parse_module("export default class {}").unwrap(); 3501 match &prog.body[0].kind { 3502 StmtKind::Export(ExportDecl::Default(expr)) => { 3503 assert!(matches!(expr.kind, ExprKind::Class(ref def) if def.id.is_none())); 3504 } 3505 _ => panic!("expected export default anonymous class"), 3506 } 3507 } 3508 3509 #[test] 3510 fn test_export_default_anonymous_generator() { 3511 let prog = Parser::parse_module("export default function*() {}").unwrap(); 3512 match &prog.body[0].kind { 3513 StmtKind::Export(ExportDecl::Default(expr)) => { 3514 assert!(matches!( 3515 expr.kind, 3516 ExprKind::Function(ref def) if def.id.is_none() && def.is_generator 3517 )); 3518 } 3519 _ => panic!("expected export default anonymous generator"), 3520 } 3521 } 3522 3523 // ── ASI (Automatic Semicolon Insertion) ───────────── 3524 3525 #[test] 3526 fn test_asi_newline() { 3527 let prog = parse("let x = 1\nlet y = 2"); 3528 assert_eq!(prog.body.len(), 2); 3529 } 3530 3531 #[test] 3532 fn test_asi_before_rbrace() { 3533 let stmt = parse_stmt("function f() { return 1 }"); 3534 match stmt.kind { 3535 StmtKind::FunctionDecl(def) => { 3536 assert_eq!(def.body.len(), 1); 3537 } 3538 _ => panic!("expected function"), 3539 } 3540 } 3541 3542 // ── Complex programs ──────────────────────────────── 3543 3544 #[test] 3545 fn test_fibonacci() { 3546 let src = r#" 3547 function fib(n) { 3548 if (n <= 1) return n; 3549 return fib(n - 1) + fib(n - 2); 3550 } 3551 "#; 3552 let prog = parse(src); 3553 assert_eq!(prog.body.len(), 1); 3554 assert!(matches!(prog.body[0].kind, StmtKind::FunctionDecl(_))); 3555 } 3556 3557 #[test] 3558 fn test_class_with_methods() { 3559 let src = r#" 3560 class Animal { 3561 constructor(name) { 3562 this.name = name; 3563 } 3564 speak() { 3565 return this.name; 3566 } 3567 static create(name) { 3568 return new Animal(name); 3569 } 3570 } 3571 "#; 3572 let prog = parse(src); 3573 assert_eq!(prog.body.len(), 1); 3574 match &prog.body[0].kind { 3575 StmtKind::ClassDecl(def) => { 3576 assert_eq!(def.body.len(), 3); 3577 } 3578 _ => panic!("expected class"), 3579 } 3580 } 3581 3582 #[test] 3583 fn test_for_of_destructuring() { 3584 let stmt = parse_stmt("for (const [k, v] of map) {}"); 3585 match stmt.kind { 3586 StmtKind::ForOf { left, .. } => match left { 3587 ForInOfLeft::VarDecl { pattern, .. } => { 3588 assert!(matches!(pattern.kind, PatternKind::Array { .. })); 3589 } 3590 _ => panic!("expected var decl"), 3591 }, 3592 _ => panic!("expected for-of"), 3593 } 3594 } 3595 3596 #[test] 3597 fn test_multiple_statements() { 3598 let src = "let x = 1; let y = 2; x + y;"; 3599 let prog = parse(src); 3600 assert_eq!(prog.body.len(), 3); 3601 } 3602 3603 // ── Error cases ───────────────────────────────────── 3604 3605 #[test] 3606 fn test_error_unexpected_token() { 3607 assert!(Parser::parse(")").is_err()); 3608 } 3609 3610 #[test] 3611 fn test_error_unterminated_block() { 3612 assert!(Parser::parse("{ let x = 1;").is_err()); 3613 } 3614 3615 #[test] 3616 fn test_error_missing_paren() { 3617 assert!(Parser::parse("if x {}").is_err()); 3618 } 3619}