1use alloc::boxed::Box;
9use alloc::string::String;
10use alloc::vec::Vec;
11
12use super::ast::*;
13use super::lexer::{Lexer, Token};
14
15#[derive(Debug, Clone, PartialEq)]
24pub struct ParseError {
25 pub message: String,
27 pub token_index: usize,
29}
30
31const MAX_RECORDED_ERRORS: usize = 64;
33
34fn describe_token(t: &Token) -> String {
36 match t {
37 Token::Keyword(k) => alloc::format!("keyword '{}'", k),
38 Token::Ident(i) => alloc::format!("identifier '{}'", i),
39 Token::Num(n) => alloc::format!("number {}", n),
40 Token::BigIntLit(s) => alloc::format!("bigint {}", s),
41 Token::Str(_) => String::from("string literal"),
42 Token::Template(_) => String::from("template literal"),
43 Token::Sym(s) => alloc::format!("'{}'", s),
44 Token::Regex(_, _) => String::from("regex literal"),
45 Token::Eof => String::from("end of input"),
46 }
47}
48
49pub struct Parser {
50 toks: Vec<Token>,
51 pos: usize,
52 errors: Vec<ParseError>,
54 error_count: usize,
56}
57
58impl Parser {
59 pub fn new(mut lexer: Lexer) -> Self {
60 let mut toks = Vec::new();
61 loop {
62 let t = lexer.next_token();
63 let eof = t == Token::Eof;
64 toks.push(t);
65 if eof {
66 break;
67 }
68 }
69 let lex_error_count = lexer.error_count();
72 let mut errors: Vec<ParseError> = lexer
73 .take_errors()
74 .into_iter()
75 .map(|e| ParseError {
76 message: e.message,
77 token_index: 0,
78 })
79 .collect();
80 errors.truncate(MAX_RECORDED_ERRORS);
81 Self {
82 toks,
83 pos: 0,
84 errors,
85 error_count: lex_error_count,
86 }
87 }
88
89 pub fn errors(&self) -> &[ParseError] {
91 &self.errors
92 }
93
94 pub fn error_count(&self) -> usize {
96 self.error_count
97 }
98
99 pub fn take_errors(&mut self) -> Vec<ParseError> {
101 core::mem::take(&mut self.errors)
102 }
103
104 fn record_error(&mut self, message: String) {
105 self.error_count += 1;
106 if self.errors.len() < MAX_RECORDED_ERRORS {
107 let msg = alloc::format!("{} 付近: {}", message, self.context_around(self.pos));
114 self.errors.push(ParseError {
115 message: msg,
116 token_index: self.pos,
117 });
118 }
119 }
120
121 fn context_around(&self, at: usize) -> String {
125 let start = at.saturating_sub(6);
126 let end = (at + 4).min(self.toks.len());
127 let mut out = String::new();
128 for i in start..end {
129 let Some(t) = self.toks.get(i) else {
130 break;
131 };
132 if i == at {
133 out.push_str("»");
134 out.push_str(&describe_token(t));
135 out.push_str("«");
136 } else {
137 out.push_str(&describe_token(t));
138 }
139 out.push(' ');
140 }
141 out
142 }
143
144 fn absorb_errors(&mut self, mut sub: Parser) {
148 let count = sub.error_count();
149 if count == 0 {
150 return;
151 }
152 for e in sub.take_errors() {
153 self.record_error(alloc::format!("in template expression: {}", e.message));
154 }
155 if count > MAX_RECORDED_ERRORS {
157 self.error_count += count - MAX_RECORDED_ERRORS;
158 }
159 }
160
161 fn cur(&self) -> &Token {
163 self.toks.get(self.pos).unwrap_or(&Token::Eof)
164 }
165 fn at(&self, off: usize) -> &Token {
166 self.toks.get(self.pos + off).unwrap_or(&Token::Eof)
167 }
168 fn bump(&mut self) -> Token {
169 let t = self.cur().clone();
170 if self.pos < self.toks.len() {
171 self.pos += 1;
172 }
173 t
174 }
175 fn is_eof(&self) -> bool {
176 matches!(self.cur(), Token::Eof)
177 }
178 fn is_sym(&self, s: &str) -> bool {
179 matches!(self.cur(), Token::Sym(x) if x == s)
180 }
181 fn sym_at(&self, off: usize, s: &str) -> bool {
182 matches!(self.at(off), Token::Sym(x) if x == s)
183 }
184 fn ident_at(&self, off: usize, s: &str) -> bool {
185 matches!(self.at(off), Token::Ident(x) if x == s)
186 }
187 fn kw_at(&self, off: usize, k: &str) -> bool {
188 matches!(self.at(off), Token::Keyword(x) if x == k)
189 }
190 fn is_property_key_token(&self, off: usize) -> bool {
193 matches!(
194 self.at(off),
195 Token::Ident(_) | Token::Keyword(_) | Token::Str(_) | Token::Num(_)
196 )
197 }
198 fn eat_sym(&mut self, s: &str) -> bool {
199 if self.is_sym(s) {
200 self.pos += 1;
201 true
202 } else {
203 false
204 }
205 }
206 fn expect_sym(&mut self, s: &str) {
209 if !self.eat_sym(s) {
210 let found = describe_token(self.cur());
211 self.record_error(alloc::format!("expected '{}' but found {}", s, found));
212 }
213 }
214 fn is_kw(&self, k: &str) -> bool {
215 matches!(self.cur(), Token::Keyword(x) if x == k)
216 }
217 fn eat_kw(&mut self, k: &str) -> bool {
218 if self.is_kw(k) {
219 self.pos += 1;
220 true
221 } else {
222 false
223 }
224 }
225 fn ident_name(&mut self) -> Option<String> {
226 match self.cur().clone() {
227 Token::Ident(n) => {
228 self.pos += 1;
229 Some(n)
230 }
231 Token::Keyword(n) => {
233 self.pos += 1;
234 Some(n)
235 }
236 _ => None,
237 }
238 }
239
240 pub fn parse_program(&mut self) -> Program {
242 let mut body = Vec::new();
243 while !self.is_eof() {
244 let before = self.pos;
245 if let Some(stmt) = self.parse_statement() {
246 body.push(stmt);
247 }
248 if self.pos == before {
251 let found = describe_token(self.cur());
252 self.record_error(alloc::format!("unexpected {}", found));
253 self.pos += 1;
254 }
255 }
256 Program { body }
257 }
258
259 pub fn parse_program_reporting(&mut self) -> (Program, Vec<ParseError>) {
264 let program = self.parse_program();
265 let errors = self.take_errors();
266 (program, errors)
267 }
268
269 fn parse_statement(&mut self) -> Option<Statement> {
271 if self.eat_sym(";") {
273 return Some(Statement::Empty);
274 }
275 if self.is_sym("{") {
276 return Some(self.parse_block());
277 }
278
279 if self.ident_at(0, "using")
283 && matches!(self.at(1), Token::Ident(_))
284 && self.sym_at(2, "=")
285 {
286 return self.parse_using_declaration(false);
287 }
288 if self.is_kw("await")
289 && self.ident_at(1, "using")
290 && matches!(self.at(2), Token::Ident(_))
291 && self.sym_at(3, "=")
292 {
293 self.bump(); return self.parse_using_declaration(true);
295 }
296
297 if let Token::Ident(label) = self.cur().clone() {
301 if self.sym_at(1, ":") {
302 self.bump(); self.bump(); let inner = self.parse_statement().unwrap_or(Statement::Empty);
305 return Some(Statement::Labeled(label, Box::new(inner)));
306 }
307 }
308
309 match self.cur().clone() {
310 Token::Keyword(kw) => match kw.as_str() {
311 "var" | "let" | "const" => self.parse_var_declaration(),
312 "if" => self.parse_if(),
313 "while" => self.parse_while(),
314 "do" => self.parse_do_while(),
315 "for" => self.parse_for(),
316 "function" => self.parse_function_declaration(false),
317 "async" if self.kw_at(1, "function") => {
318 self.bump(); self.parse_function_declaration(true)
320 }
321 "return" => {
322 self.bump();
323 if self.is_sym(";") || self.is_sym("}") || self.is_eof() {
324 self.eat_sym(";");
325 Some(Statement::Return(None))
326 } else {
327 let e = self.parse_expression();
328 self.eat_sym(";");
329 Some(Statement::Return(Some(e)))
330 }
331 }
332 "break" => {
333 self.bump();
334 let label = if let Token::Ident(n) = self.cur().clone() {
338 self.bump();
339 Some(n)
340 } else {
341 None
342 };
343 self.eat_sym(";");
344 Some(Statement::Break(label))
345 }
346 "continue" => {
347 self.bump();
348 let label = if let Token::Ident(n) = self.cur().clone() {
349 self.bump();
350 Some(n)
351 } else {
352 None
353 };
354 self.eat_sym(";");
355 Some(Statement::Continue(label))
356 }
357 "throw" => {
358 self.bump();
359 let e = self.parse_expression();
360 self.eat_sym(";");
361 Some(Statement::Throw(e))
362 }
363 "try" => self.parse_try(),
364 "switch" => self.parse_switch(),
365 "import" => self.parse_import(),
366 "export" => self.parse_export(),
367 "class" => {
368 let cls = self.parse_class();
370 let name = if let Expression::Class { name: Some(n), .. } = &cls {
371 n.clone()
372 } else {
373 String::new()
374 };
375 self.eat_sym(";");
376 Some(Statement::VarDeclaration {
377 kind: VarKind::Let,
378 decls: alloc::vec![(Pattern::Identifier(name), Some(cls))],
379 })
380 }
381 _ => self.parse_expression_statement(),
382 },
383 _ => self.parse_expression_statement(),
384 }
385 }
386
387 fn parse_block(&mut self) -> Statement {
388 self.expect_sym("{");
389 let mut body = Vec::new();
390 while !self.is_sym("}") && !self.is_eof() {
391 let before = self.pos;
392 if let Some(s) = self.parse_statement() {
393 body.push(s);
394 }
395 if self.pos == before {
396 self.pos += 1;
397 }
398 }
399 self.expect_sym("}");
400 Statement::Block(body)
401 }
402
403 fn parse_brace_body(&mut self) -> Vec<Statement> {
405 match self.parse_block() {
406 Statement::Block(b) => b,
407 _ => Vec::new(),
408 }
409 }
410
411 fn parse_var_declaration(&mut self) -> Option<Statement> {
412 let kind = match self.bump() {
413 Token::Keyword(k) => match k.as_str() {
414 "let" => VarKind::Let,
415 "const" => VarKind::Const,
416 _ => VarKind::Var,
417 },
418 _ => VarKind::Var,
419 };
420 let mut decls = Vec::new();
421 loop {
422 if self.is_eof() || self.is_sym(";") {
423 break;
424 }
425 let pat = self.parse_pattern();
426 let init = if self.eat_sym("=") {
427 Some(self.parse_assignment())
428 } else {
429 None
430 };
431 decls.push((pat, init));
432 if !self.eat_sym(",") {
433 break;
434 }
435 }
436 self.eat_sym(";");
437 Some(Statement::VarDeclaration { kind, decls })
438 }
439
440 fn parse_using_declaration(&mut self, is_await: bool) -> Option<Statement> {
443 self.bump(); let kind = if is_await {
445 VarKind::AwaitUsing
446 } else {
447 VarKind::Using
448 };
449 let mut decls = Vec::new();
450 while let Some(name) = self.ident_name() {
451 let init = if self.eat_sym("=") {
452 Some(self.parse_assignment())
453 } else {
454 None
455 };
456 decls.push((Pattern::Identifier(name), init));
457 if !self.eat_sym(",") {
458 break;
459 }
460 }
461 self.eat_sym(";");
462 Some(Statement::VarDeclaration { kind, decls })
463 }
464
465 fn parse_if(&mut self) -> Option<Statement> {
466 self.bump(); self.expect_sym("(");
468 let test = self.parse_expression();
469 self.expect_sym(")");
470 let consequent = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
471 let alternate = if self.eat_kw("else") {
472 Some(Box::new(self.parse_statement().unwrap_or(Statement::Empty)))
473 } else {
474 None
475 };
476 Some(Statement::If {
477 test,
478 consequent,
479 alternate,
480 })
481 }
482
483 fn parse_while(&mut self) -> Option<Statement> {
484 self.bump();
485 self.expect_sym("(");
486 let test = self.parse_expression();
487 self.expect_sym(")");
488 let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
489 Some(Statement::While { test, body })
490 }
491
492 fn parse_do_while(&mut self) -> Option<Statement> {
493 self.bump(); let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
495 self.eat_kw("while");
496 self.expect_sym("(");
497 let test = self.parse_expression();
498 self.expect_sym(")");
499 self.eat_sym(";");
500 Some(Statement::DoWhile { body, test })
501 }
502
503 fn parse_for(&mut self) -> Option<Statement> {
504 self.bump(); let is_await = self.eat_kw("await");
506 self.expect_sym("(");
507
508 if self.is_kw("var") || self.is_kw("let") || self.is_kw("const") {
510 let decl_kind = match self.bump() {
511 Token::Keyword(k) => match k.as_str() {
512 "let" => VarKind::Let,
513 "const" => VarKind::Const,
514 _ => VarKind::Var,
515 },
516 _ => VarKind::Var,
517 };
518 let pat = self.parse_pattern();
519 if self.eat_kw("of") || self.is_kw("in") {
520 let of = !self.is_kw("in");
521 if !of {
522 self.bump();
523 } let object = self.parse_expression();
525 self.expect_sym(")");
526 let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
527 return Some(Statement::ForIn {
528 decl_kind: Some(decl_kind),
529 pattern: pat,
530 object,
531 body,
532 of,
533 is_await,
534 });
535 }
536 let init_expr = if self.eat_sym("=") {
538 Some(self.parse_assignment())
539 } else {
540 None
541 };
542 let mut decls = alloc::vec![(pat, init_expr)];
543 while self.eat_sym(",") {
544 let p = self.parse_pattern();
545 let i = if self.eat_sym("=") {
546 Some(self.parse_assignment())
547 } else {
548 None
549 };
550 decls.push((p, i));
551 }
552 self.eat_sym(";");
553 let init = Some(Box::new(Statement::VarDeclaration {
554 kind: decl_kind,
555 decls,
556 }));
557 return self.finish_c_for(init);
558 }
559
560 if let Token::Ident(name) = self.cur().clone() {
564 if self.kw_at(1, "of") || self.kw_at(1, "in") {
565 let of = self.kw_at(1, "of");
566 self.bump(); self.bump(); let object = self.parse_expression();
569 self.expect_sym(")");
570 let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
571 return Some(Statement::ForIn {
572 decl_kind: None,
573 pattern: Pattern::Identifier(name),
574 object,
575 body,
576 of,
577 is_await,
578 });
579 }
580 }
581
582 if self.is_sym("[") || self.is_sym("{") {
587 let save = self.pos;
588 let err_save = (self.errors.len(), self.error_count);
594 let pat = self.parse_pattern();
595 if self.eat_kw("of") || self.is_kw("in") {
596 let of = !self.is_kw("in");
597 if !of {
598 self.bump();
599 } let object = self.parse_expression();
601 self.expect_sym(")");
602 let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
603 return Some(Statement::ForIn {
604 decl_kind: None,
605 pattern: pat,
606 object,
607 body,
608 of,
609 is_await,
610 });
611 }
612 self.pos = save;
613 self.errors.truncate(err_save.0);
614 self.error_count = err_save.1;
617 }
618
619 if !self.is_kw("var") && !self.is_kw("let") && !self.is_kw("const") {
624 let save = self.pos;
625 let err_save = (self.errors.len(), self.error_count);
631 let expr = self.parse_call_member(false);
632 let is_target = matches!(expr, Expression::Member { .. } | Expression::Index { .. });
633 if is_target && (self.eat_kw("of") || self.is_kw("in")) {
634 let of = !self.is_kw("in");
635 if !of {
636 self.bump();
637 } let object = self.parse_expression();
639 self.expect_sym(")");
640 let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
641 return Some(Statement::ForIn {
642 decl_kind: None,
643 pattern: Pattern::Expr(Box::new(expr)),
644 object,
645 body,
646 of,
647 is_await,
648 });
649 }
650 self.pos = save;
651 self.errors.truncate(err_save.0);
652 self.error_count = err_save.1;
655 }
656
657 let init = if self.is_sym(";") {
659 None
660 } else {
661 let e = self.parse_expression();
662 Some(Box::new(Statement::Expression(e)))
663 };
664 self.eat_sym(";");
665 self.finish_c_for(init)
666 }
667
668 fn finish_c_for(&mut self, init: Option<Box<Statement>>) -> Option<Statement> {
669 let test = if self.is_sym(";") {
671 None
672 } else {
673 Some(self.parse_expression())
674 };
675 self.eat_sym(";");
676 let update = if self.is_sym(")") {
677 None
678 } else {
679 Some(self.parse_expression())
680 };
681 self.expect_sym(")");
682 let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
683 Some(Statement::For {
684 init,
685 test,
686 update,
687 body,
688 })
689 }
690
691 fn parse_function_declaration(&mut self, is_async: bool) -> Option<Statement> {
692 self.bump(); let is_generator = self.eat_sym("*");
694 let name = self.ident_name().unwrap_or_default();
695 let params = self.parse_param_list();
696 let body = self.parse_brace_body();
697 Some(Statement::FunctionDeclaration {
698 name,
699 params,
700 body,
701 is_async,
702 is_generator,
703 })
704 }
705
706 fn parse_try(&mut self) -> Option<Statement> {
707 self.bump(); let block = self.parse_brace_body();
709 let mut catch_param = None;
710 let mut catch_block = None;
711 let mut finally_block = None;
712 if self.eat_kw("catch") {
713 if self.eat_sym("(") {
714 catch_param = Some(self.parse_pattern());
715 self.expect_sym(")");
716 }
717 catch_block = Some(self.parse_brace_body());
718 }
719 if self.eat_kw("finally") {
720 finally_block = Some(self.parse_brace_body());
721 }
722 Some(Statement::Try {
723 block,
724 catch_param,
725 catch_block,
726 finally_block,
727 })
728 }
729
730 fn parse_module_specifier(&mut self) -> String {
732 match self.cur().clone() {
733 Token::Str(s) => {
734 self.bump();
735 s
736 }
737 _ => String::new(),
738 }
739 }
740
741 fn eat_contextual(&mut self, word: &str) -> bool {
743 if matches!(self.cur(), Token::Ident(x) if x == word) {
744 self.pos += 1;
745 true
746 } else {
747 false
748 }
749 }
750
751 fn parse_named_specifiers(&mut self) -> Vec<(String, String)> {
753 let mut out = Vec::new();
754 self.expect_sym("{");
755 while !self.is_sym("}") && !self.is_eof() {
756 let orig = self.ident_name().unwrap_or_default();
757 let local = if self.eat_contextual("as") {
758 self.ident_name().unwrap_or_default()
759 } else {
760 orig.clone()
761 };
762 out.push((orig, local));
763 if !self.eat_sym(",") {
764 break;
765 }
766 }
767 self.expect_sym("}");
768 out
769 }
770
771 fn parse_import(&mut self) -> Option<Statement> {
776 self.bump(); let mut default = None;
778 let mut namespace = None;
779 let mut named = Vec::new();
780
781 if let Token::Str(s) = self.cur().clone() {
783 self.bump();
784 self.eat_sym(";");
785 return Some(Statement::Import {
786 source: s,
787 default: None,
788 namespace: None,
789 named: Vec::new(),
790 side_effect_only: true,
791 });
792 }
793
794 if let Token::Ident(n) = self.cur().clone() {
796 self.bump();
797 default = Some(n);
798 self.eat_sym(","); }
800
801 if self.eat_sym("*") {
803 self.eat_contextual("as");
804 namespace = self.ident_name();
805 } else if self.is_sym("{") {
806 named = self.parse_named_specifiers();
808 }
809
810 self.eat_contextual("from");
811 let source = self.parse_module_specifier();
812 self.eat_sym(";");
813 Some(Statement::Import {
814 source,
815 default,
816 namespace,
817 named,
818 side_effect_only: false,
819 })
820 }
821
822 fn parse_export(&mut self) -> Option<Statement> {
827 self.bump(); if self.eat_kw("default") {
831 let expr = if self.is_kw("function") {
833 self.parse_function_expression(false)
834 } else if self.is_kw("async") && self.kw_at(1, "function") {
835 self.bump(); self.parse_function_expression(true)
837 } else if self.is_kw("class") {
838 self.parse_class()
839 } else {
840 self.parse_assignment()
841 };
842 self.eat_sym(";");
843 return Some(Statement::ExportDefault(expr));
844 }
845
846 if self.eat_sym("*") {
848 self.eat_contextual("from");
849 let source = self.parse_module_specifier();
850 self.eat_sym(";");
851 return Some(Statement::ExportAll { source });
852 }
853
854 if self.is_sym("{") {
856 let specs = self.parse_named_specifiers();
858 let source = if self.eat_contextual("from") {
859 Some(self.parse_module_specifier())
860 } else {
861 None
862 };
863 self.eat_sym(";");
864 return Some(Statement::ExportNamed {
865 specifiers: specs,
866 source,
867 });
868 }
869
870 let names = self.export_decl_names();
872 let declaration = self.parse_statement().unwrap_or(Statement::Empty);
873 Some(Statement::ExportDecl {
874 declaration: Box::new(declaration),
875 names,
876 })
877 }
878
879 fn export_decl_names(&self) -> Vec<String> {
881 let mut names = Vec::new();
882 match self.cur() {
883 Token::Keyword(k) if k == "function" => {
884 let mut off = 1;
886 if self.sym_at(off, "*") {
887 off += 1;
888 }
889 if let Token::Ident(n) = self.at(off) {
890 names.push(n.clone());
891 }
892 }
893 Token::Keyword(k) if k == "async" => {
894 let mut off = 2;
896 if self.sym_at(off, "*") {
897 off += 1;
898 }
899 if let Token::Ident(n) = self.at(off) {
900 names.push(n.clone());
901 }
902 }
903 Token::Keyword(k) if k == "class" => {
904 if let Token::Ident(n) = self.at(1) {
905 names.push(n.clone());
906 }
907 }
908 Token::Keyword(k) if k == "var" || k == "let" || k == "const" => {
909 let mut off = 1;
911 while let Token::Ident(n) = self.at(off) {
912 names.push(n.clone());
913 if self.sym_at(off + 1, ",") {
915 off += 2;
916 } else {
917 break;
918 }
919 }
920 }
921 _ => {}
922 }
923 names
924 }
925
926 fn parse_expression_statement(&mut self) -> Option<Statement> {
927 let e = self.parse_expression();
928 self.eat_sym(";");
929 Some(Statement::Expression(e))
930 }
931
932 fn parse_switch(&mut self) -> Option<Statement> {
933 self.eat_kw("switch");
934 self.expect_sym("(");
935 let discriminant = self.parse_expression();
936 self.expect_sym(")");
937 self.expect_sym("{");
938 let mut cases = Vec::new();
939 while !self.is_sym("}") && !self.is_eof() {
940 let test = if self.eat_kw("case") {
941 let t = self.parse_expression();
942 self.expect_sym(":");
943 Some(t)
944 } else if self.eat_kw("default") {
945 self.expect_sym(":");
946 None
947 } else {
948 self.bump();
950 continue;
951 };
952 let mut body = Vec::new();
954 while !self.is_kw("case")
955 && !self.is_kw("default")
956 && !self.is_sym("}")
957 && !self.is_eof()
958 {
959 let before = self.pos;
960 if let Some(s) = self.parse_statement() {
961 body.push(s);
962 }
963 if self.pos == before {
964 self.pos += 1;
965 }
966 }
967 cases.push(crate::os_lib::js::ast::SwitchCase { test, body });
968 }
969 self.expect_sym("}");
970 Some(Statement::Switch {
971 discriminant,
972 cases,
973 })
974 }
975
976 fn parse_param_list(&mut self) -> Vec<Param> {
977 let mut params = Vec::new();
978 if self.eat_sym("(") {
979 while !self.is_sym(")") && !self.is_eof() {
980 let is_rest = self.eat_sym("...");
981 let pattern = self.parse_pattern();
982 let default = if self.eat_sym("=") {
983 Some(self.parse_assignment())
984 } else {
985 None
986 };
987 params.push(Param {
988 pattern,
989 default,
990 is_rest,
991 });
992 if !self.eat_sym(",") {
993 break;
994 }
995 }
996 self.expect_sym(")");
997 }
998 params
999 }
1000
1001 fn parse_pattern(&mut self) -> Pattern {
1003 if self.is_sym("{") {
1004 return self.parse_object_pattern();
1005 }
1006 if self.is_sym("[") {
1007 return self.parse_array_pattern();
1008 }
1009 Pattern::Identifier(self.ident_name().unwrap_or_default())
1010 }
1011
1012 fn parse_object_pattern(&mut self) -> Pattern {
1013 self.expect_sym("{");
1014 let mut props = Vec::new();
1015 while !self.is_sym("}") && !self.is_eof() {
1016 if self.eat_sym("...") {
1017 let name = self.ident_name().unwrap_or_default();
1018 props.push(ObjPatProp {
1019 key: String::new(),
1020 computed_key: None,
1021 value: Pattern::Identifier(name),
1022 default: None,
1023 is_rest: true,
1024 });
1025 break; }
1027 let (key, computed_key) = if self.eat_sym("[") {
1032 let ce = self.parse_assignment();
1033 self.expect_sym("]");
1034 (String::new(), Some(ce))
1035 } else {
1036 let k = match self.cur().clone() {
1037 Token::Ident(n) => {
1038 self.bump();
1039 n
1040 }
1041 Token::Keyword(n) => {
1042 self.bump();
1043 n
1044 }
1045 Token::Str(s) => {
1046 self.bump();
1047 s
1048 }
1049 Token::Num(n) => {
1050 self.bump();
1051 super::value::fmt_number(n)
1052 }
1053 _ => break,
1054 };
1055 (k, None)
1056 };
1057 let value = if self.eat_sym(":") {
1060 self.parse_pattern()
1061 } else {
1062 Pattern::Identifier(key.clone())
1063 };
1064 let default = if self.eat_sym("=") {
1065 Some(self.parse_assignment())
1066 } else {
1067 None
1068 };
1069 props.push(ObjPatProp {
1070 key,
1071 computed_key,
1072 value,
1073 default,
1074 is_rest: false,
1075 });
1076 if !self.eat_sym(",") {
1077 break;
1078 }
1079 }
1080 self.expect_sym("}");
1081 Pattern::Object(props)
1082 }
1083
1084 fn parse_array_pattern(&mut self) -> Pattern {
1085 self.expect_sym("[");
1086 let mut elems = Vec::new();
1087 while !self.is_sym("]") && !self.is_eof() {
1088 if self.is_sym(",") {
1089 elems.push(ArrPatElem {
1091 pattern: None,
1092 default: None,
1093 is_rest: false,
1094 });
1095 self.bump();
1096 continue;
1097 }
1098 let is_rest = self.eat_sym("...");
1099 let pat = self.parse_pattern();
1100 let default = if !is_rest && self.eat_sym("=") {
1101 Some(self.parse_assignment())
1102 } else {
1103 None
1104 };
1105 elems.push(ArrPatElem {
1106 pattern: Some(pat),
1107 default,
1108 is_rest,
1109 });
1110 if is_rest {
1111 break;
1112 }
1113 if !self.eat_sym(",") {
1114 break;
1115 }
1116 }
1117 self.expect_sym("]");
1118 Pattern::Array(elems)
1119 }
1120
1121 pub fn parse_expression(&mut self) -> Expression {
1123 let first = self.parse_assignment();
1124 if !self.is_sym(",") {
1125 return first;
1126 }
1127 let mut items = alloc::vec![first];
1131 while self.eat_sym(",") {
1132 items.push(self.parse_assignment());
1133 }
1134 Expression::Sequence(items)
1135 }
1136
1137 fn parse_assignment(&mut self) -> Expression {
1138 if self.is_kw("yield") {
1140 self.bump();
1141 let delegate = self.eat_sym("*");
1142 let argument = if self.is_sym(";")
1144 || self.is_sym(")")
1145 || self.is_sym("]")
1146 || self.is_sym("}")
1147 || self.is_sym(",")
1148 || self.is_eof()
1149 {
1150 None
1151 } else {
1152 Some(Box::new(self.parse_assignment()))
1153 };
1154 return Expression::Yield { argument, delegate };
1155 }
1156 if let Some(arrow) = self.try_parse_arrow() {
1158 return arrow;
1159 }
1160 let left = self.parse_conditional();
1161 if let Token::Sym(op) = self.cur().clone() {
1162 if is_assign_op(&op) {
1163 self.bump();
1164 let value = self.parse_assignment();
1165 return Expression::Assign {
1166 op,
1167 target: Box::new(left),
1168 value: Box::new(value),
1169 };
1170 }
1171 }
1172 left
1173 }
1174
1175 fn try_parse_arrow(&mut self) -> Option<Expression> {
1176 let start = self.pos;
1177 let is_async = if self.is_kw("async") {
1179 if self.kw_at(1, "function") {
1180 return None;
1181 }
1182 self.bump();
1183 true
1184 } else {
1185 false
1186 };
1187 if let Token::Ident(name) = self.cur().clone() {
1189 if self.sym_at(1, "=>") {
1190 self.bump(); self.bump(); let body = self.parse_arrow_body();
1193 return Some(Expression::Function {
1194 name: None,
1195 params: alloc::vec![Param {
1196 pattern: Pattern::Identifier(name),
1197 default: None,
1198 is_rest: false
1199 }],
1200 body,
1201 is_arrow: true,
1202 is_async,
1203 is_generator: false,
1204 });
1205 }
1206 }
1207 if self.is_sym("(") {
1209 if let Some(close) = self.matching_paren() {
1210 if matches!(self.toks.get(close + 1), Some(Token::Sym(s)) if s == "=>") {
1211 let params = self.parse_param_list();
1212 self.expect_sym("=>");
1213 let body = self.parse_arrow_body();
1214 return Some(Expression::Function {
1215 name: None,
1216 params,
1217 body,
1218 is_arrow: true,
1219 is_async,
1220 is_generator: false,
1221 });
1222 }
1223 }
1224 }
1225 self.pos = start;
1227 None
1228 }
1229
1230 fn matching_paren(&self) -> Option<usize> {
1232 let mut depth = 0i32;
1233 let mut i = self.pos;
1234 while i < self.toks.len() {
1235 match &self.toks[i] {
1236 Token::Sym(s) if s == "(" => depth += 1,
1237 Token::Sym(s) if s == ")" => {
1238 depth -= 1;
1239 if depth == 0 {
1240 return Some(i);
1241 }
1242 }
1243 Token::Eof => return None,
1244 _ => {}
1245 }
1246 i += 1;
1247 }
1248 None
1249 }
1250
1251 fn parse_arrow_body(&mut self) -> Vec<Statement> {
1252 if self.is_sym("{") {
1253 self.parse_brace_body()
1254 } else {
1255 let e = self.parse_assignment();
1256 alloc::vec![Statement::Return(Some(e))]
1257 }
1258 }
1259
1260 fn parse_conditional(&mut self) -> Expression {
1261 let test = self.parse_binary(0);
1262 if self.eat_sym("?") {
1263 let consequent = self.parse_assignment();
1264 self.expect_sym(":");
1265 let alternate = self.parse_assignment();
1266 return Expression::Conditional {
1267 test: Box::new(test),
1268 consequent: Box::new(consequent),
1269 alternate: Box::new(alternate),
1270 };
1271 }
1272 test
1273 }
1274
1275 fn parse_binary(&mut self, min_prec: u8) -> Expression {
1276 let mut left = self.parse_unary();
1277 while let Some(op) = self.current_binop_str() {
1278 let prec = match bin_prec(&op) {
1279 Some(p) => p,
1280 None => break,
1281 };
1282 if prec < min_prec {
1283 break;
1284 }
1285 self.bump(); let next_min = if is_right_assoc(&op) { prec } else { prec + 1 };
1287 let right = self.parse_binary(next_min);
1288 left = if let Some(lop) = to_logical(&op) {
1289 Expression::Logical {
1290 op: lop,
1291 left: Box::new(left),
1292 right: Box::new(right),
1293 }
1294 } else if let Some(bop) = to_binop(&op) {
1295 Expression::Binary {
1296 op: bop,
1297 left: Box::new(left),
1298 right: Box::new(right),
1299 }
1300 } else {
1301 left
1302 };
1303 }
1304 left
1305 }
1306
1307 fn current_binop_str(&self) -> Option<String> {
1309 match self.cur() {
1310 Token::Sym(s) if bin_prec(s).is_some() => Some(s.clone()),
1311 Token::Keyword(k) if k == "instanceof" || k == "in" => Some(k.clone()),
1312 _ => None,
1313 }
1314 }
1315
1316 fn parse_unary(&mut self) -> Expression {
1317 if let Token::Sym(s) = self.cur().clone() {
1319 let uop = match s.as_str() {
1320 "!" => Some(UnaryOp::Not),
1321 "-" => Some(UnaryOp::Neg),
1322 "+" => Some(UnaryOp::Pos),
1323 "~" => Some(UnaryOp::BitNot),
1324 _ => None,
1325 };
1326 if let Some(op) = uop {
1327 self.bump();
1328 let expr = self.parse_unary();
1329 return Expression::Unary {
1330 op,
1331 expr: Box::new(expr),
1332 };
1333 }
1334 if s == "++" || s == "--" {
1335 self.bump();
1336 let target = self.parse_unary();
1337 return Expression::Update {
1338 op: s,
1339 prefix: true,
1340 target: Box::new(target),
1341 };
1342 }
1343 }
1344 if let Token::Keyword(k) = self.cur().clone() {
1345 let uop = match k.as_str() {
1346 "typeof" => Some(UnaryOp::TypeOf),
1347 "void" => Some(UnaryOp::Void),
1348 "delete" => Some(UnaryOp::Delete),
1349 _ => None,
1350 };
1351 if let Some(op) = uop {
1352 self.bump();
1353 let expr = self.parse_unary();
1354 return Expression::Unary {
1355 op,
1356 expr: Box::new(expr),
1357 };
1358 }
1359 if k == "await" {
1360 self.bump();
1361 let expr = self.parse_unary();
1362 return Expression::Await(Box::new(expr));
1363 }
1364 if k == "new" {
1365 return self.parse_new();
1366 }
1367 }
1368 self.parse_postfix()
1369 }
1370
1371 fn parse_new(&mut self) -> Expression {
1372 self.bump(); if self.is_sym(".") && self.ident_at(1, "target") {
1376 self.bump(); self.bump(); return self.parse_call_member_tail(Expression::NewTarget, true);
1379 }
1380 let callee = self.parse_call_member(false);
1382 let arguments = if self.is_sym("(") {
1383 self.parse_arguments()
1384 } else {
1385 Vec::new()
1386 };
1387 let new_expr = Expression::New {
1388 callee: Box::new(callee),
1389 arguments,
1390 };
1391 self.parse_call_member_tail(new_expr, true)
1393 }
1394
1395 fn parse_postfix(&mut self) -> Expression {
1396 let expr = self.parse_call_member(true);
1397 if let Token::Sym(s) = self.cur().clone() {
1398 if s == "++" || s == "--" {
1399 self.bump();
1400 return Expression::Update {
1401 op: s,
1402 prefix: false,
1403 target: Box::new(expr),
1404 };
1405 }
1406 }
1407 expr
1408 }
1409
1410 fn parse_call_member(&mut self, allow_call: bool) -> Expression {
1412 let expr = self.parse_primary();
1413 self.parse_call_member_tail(expr, allow_call)
1414 }
1415
1416 fn parse_call_member_tail(&mut self, mut expr: Expression, allow_call: bool) -> Expression {
1418 loop {
1419 if self.eat_sym(".") {
1420 let prop = self.ident_name().unwrap_or_default();
1421 expr = Expression::Member {
1422 object: Box::new(expr),
1423 property: prop,
1424 optional: false,
1425 };
1426 } else if self.is_sym("?.") {
1427 self.bump();
1428 if self.is_sym("(") && allow_call {
1429 let arguments = self.parse_arguments();
1430 expr = Expression::Call {
1431 callee: Box::new(expr),
1432 arguments,
1433 optional: true,
1434 };
1435 } else if self.is_sym("[") {
1436 self.bump();
1437 let index = self.parse_expression();
1438 self.expect_sym("]");
1439 expr = Expression::Index {
1440 object: Box::new(expr),
1441 index: Box::new(index),
1442 optional: true,
1443 };
1444 } else {
1445 let prop = self.ident_name().unwrap_or_default();
1446 expr = Expression::Member {
1447 object: Box::new(expr),
1448 property: prop,
1449 optional: true,
1450 };
1451 }
1452 } else if self.eat_sym("[") {
1453 let index = self.parse_expression();
1454 self.expect_sym("]");
1455 expr = Expression::Index {
1456 object: Box::new(expr),
1457 index: Box::new(index),
1458 optional: false,
1459 };
1460 } else if self.is_sym("(") && allow_call {
1461 let arguments = self.parse_arguments();
1462 expr = Expression::Call {
1463 callee: Box::new(expr),
1464 arguments,
1465 optional: false,
1466 };
1467 } else if allow_call && matches!(self.cur(), Token::Template(_)) {
1468 let parts = match self.cur().clone() {
1473 Token::Template(p) => p,
1474 _ => unreachable!(),
1475 };
1476 self.bump();
1477 let mut quasis = Vec::new();
1478 let mut raw = Vec::new();
1479 let mut exprs = Vec::new();
1480 for part in parts {
1481 match part {
1482 super::lexer::TemplatePart::Quasi(s, r) => {
1483 quasis.push(s);
1484 raw.push(r);
1485 }
1486 super::lexer::TemplatePart::Expr(src) => {
1487 let mut sub = Parser::new(Lexer::new(&src));
1488 exprs.push(sub.parse_assignment());
1489 self.absorb_errors(sub);
1492 }
1493 }
1494 }
1495 expr = Expression::TaggedTemplate {
1496 tag: Box::new(expr),
1497 quasis,
1498 raw,
1499 exprs,
1500 };
1501 } else {
1502 break;
1503 }
1504 }
1505 expr
1506 }
1507
1508 fn parse_arguments(&mut self) -> Vec<Expression> {
1509 let mut args = Vec::new();
1510 self.expect_sym("(");
1511 while !self.is_sym(")") && !self.is_eof() {
1512 if self.eat_sym("...") {
1513 args.push(Expression::Spread(Box::new(self.parse_assignment())));
1514 } else {
1515 args.push(self.parse_assignment());
1516 }
1517 if !self.eat_sym(",") {
1518 break;
1519 }
1520 }
1521 self.expect_sym(")");
1522 args
1523 }
1524
1525 fn parse_primary(&mut self) -> Expression {
1526 match self.cur().clone() {
1527 Token::Num(n) => {
1528 self.bump();
1529 Expression::Number(n)
1530 }
1531 Token::BigIntLit(s) => {
1532 self.bump();
1533 Expression::BigIntLit(s)
1534 }
1535 Token::Str(s) => {
1536 self.bump();
1537 Expression::Str(s)
1538 }
1539 Token::Regex(p, f) => {
1540 self.bump();
1541 Expression::Regex(p, f)
1542 }
1543 Token::Template(parts) => {
1544 self.bump();
1545 let mut quasis = Vec::new();
1546 let mut exprs = Vec::new();
1547 for part in parts {
1548 match part {
1549 super::lexer::TemplatePart::Quasi(s, _raw) => quasis.push(s),
1550 super::lexer::TemplatePart::Expr(src) => {
1551 let mut sub = Parser::new(Lexer::new(&src));
1555 exprs.push(sub.parse_assignment());
1556 self.absorb_errors(sub);
1559 }
1560 }
1561 }
1562 Expression::TemplateLiteral { quasis, exprs }
1563 }
1564 Token::Ident(name) => {
1565 self.bump();
1566 Expression::Identifier(name)
1567 }
1568 Token::Keyword(kw) => match kw.as_str() {
1569 "true" => {
1570 self.bump();
1571 Expression::Bool(true)
1572 }
1573 "false" => {
1574 self.bump();
1575 Expression::Bool(false)
1576 }
1577 "null" => {
1578 self.bump();
1579 Expression::Null
1580 }
1581 "undefined" => {
1582 self.bump();
1583 Expression::Undefined
1584 }
1585 "this" => {
1586 self.bump();
1587 Expression::This
1588 }
1589 "super" => {
1590 self.bump();
1591 Expression::Super
1592 }
1593 "function" => self.parse_function_expression(false),
1594 "async" if self.kw_at(1, "function") => {
1595 self.bump(); self.parse_function_expression(true)
1597 }
1598 "class" => self.parse_class(),
1599 "of" => {
1602 self.bump();
1603 Expression::Identifier(String::from("of"))
1604 }
1605 other => {
1606 let msg = alloc::format!("unexpected keyword '{}' in expression", other);
1610 self.record_error(msg);
1611 self.bump();
1612 Expression::Undefined
1613 }
1614 },
1615 Token::Sym(s) => match s.as_str() {
1616 "(" => {
1617 self.bump();
1618 let e = self.parse_expression();
1619 self.expect_sym(")");
1620 e
1621 }
1622 "[" => self.parse_array_literal(),
1623 "{" => self.parse_object_literal(),
1624 other => {
1625 let msg = alloc::format!("unexpected '{}' in expression", other);
1627 self.record_error(msg);
1628 self.bump();
1629 Expression::Undefined
1630 }
1631 },
1632 Token::Eof => Expression::Undefined,
1633 }
1634 }
1635
1636 fn parse_function_expression(&mut self, is_async: bool) -> Expression {
1637 self.bump(); let is_generator = self.eat_sym("*");
1639 let name = match self.cur().clone() {
1640 Token::Ident(n) => {
1641 self.bump();
1642 Some(n)
1643 }
1644 _ => None,
1645 };
1646 let params = self.parse_param_list();
1647 let body = self.parse_brace_body();
1648 Expression::Function {
1649 name,
1650 params,
1651 body,
1652 is_arrow: false,
1653 is_async,
1654 is_generator,
1655 }
1656 }
1657
1658 fn parse_class(&mut self) -> Expression {
1659 self.eat_kw("class");
1660 let name = match self.cur().clone() {
1661 Token::Ident(n) => {
1662 self.bump();
1663 Some(n)
1664 }
1665 _ => None,
1666 };
1667 let superclass = if self.eat_kw("extends") {
1668 Some(Box::new(self.parse_conditional()))
1669 } else {
1670 None
1671 };
1672 self.expect_sym("{");
1673 let mut members = Vec::new();
1674 while !self.is_sym("}") && !self.is_eof() {
1675 if self.eat_sym(";") {
1676 continue;
1677 }
1678 let is_static = if let Token::Ident(n) = self.cur().clone() {
1685 n == "static"
1686 && (self.is_property_key_token(1)
1687 || self.sym_at(1, "[")
1688 || self.sym_at(1, "*")
1689 || self.sym_at(1, "{"))
1690 } else {
1691 false
1692 };
1693 if is_static {
1694 self.bump();
1695 }
1696 if is_static && self.is_sym("{") {
1698 let body = self.parse_brace_body();
1699 members.push(ClassMember {
1700 key: String::new(),
1701 computed_key: None,
1702 kind: MethodKind::StaticBlock,
1703 params: Vec::new(),
1704 body,
1705 is_static: true,
1706 field_init: None,
1707 is_async: false,
1708 is_generator: false,
1709 });
1710 continue;
1711 }
1712 let async_modifier_ok =
1721 self.is_property_key_token(1) || self.sym_at(1, "[") || self.sym_at(1, "*");
1722 let is_async = self.is_kw("async") && async_modifier_ok;
1723 if is_async {
1724 self.bump();
1725 }
1726 let is_generator = self.eat_sym("*");
1727 let accessor_kind = if let Token::Ident(n) = self.cur().clone() {
1736 if (n == "get" || n == "set")
1737 && (self.sym_at(1, "[")
1738 || (self.is_property_key_token(1) && self.sym_at(2, "(")))
1739 {
1740 self.bump();
1741 Some(n == "get")
1742 } else {
1743 None
1744 }
1745 } else {
1746 None
1747 };
1748 let mut computed_key = None;
1750 let key = match self.cur().clone() {
1751 Token::Ident(n) => {
1752 self.bump();
1753 n
1754 }
1755 Token::Keyword(n) => {
1756 self.bump();
1757 n
1758 }
1759 Token::Str(s) => {
1760 self.bump();
1761 s
1762 }
1763 Token::Num(n) => {
1764 self.bump();
1765 super::value::fmt_number(n)
1766 }
1767 Token::Sym(s) if s == "[" => {
1768 self.bump();
1769 computed_key = Some(self.parse_assignment());
1770 self.expect_sym("]");
1771 String::new()
1772 }
1773 _ => {
1774 self.bump();
1775 continue;
1776 }
1777 };
1778 if self.is_sym("(") {
1779 let params = self.parse_param_list();
1781 let body = self.parse_brace_body();
1782 let kind = match accessor_kind {
1783 Some(true) => MethodKind::Getter,
1784 Some(false) => MethodKind::Setter,
1785 None if computed_key.is_none() && key == "constructor" => {
1786 MethodKind::Constructor
1787 }
1788 None => MethodKind::Method,
1789 };
1790 members.push(ClassMember {
1791 key,
1792 computed_key,
1793 kind,
1794 params,
1795 body,
1796 is_static,
1797 field_init: None,
1798 is_async,
1799 is_generator,
1800 });
1801 } else {
1802 let init = if self.eat_sym("=") {
1805 Some(self.parse_assignment())
1806 } else {
1807 None
1808 };
1809 self.eat_sym(";");
1810 members.push(ClassMember {
1811 key,
1812 computed_key: None,
1815 kind: MethodKind::Field,
1816 params: Vec::new(),
1817 body: Vec::new(),
1818 is_static,
1819 field_init: init,
1820 is_async: false,
1821 is_generator: false,
1822 });
1823 }
1824 }
1825 self.expect_sym("}");
1826 Expression::Class {
1827 name,
1828 superclass,
1829 members,
1830 }
1831 }
1832
1833 fn parse_array_literal(&mut self) -> Expression {
1834 self.expect_sym("[");
1835 let mut items = Vec::new();
1836 while !self.is_sym("]") && !self.is_eof() {
1837 if self.is_sym(",") {
1838 items.push(Expression::Undefined);
1840 self.bump();
1841 continue;
1842 }
1843 if self.eat_sym("...") {
1844 items.push(Expression::Spread(Box::new(self.parse_assignment())));
1845 } else {
1846 items.push(self.parse_assignment());
1847 }
1848 if !self.eat_sym(",") {
1849 break;
1850 }
1851 }
1852 self.expect_sym("]");
1853 Expression::Array(items)
1854 }
1855
1856 fn parse_object_literal(&mut self) -> Expression {
1857 self.expect_sym("{");
1858 let mut props = Vec::new();
1859 while !self.is_sym("}") && !self.is_eof() {
1860 if self.eat_sym("...") {
1862 let value = self.parse_assignment();
1863 props.push(Property {
1864 key: String::from(crate::os_lib::js::ast::OBJECT_SPREAD_KEY),
1865 value,
1866 computed: None,
1867 accessor: None,
1868 });
1869 if !self.eat_sym(",") {
1870 break;
1871 }
1872 continue;
1873 }
1874 let async_modifier_ok =
1881 self.is_property_key_token(1) || self.sym_at(1, "[") || self.sym_at(1, "*");
1882 let is_async = self.is_kw("async") && async_modifier_ok;
1883 if is_async {
1884 self.bump();
1885 }
1886 let is_generator = self.eat_sym("*");
1887 let accessor_kind = if let Token::Ident(n) = self.cur().clone() {
1893 if (n == "get" || n == "set")
1894 && (self.sym_at(1, "[")
1895 || (self.is_property_key_token(1) && self.sym_at(2, "(")))
1896 {
1897 self.bump();
1898 Some(n == "get")
1899 } else {
1900 None
1901 }
1902 } else {
1903 None
1904 };
1905 let mut computed = None;
1907 let key = match self.cur().clone() {
1909 Token::Ident(n) => {
1910 self.bump();
1911 n
1912 }
1913 Token::Keyword(n) => {
1914 self.bump();
1915 n
1916 }
1917 Token::Str(s) => {
1918 self.bump();
1919 s
1920 }
1921 Token::Num(n) => {
1922 self.bump();
1923 super::value::fmt_number(n)
1924 }
1925 Token::Sym(s) if s == "[" => {
1926 self.bump();
1927 computed = Some(self.parse_assignment());
1928 self.expect_sym("]");
1929 String::new()
1930 }
1931 _ => break,
1932 };
1933 let value = if self.eat_sym(":") {
1934 self.parse_assignment()
1935 } else if self.is_sym("(") {
1936 let params = self.parse_param_list();
1938 let body = self.parse_brace_body();
1939 Expression::Function {
1940 name: Some(key.clone()),
1941 params,
1942 body,
1943 is_arrow: false,
1944 is_async,
1945 is_generator,
1946 }
1947 } else {
1948 Expression::Identifier(key.clone())
1950 };
1951 props.push(Property {
1952 key,
1953 value,
1954 computed,
1955 accessor: accessor_kind,
1956 });
1957 if !self.eat_sym(",") {
1958 break;
1959 }
1960 }
1961 self.expect_sym("}");
1962 Expression::Object(props)
1963 }
1964}
1965
1966fn is_assign_op(op: &str) -> bool {
1969 matches!(
1970 op,
1971 "=" | "+="
1972 | "-="
1973 | "*="
1974 | "/="
1975 | "%="
1976 | "**="
1977 | "&="
1978 | "|="
1979 | "^="
1980 | "<<="
1981 | ">>="
1982 | ">>>="
1983 | "&&="
1984 | "||="
1985 | "??="
1986 )
1987}
1988
1989fn bin_prec(op: &str) -> Option<u8> {
1990 Some(match op {
1991 "??" => 1,
1992 "||" => 2,
1993 "&&" => 3,
1994 "|" => 4,
1995 "^" => 5,
1996 "&" => 6,
1997 "==" | "!=" | "===" | "!==" => 7,
1998 "<" | ">" | "<=" | ">=" | "instanceof" | "in" => 8,
1999 "<<" | ">>" | ">>>" => 9,
2000 "+" | "-" => 10,
2001 "*" | "/" | "%" => 11,
2002 "**" => 12,
2003 _ => return None,
2004 })
2005}
2006
2007fn is_right_assoc(op: &str) -> bool {
2008 op == "**"
2009}
2010
2011fn to_logical(op: &str) -> Option<LogicalOp> {
2012 match op {
2013 "&&" => Some(LogicalOp::And),
2014 "||" => Some(LogicalOp::Or),
2015 "??" => Some(LogicalOp::Nullish),
2016 _ => None,
2017 }
2018}
2019
2020fn to_binop(op: &str) -> Option<BinaryOp> {
2021 Some(match op {
2022 "+" => BinaryOp::Add,
2023 "-" => BinaryOp::Sub,
2024 "*" => BinaryOp::Mul,
2025 "/" => BinaryOp::Div,
2026 "%" => BinaryOp::Mod,
2027 "**" => BinaryOp::Pow,
2028 "==" => BinaryOp::Eq,
2029 "!=" => BinaryOp::NotEq,
2030 "===" => BinaryOp::StrictEq,
2031 "!==" => BinaryOp::StrictNotEq,
2032 "<" => BinaryOp::Lt,
2033 ">" => BinaryOp::Gt,
2034 "<=" => BinaryOp::LtEq,
2035 ">=" => BinaryOp::GtEq,
2036 "&" => BinaryOp::BitAnd,
2037 "|" => BinaryOp::BitOr,
2038 "^" => BinaryOp::BitXor,
2039 "<<" => BinaryOp::Shl,
2040 ">>" => BinaryOp::Shr,
2041 ">>>" => BinaryOp::UShr,
2042 "instanceof" => BinaryOp::InstanceOf,
2043 "in" => BinaryOp::In,
2044 _ => return None,
2045 })
2046}