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();
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);
614 }
615
616 if !self.is_kw("var") && !self.is_kw("let") && !self.is_kw("const") {
621 let save = self.pos;
622 let err_save = self.errors.len();
628 let expr = self.parse_call_member(false);
629 let is_target = matches!(expr, Expression::Member { .. } | Expression::Index { .. });
630 if is_target && (self.eat_kw("of") || self.is_kw("in")) {
631 let of = !self.is_kw("in");
632 if !of {
633 self.bump();
634 } let object = self.parse_expression();
636 self.expect_sym(")");
637 let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
638 return Some(Statement::ForIn {
639 decl_kind: None,
640 pattern: Pattern::Expr(Box::new(expr)),
641 object,
642 body,
643 of,
644 is_await,
645 });
646 }
647 self.pos = save;
648 self.errors.truncate(err_save);
649 }
650
651 let init = if self.is_sym(";") {
653 None
654 } else {
655 let e = self.parse_expression();
656 Some(Box::new(Statement::Expression(e)))
657 };
658 self.eat_sym(";");
659 self.finish_c_for(init)
660 }
661
662 fn finish_c_for(&mut self, init: Option<Box<Statement>>) -> Option<Statement> {
663 let test = if self.is_sym(";") {
665 None
666 } else {
667 Some(self.parse_expression())
668 };
669 self.eat_sym(";");
670 let update = if self.is_sym(")") {
671 None
672 } else {
673 Some(self.parse_expression())
674 };
675 self.expect_sym(")");
676 let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
677 Some(Statement::For {
678 init,
679 test,
680 update,
681 body,
682 })
683 }
684
685 fn parse_function_declaration(&mut self, is_async: bool) -> Option<Statement> {
686 self.bump(); let is_generator = self.eat_sym("*");
688 let name = self.ident_name().unwrap_or_default();
689 let params = self.parse_param_list();
690 let body = self.parse_brace_body();
691 Some(Statement::FunctionDeclaration {
692 name,
693 params,
694 body,
695 is_async,
696 is_generator,
697 })
698 }
699
700 fn parse_try(&mut self) -> Option<Statement> {
701 self.bump(); let block = self.parse_brace_body();
703 let mut catch_param = None;
704 let mut catch_block = None;
705 let mut finally_block = None;
706 if self.eat_kw("catch") {
707 if self.eat_sym("(") {
708 catch_param = Some(self.parse_pattern());
709 self.expect_sym(")");
710 }
711 catch_block = Some(self.parse_brace_body());
712 }
713 if self.eat_kw("finally") {
714 finally_block = Some(self.parse_brace_body());
715 }
716 Some(Statement::Try {
717 block,
718 catch_param,
719 catch_block,
720 finally_block,
721 })
722 }
723
724 fn parse_module_specifier(&mut self) -> String {
726 match self.cur().clone() {
727 Token::Str(s) => {
728 self.bump();
729 s
730 }
731 _ => String::new(),
732 }
733 }
734
735 fn eat_contextual(&mut self, word: &str) -> bool {
737 if matches!(self.cur(), Token::Ident(x) if x == word) {
738 self.pos += 1;
739 true
740 } else {
741 false
742 }
743 }
744
745 fn parse_named_specifiers(&mut self) -> Vec<(String, String)> {
747 let mut out = Vec::new();
748 self.expect_sym("{");
749 while !self.is_sym("}") && !self.is_eof() {
750 let orig = self.ident_name().unwrap_or_default();
751 let local = if self.eat_contextual("as") {
752 self.ident_name().unwrap_or_default()
753 } else {
754 orig.clone()
755 };
756 out.push((orig, local));
757 if !self.eat_sym(",") {
758 break;
759 }
760 }
761 self.expect_sym("}");
762 out
763 }
764
765 fn parse_import(&mut self) -> Option<Statement> {
770 self.bump(); let mut default = None;
772 let mut namespace = None;
773 let mut named = Vec::new();
774
775 if let Token::Str(s) = self.cur().clone() {
777 self.bump();
778 self.eat_sym(";");
779 return Some(Statement::Import {
780 source: s,
781 default: None,
782 namespace: None,
783 named: Vec::new(),
784 side_effect_only: true,
785 });
786 }
787
788 if let Token::Ident(n) = self.cur().clone() {
790 self.bump();
791 default = Some(n);
792 self.eat_sym(","); }
794
795 if self.eat_sym("*") {
797 self.eat_contextual("as");
798 namespace = self.ident_name();
799 } else if self.is_sym("{") {
800 named = self.parse_named_specifiers();
802 }
803
804 self.eat_contextual("from");
805 let source = self.parse_module_specifier();
806 self.eat_sym(";");
807 Some(Statement::Import {
808 source,
809 default,
810 namespace,
811 named,
812 side_effect_only: false,
813 })
814 }
815
816 fn parse_export(&mut self) -> Option<Statement> {
821 self.bump(); if self.eat_kw("default") {
825 let expr = if self.is_kw("function") {
827 self.parse_function_expression(false)
828 } else if self.is_kw("async") && self.kw_at(1, "function") {
829 self.bump(); self.parse_function_expression(true)
831 } else if self.is_kw("class") {
832 self.parse_class()
833 } else {
834 self.parse_assignment()
835 };
836 self.eat_sym(";");
837 return Some(Statement::ExportDefault(expr));
838 }
839
840 if self.eat_sym("*") {
842 self.eat_contextual("from");
843 let source = self.parse_module_specifier();
844 self.eat_sym(";");
845 return Some(Statement::ExportAll { source });
846 }
847
848 if self.is_sym("{") {
850 let specs = self.parse_named_specifiers();
852 let source = if self.eat_contextual("from") {
853 Some(self.parse_module_specifier())
854 } else {
855 None
856 };
857 self.eat_sym(";");
858 return Some(Statement::ExportNamed {
859 specifiers: specs,
860 source,
861 });
862 }
863
864 let names = self.export_decl_names();
866 let declaration = self.parse_statement().unwrap_or(Statement::Empty);
867 Some(Statement::ExportDecl {
868 declaration: Box::new(declaration),
869 names,
870 })
871 }
872
873 fn export_decl_names(&self) -> Vec<String> {
875 let mut names = Vec::new();
876 match self.cur() {
877 Token::Keyword(k) if k == "function" => {
878 let mut off = 1;
880 if self.sym_at(off, "*") {
881 off += 1;
882 }
883 if let Token::Ident(n) = self.at(off) {
884 names.push(n.clone());
885 }
886 }
887 Token::Keyword(k) if k == "async" => {
888 let mut off = 2;
890 if self.sym_at(off, "*") {
891 off += 1;
892 }
893 if let Token::Ident(n) = self.at(off) {
894 names.push(n.clone());
895 }
896 }
897 Token::Keyword(k) if k == "class" => {
898 if let Token::Ident(n) = self.at(1) {
899 names.push(n.clone());
900 }
901 }
902 Token::Keyword(k) if k == "var" || k == "let" || k == "const" => {
903 let mut off = 1;
905 while let Token::Ident(n) = self.at(off) {
906 names.push(n.clone());
907 if self.sym_at(off + 1, ",") {
909 off += 2;
910 } else {
911 break;
912 }
913 }
914 }
915 _ => {}
916 }
917 names
918 }
919
920 fn parse_expression_statement(&mut self) -> Option<Statement> {
921 let e = self.parse_expression();
922 self.eat_sym(";");
923 Some(Statement::Expression(e))
924 }
925
926 fn parse_switch(&mut self) -> Option<Statement> {
927 self.eat_kw("switch");
928 self.expect_sym("(");
929 let discriminant = self.parse_expression();
930 self.expect_sym(")");
931 self.expect_sym("{");
932 let mut cases = Vec::new();
933 while !self.is_sym("}") && !self.is_eof() {
934 let test = if self.eat_kw("case") {
935 let t = self.parse_expression();
936 self.expect_sym(":");
937 Some(t)
938 } else if self.eat_kw("default") {
939 self.expect_sym(":");
940 None
941 } else {
942 self.bump();
944 continue;
945 };
946 let mut body = Vec::new();
948 while !self.is_kw("case")
949 && !self.is_kw("default")
950 && !self.is_sym("}")
951 && !self.is_eof()
952 {
953 let before = self.pos;
954 if let Some(s) = self.parse_statement() {
955 body.push(s);
956 }
957 if self.pos == before {
958 self.pos += 1;
959 }
960 }
961 cases.push(crate::os_lib::js::ast::SwitchCase { test, body });
962 }
963 self.expect_sym("}");
964 Some(Statement::Switch {
965 discriminant,
966 cases,
967 })
968 }
969
970 fn parse_param_list(&mut self) -> Vec<Param> {
971 let mut params = Vec::new();
972 if self.eat_sym("(") {
973 while !self.is_sym(")") && !self.is_eof() {
974 let is_rest = self.eat_sym("...");
975 let pattern = self.parse_pattern();
976 let default = if self.eat_sym("=") {
977 Some(self.parse_assignment())
978 } else {
979 None
980 };
981 params.push(Param {
982 pattern,
983 default,
984 is_rest,
985 });
986 if !self.eat_sym(",") {
987 break;
988 }
989 }
990 self.expect_sym(")");
991 }
992 params
993 }
994
995 fn parse_pattern(&mut self) -> Pattern {
997 if self.is_sym("{") {
998 return self.parse_object_pattern();
999 }
1000 if self.is_sym("[") {
1001 return self.parse_array_pattern();
1002 }
1003 Pattern::Identifier(self.ident_name().unwrap_or_default())
1004 }
1005
1006 fn parse_object_pattern(&mut self) -> Pattern {
1007 self.expect_sym("{");
1008 let mut props = Vec::new();
1009 while !self.is_sym("}") && !self.is_eof() {
1010 if self.eat_sym("...") {
1011 let name = self.ident_name().unwrap_or_default();
1012 props.push(ObjPatProp {
1013 key: String::new(),
1014 computed_key: None,
1015 value: Pattern::Identifier(name),
1016 default: None,
1017 is_rest: true,
1018 });
1019 break; }
1021 let (key, computed_key) = if self.eat_sym("[") {
1026 let ce = self.parse_assignment();
1027 self.expect_sym("]");
1028 (String::new(), Some(ce))
1029 } else {
1030 let k = match self.cur().clone() {
1031 Token::Ident(n) => {
1032 self.bump();
1033 n
1034 }
1035 Token::Keyword(n) => {
1036 self.bump();
1037 n
1038 }
1039 Token::Str(s) => {
1040 self.bump();
1041 s
1042 }
1043 Token::Num(n) => {
1044 self.bump();
1045 super::value::fmt_number(n)
1046 }
1047 _ => break,
1048 };
1049 (k, None)
1050 };
1051 let value = if self.eat_sym(":") {
1054 self.parse_pattern()
1055 } else {
1056 Pattern::Identifier(key.clone())
1057 };
1058 let default = if self.eat_sym("=") {
1059 Some(self.parse_assignment())
1060 } else {
1061 None
1062 };
1063 props.push(ObjPatProp {
1064 key,
1065 computed_key,
1066 value,
1067 default,
1068 is_rest: false,
1069 });
1070 if !self.eat_sym(",") {
1071 break;
1072 }
1073 }
1074 self.expect_sym("}");
1075 Pattern::Object(props)
1076 }
1077
1078 fn parse_array_pattern(&mut self) -> Pattern {
1079 self.expect_sym("[");
1080 let mut elems = Vec::new();
1081 while !self.is_sym("]") && !self.is_eof() {
1082 if self.is_sym(",") {
1083 elems.push(ArrPatElem {
1085 pattern: None,
1086 default: None,
1087 is_rest: false,
1088 });
1089 self.bump();
1090 continue;
1091 }
1092 let is_rest = self.eat_sym("...");
1093 let pat = self.parse_pattern();
1094 let default = if !is_rest && self.eat_sym("=") {
1095 Some(self.parse_assignment())
1096 } else {
1097 None
1098 };
1099 elems.push(ArrPatElem {
1100 pattern: Some(pat),
1101 default,
1102 is_rest,
1103 });
1104 if is_rest {
1105 break;
1106 }
1107 if !self.eat_sym(",") {
1108 break;
1109 }
1110 }
1111 self.expect_sym("]");
1112 Pattern::Array(elems)
1113 }
1114
1115 pub fn parse_expression(&mut self) -> Expression {
1117 let first = self.parse_assignment();
1118 if !self.is_sym(",") {
1119 return first;
1120 }
1121 let mut items = alloc::vec![first];
1125 while self.eat_sym(",") {
1126 items.push(self.parse_assignment());
1127 }
1128 Expression::Sequence(items)
1129 }
1130
1131 fn parse_assignment(&mut self) -> Expression {
1132 if self.is_kw("yield") {
1134 self.bump();
1135 let delegate = self.eat_sym("*");
1136 let argument = if self.is_sym(";")
1138 || self.is_sym(")")
1139 || self.is_sym("]")
1140 || self.is_sym("}")
1141 || self.is_sym(",")
1142 || self.is_eof()
1143 {
1144 None
1145 } else {
1146 Some(Box::new(self.parse_assignment()))
1147 };
1148 return Expression::Yield { argument, delegate };
1149 }
1150 if let Some(arrow) = self.try_parse_arrow() {
1152 return arrow;
1153 }
1154 let left = self.parse_conditional();
1155 if let Token::Sym(op) = self.cur().clone() {
1156 if is_assign_op(&op) {
1157 self.bump();
1158 let value = self.parse_assignment();
1159 return Expression::Assign {
1160 op,
1161 target: Box::new(left),
1162 value: Box::new(value),
1163 };
1164 }
1165 }
1166 left
1167 }
1168
1169 fn try_parse_arrow(&mut self) -> Option<Expression> {
1170 let start = self.pos;
1171 let is_async = if self.is_kw("async") {
1173 if self.kw_at(1, "function") {
1174 return None;
1175 }
1176 self.bump();
1177 true
1178 } else {
1179 false
1180 };
1181 if let Token::Ident(name) = self.cur().clone() {
1183 if self.sym_at(1, "=>") {
1184 self.bump(); self.bump(); let body = self.parse_arrow_body();
1187 return Some(Expression::Function {
1188 name: None,
1189 params: alloc::vec![Param {
1190 pattern: Pattern::Identifier(name),
1191 default: None,
1192 is_rest: false
1193 }],
1194 body,
1195 is_arrow: true,
1196 is_async,
1197 is_generator: false,
1198 });
1199 }
1200 }
1201 if self.is_sym("(") {
1203 if let Some(close) = self.matching_paren() {
1204 if matches!(self.toks.get(close + 1), Some(Token::Sym(s)) if s == "=>") {
1205 let params = self.parse_param_list();
1206 self.expect_sym("=>");
1207 let body = self.parse_arrow_body();
1208 return Some(Expression::Function {
1209 name: None,
1210 params,
1211 body,
1212 is_arrow: true,
1213 is_async,
1214 is_generator: false,
1215 });
1216 }
1217 }
1218 }
1219 self.pos = start;
1221 None
1222 }
1223
1224 fn matching_paren(&self) -> Option<usize> {
1226 let mut depth = 0i32;
1227 let mut i = self.pos;
1228 while i < self.toks.len() {
1229 match &self.toks[i] {
1230 Token::Sym(s) if s == "(" => depth += 1,
1231 Token::Sym(s) if s == ")" => {
1232 depth -= 1;
1233 if depth == 0 {
1234 return Some(i);
1235 }
1236 }
1237 Token::Eof => return None,
1238 _ => {}
1239 }
1240 i += 1;
1241 }
1242 None
1243 }
1244
1245 fn parse_arrow_body(&mut self) -> Vec<Statement> {
1246 if self.is_sym("{") {
1247 self.parse_brace_body()
1248 } else {
1249 let e = self.parse_assignment();
1250 alloc::vec![Statement::Return(Some(e))]
1251 }
1252 }
1253
1254 fn parse_conditional(&mut self) -> Expression {
1255 let test = self.parse_binary(0);
1256 if self.eat_sym("?") {
1257 let consequent = self.parse_assignment();
1258 self.expect_sym(":");
1259 let alternate = self.parse_assignment();
1260 return Expression::Conditional {
1261 test: Box::new(test),
1262 consequent: Box::new(consequent),
1263 alternate: Box::new(alternate),
1264 };
1265 }
1266 test
1267 }
1268
1269 fn parse_binary(&mut self, min_prec: u8) -> Expression {
1270 let mut left = self.parse_unary();
1271 while let Some(op) = self.current_binop_str() {
1272 let prec = match bin_prec(&op) {
1273 Some(p) => p,
1274 None => break,
1275 };
1276 if prec < min_prec {
1277 break;
1278 }
1279 self.bump(); let next_min = if is_right_assoc(&op) { prec } else { prec + 1 };
1281 let right = self.parse_binary(next_min);
1282 left = if let Some(lop) = to_logical(&op) {
1283 Expression::Logical {
1284 op: lop,
1285 left: Box::new(left),
1286 right: Box::new(right),
1287 }
1288 } else if let Some(bop) = to_binop(&op) {
1289 Expression::Binary {
1290 op: bop,
1291 left: Box::new(left),
1292 right: Box::new(right),
1293 }
1294 } else {
1295 left
1296 };
1297 }
1298 left
1299 }
1300
1301 fn current_binop_str(&self) -> Option<String> {
1303 match self.cur() {
1304 Token::Sym(s) if bin_prec(s).is_some() => Some(s.clone()),
1305 Token::Keyword(k) if k == "instanceof" || k == "in" => Some(k.clone()),
1306 _ => None,
1307 }
1308 }
1309
1310 fn parse_unary(&mut self) -> Expression {
1311 if let Token::Sym(s) = self.cur().clone() {
1313 let uop = match s.as_str() {
1314 "!" => Some(UnaryOp::Not),
1315 "-" => Some(UnaryOp::Neg),
1316 "+" => Some(UnaryOp::Pos),
1317 "~" => Some(UnaryOp::BitNot),
1318 _ => None,
1319 };
1320 if let Some(op) = uop {
1321 self.bump();
1322 let expr = self.parse_unary();
1323 return Expression::Unary {
1324 op,
1325 expr: Box::new(expr),
1326 };
1327 }
1328 if s == "++" || s == "--" {
1329 self.bump();
1330 let target = self.parse_unary();
1331 return Expression::Update {
1332 op: s,
1333 prefix: true,
1334 target: Box::new(target),
1335 };
1336 }
1337 }
1338 if let Token::Keyword(k) = self.cur().clone() {
1339 let uop = match k.as_str() {
1340 "typeof" => Some(UnaryOp::TypeOf),
1341 "void" => Some(UnaryOp::Void),
1342 "delete" => Some(UnaryOp::Delete),
1343 _ => None,
1344 };
1345 if let Some(op) = uop {
1346 self.bump();
1347 let expr = self.parse_unary();
1348 return Expression::Unary {
1349 op,
1350 expr: Box::new(expr),
1351 };
1352 }
1353 if k == "await" {
1354 self.bump();
1355 let expr = self.parse_unary();
1356 return Expression::Await(Box::new(expr));
1357 }
1358 if k == "new" {
1359 return self.parse_new();
1360 }
1361 }
1362 self.parse_postfix()
1363 }
1364
1365 fn parse_new(&mut self) -> Expression {
1366 self.bump(); if self.is_sym(".") && self.ident_at(1, "target") {
1370 self.bump(); self.bump(); return self.parse_call_member_tail(Expression::NewTarget, true);
1373 }
1374 let callee = self.parse_call_member(false);
1376 let arguments = if self.is_sym("(") {
1377 self.parse_arguments()
1378 } else {
1379 Vec::new()
1380 };
1381 let new_expr = Expression::New {
1382 callee: Box::new(callee),
1383 arguments,
1384 };
1385 self.parse_call_member_tail(new_expr, true)
1387 }
1388
1389 fn parse_postfix(&mut self) -> Expression {
1390 let expr = self.parse_call_member(true);
1391 if let Token::Sym(s) = self.cur().clone() {
1392 if s == "++" || s == "--" {
1393 self.bump();
1394 return Expression::Update {
1395 op: s,
1396 prefix: false,
1397 target: Box::new(expr),
1398 };
1399 }
1400 }
1401 expr
1402 }
1403
1404 fn parse_call_member(&mut self, allow_call: bool) -> Expression {
1406 let expr = self.parse_primary();
1407 self.parse_call_member_tail(expr, allow_call)
1408 }
1409
1410 fn parse_call_member_tail(&mut self, mut expr: Expression, allow_call: bool) -> Expression {
1412 loop {
1413 if self.eat_sym(".") {
1414 let prop = self.ident_name().unwrap_or_default();
1415 expr = Expression::Member {
1416 object: Box::new(expr),
1417 property: prop,
1418 optional: false,
1419 };
1420 } else if self.is_sym("?.") {
1421 self.bump();
1422 if self.is_sym("(") && allow_call {
1423 let arguments = self.parse_arguments();
1424 expr = Expression::Call {
1425 callee: Box::new(expr),
1426 arguments,
1427 optional: true,
1428 };
1429 } else if self.is_sym("[") {
1430 self.bump();
1431 let index = self.parse_expression();
1432 self.expect_sym("]");
1433 expr = Expression::Index {
1434 object: Box::new(expr),
1435 index: Box::new(index),
1436 optional: true,
1437 };
1438 } else {
1439 let prop = self.ident_name().unwrap_or_default();
1440 expr = Expression::Member {
1441 object: Box::new(expr),
1442 property: prop,
1443 optional: true,
1444 };
1445 }
1446 } else if self.eat_sym("[") {
1447 let index = self.parse_expression();
1448 self.expect_sym("]");
1449 expr = Expression::Index {
1450 object: Box::new(expr),
1451 index: Box::new(index),
1452 optional: false,
1453 };
1454 } else if self.is_sym("(") && allow_call {
1455 let arguments = self.parse_arguments();
1456 expr = Expression::Call {
1457 callee: Box::new(expr),
1458 arguments,
1459 optional: false,
1460 };
1461 } else if allow_call && matches!(self.cur(), Token::Template(_)) {
1462 let parts = match self.cur().clone() {
1467 Token::Template(p) => p,
1468 _ => unreachable!(),
1469 };
1470 self.bump();
1471 let mut quasis = Vec::new();
1472 let mut raw = Vec::new();
1473 let mut exprs = Vec::new();
1474 for part in parts {
1475 match part {
1476 super::lexer::TemplatePart::Quasi(s, r) => {
1477 quasis.push(s);
1478 raw.push(r);
1479 }
1480 super::lexer::TemplatePart::Expr(src) => {
1481 let mut sub = Parser::new(Lexer::new(&src));
1482 exprs.push(sub.parse_assignment());
1483 self.absorb_errors(sub);
1486 }
1487 }
1488 }
1489 expr = Expression::TaggedTemplate {
1490 tag: Box::new(expr),
1491 quasis,
1492 raw,
1493 exprs,
1494 };
1495 } else {
1496 break;
1497 }
1498 }
1499 expr
1500 }
1501
1502 fn parse_arguments(&mut self) -> Vec<Expression> {
1503 let mut args = Vec::new();
1504 self.expect_sym("(");
1505 while !self.is_sym(")") && !self.is_eof() {
1506 if self.eat_sym("...") {
1507 args.push(Expression::Spread(Box::new(self.parse_assignment())));
1508 } else {
1509 args.push(self.parse_assignment());
1510 }
1511 if !self.eat_sym(",") {
1512 break;
1513 }
1514 }
1515 self.expect_sym(")");
1516 args
1517 }
1518
1519 fn parse_primary(&mut self) -> Expression {
1520 match self.cur().clone() {
1521 Token::Num(n) => {
1522 self.bump();
1523 Expression::Number(n)
1524 }
1525 Token::BigIntLit(s) => {
1526 self.bump();
1527 Expression::BigIntLit(s)
1528 }
1529 Token::Str(s) => {
1530 self.bump();
1531 Expression::Str(s)
1532 }
1533 Token::Regex(p, f) => {
1534 self.bump();
1535 Expression::Regex(p, f)
1536 }
1537 Token::Template(parts) => {
1538 self.bump();
1539 let mut quasis = Vec::new();
1540 let mut exprs = Vec::new();
1541 for part in parts {
1542 match part {
1543 super::lexer::TemplatePart::Quasi(s, _raw) => quasis.push(s),
1544 super::lexer::TemplatePart::Expr(src) => {
1545 let mut sub = Parser::new(Lexer::new(&src));
1549 exprs.push(sub.parse_assignment());
1550 self.absorb_errors(sub);
1553 }
1554 }
1555 }
1556 Expression::TemplateLiteral { quasis, exprs }
1557 }
1558 Token::Ident(name) => {
1559 self.bump();
1560 Expression::Identifier(name)
1561 }
1562 Token::Keyword(kw) => match kw.as_str() {
1563 "true" => {
1564 self.bump();
1565 Expression::Bool(true)
1566 }
1567 "false" => {
1568 self.bump();
1569 Expression::Bool(false)
1570 }
1571 "null" => {
1572 self.bump();
1573 Expression::Null
1574 }
1575 "undefined" => {
1576 self.bump();
1577 Expression::Undefined
1578 }
1579 "this" => {
1580 self.bump();
1581 Expression::This
1582 }
1583 "super" => {
1584 self.bump();
1585 Expression::Super
1586 }
1587 "function" => self.parse_function_expression(false),
1588 "async" if self.kw_at(1, "function") => {
1589 self.bump(); self.parse_function_expression(true)
1591 }
1592 "class" => self.parse_class(),
1593 other => {
1594 let msg = alloc::format!("unexpected keyword '{}' in expression", other);
1598 self.record_error(msg);
1599 self.bump();
1600 Expression::Undefined
1601 }
1602 },
1603 Token::Sym(s) => match s.as_str() {
1604 "(" => {
1605 self.bump();
1606 let e = self.parse_expression();
1607 self.expect_sym(")");
1608 e
1609 }
1610 "[" => self.parse_array_literal(),
1611 "{" => self.parse_object_literal(),
1612 other => {
1613 let msg = alloc::format!("unexpected '{}' in expression", other);
1615 self.record_error(msg);
1616 self.bump();
1617 Expression::Undefined
1618 }
1619 },
1620 Token::Eof => Expression::Undefined,
1621 }
1622 }
1623
1624 fn parse_function_expression(&mut self, is_async: bool) -> Expression {
1625 self.bump(); let is_generator = self.eat_sym("*");
1627 let name = match self.cur().clone() {
1628 Token::Ident(n) => {
1629 self.bump();
1630 Some(n)
1631 }
1632 _ => None,
1633 };
1634 let params = self.parse_param_list();
1635 let body = self.parse_brace_body();
1636 Expression::Function {
1637 name,
1638 params,
1639 body,
1640 is_arrow: false,
1641 is_async,
1642 is_generator,
1643 }
1644 }
1645
1646 fn parse_class(&mut self) -> Expression {
1647 self.eat_kw("class");
1648 let name = match self.cur().clone() {
1649 Token::Ident(n) => {
1650 self.bump();
1651 Some(n)
1652 }
1653 _ => None,
1654 };
1655 let superclass = if self.eat_kw("extends") {
1656 Some(Box::new(self.parse_conditional()))
1657 } else {
1658 None
1659 };
1660 self.expect_sym("{");
1661 let mut members = Vec::new();
1662 while !self.is_sym("}") && !self.is_eof() {
1663 if self.eat_sym(";") {
1664 continue;
1665 }
1666 let is_static = if let Token::Ident(n) = self.cur().clone() {
1673 n == "static"
1674 && (self.is_property_key_token(1)
1675 || self.sym_at(1, "[")
1676 || self.sym_at(1, "*")
1677 || self.sym_at(1, "{"))
1678 } else {
1679 false
1680 };
1681 if is_static {
1682 self.bump();
1683 }
1684 if is_static && self.is_sym("{") {
1686 let body = self.parse_brace_body();
1687 members.push(ClassMember {
1688 key: String::new(),
1689 computed_key: None,
1690 kind: MethodKind::StaticBlock,
1691 params: Vec::new(),
1692 body,
1693 is_static: true,
1694 field_init: None,
1695 is_async: false,
1696 is_generator: false,
1697 });
1698 continue;
1699 }
1700 let async_modifier_ok =
1709 self.is_property_key_token(1) || self.sym_at(1, "[") || self.sym_at(1, "*");
1710 let is_async = self.is_kw("async") && async_modifier_ok;
1711 if is_async {
1712 self.bump();
1713 }
1714 let is_generator = self.eat_sym("*");
1715 let accessor_kind = if let Token::Ident(n) = self.cur().clone() {
1724 if (n == "get" || n == "set")
1725 && (self.sym_at(1, "[")
1726 || (self.is_property_key_token(1) && self.sym_at(2, "(")))
1727 {
1728 self.bump();
1729 Some(n == "get")
1730 } else {
1731 None
1732 }
1733 } else {
1734 None
1735 };
1736 let mut computed_key = None;
1738 let key = match self.cur().clone() {
1739 Token::Ident(n) => {
1740 self.bump();
1741 n
1742 }
1743 Token::Keyword(n) => {
1744 self.bump();
1745 n
1746 }
1747 Token::Str(s) => {
1748 self.bump();
1749 s
1750 }
1751 Token::Num(n) => {
1752 self.bump();
1753 super::value::fmt_number(n)
1754 }
1755 Token::Sym(s) if s == "[" => {
1756 self.bump();
1757 computed_key = Some(self.parse_assignment());
1758 self.expect_sym("]");
1759 String::new()
1760 }
1761 _ => {
1762 self.bump();
1763 continue;
1764 }
1765 };
1766 if self.is_sym("(") {
1767 let params = self.parse_param_list();
1769 let body = self.parse_brace_body();
1770 let kind = match accessor_kind {
1771 Some(true) => MethodKind::Getter,
1772 Some(false) => MethodKind::Setter,
1773 None if computed_key.is_none() && key == "constructor" => {
1774 MethodKind::Constructor
1775 }
1776 None => MethodKind::Method,
1777 };
1778 members.push(ClassMember {
1779 key,
1780 computed_key,
1781 kind,
1782 params,
1783 body,
1784 is_static,
1785 field_init: None,
1786 is_async,
1787 is_generator,
1788 });
1789 } else {
1790 let init = if self.eat_sym("=") {
1793 Some(self.parse_assignment())
1794 } else {
1795 None
1796 };
1797 self.eat_sym(";");
1798 members.push(ClassMember {
1799 key,
1800 computed_key: None,
1803 kind: MethodKind::Field,
1804 params: Vec::new(),
1805 body: Vec::new(),
1806 is_static,
1807 field_init: init,
1808 is_async: false,
1809 is_generator: false,
1810 });
1811 }
1812 }
1813 self.expect_sym("}");
1814 Expression::Class {
1815 name,
1816 superclass,
1817 members,
1818 }
1819 }
1820
1821 fn parse_array_literal(&mut self) -> Expression {
1822 self.expect_sym("[");
1823 let mut items = Vec::new();
1824 while !self.is_sym("]") && !self.is_eof() {
1825 if self.is_sym(",") {
1826 items.push(Expression::Undefined);
1828 self.bump();
1829 continue;
1830 }
1831 if self.eat_sym("...") {
1832 items.push(Expression::Spread(Box::new(self.parse_assignment())));
1833 } else {
1834 items.push(self.parse_assignment());
1835 }
1836 if !self.eat_sym(",") {
1837 break;
1838 }
1839 }
1840 self.expect_sym("]");
1841 Expression::Array(items)
1842 }
1843
1844 fn parse_object_literal(&mut self) -> Expression {
1845 self.expect_sym("{");
1846 let mut props = Vec::new();
1847 while !self.is_sym("}") && !self.is_eof() {
1848 if self.eat_sym("...") {
1850 let value = self.parse_assignment();
1851 props.push(Property {
1852 key: String::from(crate::os_lib::js::ast::OBJECT_SPREAD_KEY),
1853 value,
1854 computed: None,
1855 accessor: None,
1856 });
1857 if !self.eat_sym(",") {
1858 break;
1859 }
1860 continue;
1861 }
1862 let async_modifier_ok =
1869 self.is_property_key_token(1) || self.sym_at(1, "[") || self.sym_at(1, "*");
1870 let is_async = self.is_kw("async") && async_modifier_ok;
1871 if is_async {
1872 self.bump();
1873 }
1874 let is_generator = self.eat_sym("*");
1875 let accessor_kind = if let Token::Ident(n) = self.cur().clone() {
1881 if (n == "get" || n == "set")
1882 && (self.sym_at(1, "[")
1883 || (self.is_property_key_token(1) && self.sym_at(2, "(")))
1884 {
1885 self.bump();
1886 Some(n == "get")
1887 } else {
1888 None
1889 }
1890 } else {
1891 None
1892 };
1893 let mut computed = None;
1895 let key = match self.cur().clone() {
1897 Token::Ident(n) => {
1898 self.bump();
1899 n
1900 }
1901 Token::Keyword(n) => {
1902 self.bump();
1903 n
1904 }
1905 Token::Str(s) => {
1906 self.bump();
1907 s
1908 }
1909 Token::Num(n) => {
1910 self.bump();
1911 super::value::fmt_number(n)
1912 }
1913 Token::Sym(s) if s == "[" => {
1914 self.bump();
1915 computed = Some(self.parse_assignment());
1916 self.expect_sym("]");
1917 String::new()
1918 }
1919 _ => break,
1920 };
1921 let value = if self.eat_sym(":") {
1922 self.parse_assignment()
1923 } else if self.is_sym("(") {
1924 let params = self.parse_param_list();
1926 let body = self.parse_brace_body();
1927 Expression::Function {
1928 name: Some(key.clone()),
1929 params,
1930 body,
1931 is_arrow: false,
1932 is_async,
1933 is_generator,
1934 }
1935 } else {
1936 Expression::Identifier(key.clone())
1938 };
1939 props.push(Property {
1940 key,
1941 value,
1942 computed,
1943 accessor: accessor_kind,
1944 });
1945 if !self.eat_sym(",") {
1946 break;
1947 }
1948 }
1949 self.expect_sym("}");
1950 Expression::Object(props)
1951 }
1952}
1953
1954fn is_assign_op(op: &str) -> bool {
1957 matches!(
1958 op,
1959 "=" | "+="
1960 | "-="
1961 | "*="
1962 | "/="
1963 | "%="
1964 | "**="
1965 | "&="
1966 | "|="
1967 | "^="
1968 | "<<="
1969 | ">>="
1970 | ">>>="
1971 | "&&="
1972 | "||="
1973 | "??="
1974 )
1975}
1976
1977fn bin_prec(op: &str) -> Option<u8> {
1978 Some(match op {
1979 "??" => 1,
1980 "||" => 2,
1981 "&&" => 3,
1982 "|" => 4,
1983 "^" => 5,
1984 "&" => 6,
1985 "==" | "!=" | "===" | "!==" => 7,
1986 "<" | ">" | "<=" | ">=" | "instanceof" | "in" => 8,
1987 "<<" | ">>" | ">>>" => 9,
1988 "+" | "-" => 10,
1989 "*" | "/" | "%" => 11,
1990 "**" => 12,
1991 _ => return None,
1992 })
1993}
1994
1995fn is_right_assoc(op: &str) -> bool {
1996 op == "**"
1997}
1998
1999fn to_logical(op: &str) -> Option<LogicalOp> {
2000 match op {
2001 "&&" => Some(LogicalOp::And),
2002 "||" => Some(LogicalOp::Or),
2003 "??" => Some(LogicalOp::Nullish),
2004 _ => None,
2005 }
2006}
2007
2008fn to_binop(op: &str) -> Option<BinaryOp> {
2009 Some(match op {
2010 "+" => BinaryOp::Add,
2011 "-" => BinaryOp::Sub,
2012 "*" => BinaryOp::Mul,
2013 "/" => BinaryOp::Div,
2014 "%" => BinaryOp::Mod,
2015 "**" => BinaryOp::Pow,
2016 "==" => BinaryOp::Eq,
2017 "!=" => BinaryOp::NotEq,
2018 "===" => BinaryOp::StrictEq,
2019 "!==" => BinaryOp::StrictNotEq,
2020 "<" => BinaryOp::Lt,
2021 ">" => BinaryOp::Gt,
2022 "<=" => BinaryOp::LtEq,
2023 ">=" => BinaryOp::GtEq,
2024 "&" => BinaryOp::BitAnd,
2025 "|" => BinaryOp::BitOr,
2026 "^" => BinaryOp::BitXor,
2027 "<<" => BinaryOp::Shl,
2028 ">>" => BinaryOp::Shr,
2029 ">>>" => BinaryOp::UShr,
2030 "instanceof" => BinaryOp::InstanceOf,
2031 "in" => BinaryOp::In,
2032 _ => return None,
2033 })
2034}