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