Skip to main content

atmos/os_lib/js/
parser.rs

1//! 再帰下降 + 優先順位クライミングの JS パーサ。
2//!
3//! 全トークンを `Vec<Token>` に集めてインデックスで走査するため、アロー関数判定の
4//! ような任意先読みが容易。エラーは致命的にせずベストエフォートで継続する
5//! (失敗箇所は `Expression::Undefined` / `Statement::Empty` にフォールバック)。
6//! セミコロンは任意(改行ベースの ASI は簡易扱い)。
7
8use alloc::boxed::Box;
9use alloc::string::String;
10use alloc::vec::Vec;
11
12use super::ast::*;
13use super::lexer::{Lexer, Token};
14
15/// 回復して解析を続けた構文エラー 1 件。
16///
17/// 【2026-07-28】本パーサは「エラーを致命的にせずベストエフォートで継続」する
18/// 方針だが、従来は**回復したことを誰にも伝えていなかった**ため、壊れた
19/// スクリプトが「正常に解析できた」のと区別できなかった(`expect_sym` は
20/// `let _ = self.eat_sym(s);` と、期待した記号が無い事実を捨てていた)。
21/// 実行はこれまでどおり継続しつつ、**何をどこで諦めたのかは必ず呼び出し側へ
22/// 返す**ためにこの記録を持つ。
23#[derive(Debug, Clone, PartialEq)]
24pub struct ParseError {
25    /// 何を期待して何が来たか。
26    pub message: String,
27    /// トークン列上の位置(`Parser` 内部のトークン索引)。
28    pub token_index: usize,
29}
30
31/// 記録する構文エラーの上限。壊れきった入力で無制限にメモリを食わないため。
32const MAX_RECORDED_ERRORS: usize = 64;
33
34/// エラーメッセージ用にトークンを短く説明する。
35fn 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    /// 回復して解析を続けた構文エラーの記録(上限 `MAX_RECORDED_ERRORS` 件)。
53    errors: Vec<ParseError>,
54    /// 上限で切り捨てた分も含めた実際の検出件数。
55    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        // 字句解析の異常(閉じ忘れの文字列・コメント、値が化けた数値リテラル)も
70        // 呼び出し側から見れば同じ「構文エラー」なので、ここで引き取る。
71        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    /// 記録済みの構文エラー(上限まで)。
90    pub fn errors(&self) -> &[ParseError] {
91        &self.errors
92    }
93
94    /// 検出した構文エラーの総数(記録上限で切り捨てた分も含む)。
95    pub fn error_count(&self) -> usize {
96        self.error_count
97    }
98
99    /// 記録済みの構文エラーを取り出す(呼び出し側へ渡してログ出力する用途)。
100    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            // 【2026-09-05】トークン索引だけでは何が起きたか分からない。
108            //
109            // 実際に「`unexpected ':' in expression (token #34956)`」という
110            // 報告から原因の構文を突き止められず、候補を 16 種類も
111            // 試すはめになった(すべて外れ)。前後のトークンを添えれば
112            // どの構文で落ちたかがその場で分かる。
113            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    /// エラー位置の前後のトークンを短い文字列にする。
122    ///
123    /// 前 6 個・後 3 個。落ちた位置は `»«` で囲む。
124    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    /// 別インスタンス(テンプレート補間式などの副パーサ)が検出したエラーを
145    /// 自分の記録へ取り込む。位置は副パーサ内の索引なので、由来が分かるよう
146    /// 印を付ける。
147    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        // 記録上限を超えた分も総数には反映する。
156        if count > MAX_RECORDED_ERRORS {
157            self.error_count += count - MAX_RECORDED_ERRORS;
158        }
159    }
160
161    // --- トークンカーソル ---
162    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    /// `off` の位置がオブジェクト/クラスのプロパティ名になり得るトークン
191    /// (識別子/予約語/文字列/数値)かどうか(`get`/`set` アクセサ判定の先読み用)。
192    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    /// 記号 `s` を消費する。無ければ**回復して継続しつつ構文エラーとして記録**する
207    /// (従来は `let _ =` で「無かった」事実ごと捨てていた)。
208    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            // プロパティ名としてキーワードも許可 (obj.return 等)。
232            Token::Keyword(n) => {
233                self.pos += 1;
234                Some(n)
235            }
236            _ => None,
237        }
238    }
239
240    // --- プログラム ---
241    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            // 前進保証(無限ループ防止)。ここへ来るのは「文として解釈できない
249            // トークンを読み飛ばした」場合であり、明確な構文エラーなので記録する。
250            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    /// パースし、**AST と構文エラーの両方**を返す。
260    ///
261    /// AST は従来どおり常に返る(ベストエフォート動作を変えない)ので、
262    /// 呼び出し側は「実行はするが、壊れている事実は知っている」状態にできる。
263    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    // --- 文 ---
270    fn parse_statement(&mut self) -> Option<Statement> {
271        // セミコロン単独は空文。
272        if self.eat_sym(";") {
273            return Some(Statement::Empty);
274        }
275        if self.is_sym("{") {
276            return Some(self.parse_block());
277        }
278
279        // `using`/`await using` 宣言(Explicit Resource Management、ES2023→ES2026ベースライン)。
280        // `using` は予約語ではなく文脈依存キーワードのため、`using IDENT =` の形のときだけ
281        // 宣言として扱う(`using` という名前の普通の変数式文と衝突しないようにするため)。
282        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(); // await
294            return self.parse_using_declaration(true);
295        }
296
297        // ラベル付き文 `label: statement`(主にループの `break label`/`continue label`
298        // ターゲット用)。識別子の直後が `:` の場合のみ(三項演算子の `:` は先頭識別子の
299        // 直後に来ないため衝突しない)。
300        if let Token::Ident(label) = self.cur().clone() {
301            if self.sym_at(1, ":") {
302                self.bump(); // label
303                self.bump(); // ':'
304                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(); // async
319                    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                    // `break label;` — ASI の改行検知はこの字句解析器に無いため、次が
335                    // 識別子ならラベルとみなす(`break;\nfoo` のような稀なケースは
336                    // 非対応の簡略実装)。
337                    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 Name = class ...` 相当に脱糖。
369                    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    /// `{ ... }` の中身を Vec<Statement> として取り出す(関数本体用)。
404    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    /// `using x = expr, y = expr2;` / `await using x = expr;`。
441    /// 仕様上バインディングは単純な識別子のみ(分割代入パターンは不可)。
442    fn parse_using_declaration(&mut self, is_await: bool) -> Option<Statement> {
443        self.bump(); // "using"
444        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(); // if
467        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(); // do
494        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(); // for
505        let is_await = self.eat_kw("await");
506        self.expect_sym("(");
507
508        // for-in / for-of を宣言形式で検出。
509        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                } // consume `in`
524                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            // C スタイル: 残りの宣言子を読む。
537            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        // 非宣言形式の for-of/for-in: `for (x of arr)` / `for (x in obj)`(x は単純識別子)。
561        // 一般の式パーサは `in` を二項演算子として消費してしまうため使えず、
562        // `IDENT of|in` の形を先読みで検出してから専用に処理する。
563        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(); // ident
567                self.bump(); // of/in
568                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        // 非宣言形式の分割代入 for-of/for-in: `for ([a,b] of arr)` / `for ({a,b} of obj)`。
583        // `[`/`{` は for(...) の頭では値コンテキストなのでパターンとして一意に解釈できるが、
584        // `for ([a,b] = [1,2]; ...)` のような C 形式 for の可能性もあるため、
585        // パターンを試しにパースしてみて `of`/`in` が続かなければ巻き戻す。
586        if self.is_sym("[") || self.is_sym("{") {
587            let save = self.pos;
588            // 【2026-09-05】巻き戻すときは**記録したエラーも巻き戻す**。
589            // ここは「for-of/for-in か?」を試すだけの投機的な解析で、
590            // 外れたら位置を戻して C 形式として読み直す。ところが
591            // 位置しか戻していなかったため、試行中に出たエラーが残り、
592            // 実際には正しい構文まで構文エラーとして報告していた。
593            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                } // consume `in`
600                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        // 非宣言形式のメンバー/添字式 for-of/for-in: `for (obj.prop of arr)` / `for (obj[k] of arr)`。
617        // `parse_call_member(false)`(呼出しは許可しない — member/index チェーンのみ)を使えば
618        // `in` を二項演算子として誤消費しない。結果が Member/Index で直後に of/in が続けば
619        // 採用し、そうでなければ(単純識別子や他の式だった場合)巻き戻して通常の C 形式へ。
620        if !self.is_kw("var") && !self.is_kw("let") && !self.is_kw("const") {
621            let save = self.pos;
622            // 同上。外れたら位置とエラーの両方を戻す。
623            // `for(;;)` は最初の `;` でここが失敗し、巻き戻した後は
624            // 正しく解析できるのに、残ったエラーのせいで
625            // 「式の位置に `;`」と報告されていた(jQuery 1.8.2 が
626            // `for(;;)` を使っており、本体が丸ごと構文エラー扱いになっていた)。
627            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                } // consume `in`
635                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        // init 式(無しの場合あり)
652        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        // init の `;` は呼び出し側で消費済み。
664        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(); // function
687        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(); // try
702        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    /// 文字列指定子(module specifier)を読む。`from "mod"` の "mod" 部分など。
725    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    /// 文脈依存キーワード(`from`/`as`)を ident として消費する。一致したら true。
736    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    /// `{ a, b as c }` の中身を (元名, ローカル名) ペアの列として読む。
746    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    /// `import` 宣言。
766    /// 形態: `import "mod"` / `import def from "mod"` /
767    /// `import * as ns from "mod"` / `import { a, b as c } from "mod"` /
768    /// `import def, { a } from "mod"` / `import def, * as ns from "mod"`。
769    fn parse_import(&mut self) -> Option<Statement> {
770        self.bump(); // import
771        let mut default = None;
772        let mut namespace = None;
773        let mut named = Vec::new();
774
775        // 副作用のみ: import "mod";
776        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        // default インポート(識別子)。
789        if let Token::Ident(n) = self.cur().clone() {
790            self.bump();
791            default = Some(n);
792            self.eat_sym(","); // default の後に名前空間/名前付きが続く場合
793        }
794
795        // 名前空間 `* as ns`。
796        if self.eat_sym("*") {
797            self.eat_contextual("as");
798            namespace = self.ident_name();
799        } else if self.is_sym("{") {
800            // 名前付き `{ a, b as c }`。
801            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    /// `export` 宣言。
817    /// 形態: `export default <expr>` / `export { a, b as c }` /
818    /// `export { a } from "mod"` / `export * from "mod"` /
819    /// `export var/let/const/function/class ...`。
820    fn parse_export(&mut self) -> Option<Statement> {
821        self.bump(); // export
822
823        // export default <expr>;
824        if self.eat_kw("default") {
825            // default の後は関数/クラス宣言または式。
826            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(); // async
830                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        // export * from "mod";
841        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        // export { a, b as c } [from "mod"];
849        if self.is_sym("{") {
850            // ここでの (orig, local) は (ローカル名, 公開名) に読み替える。
851            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        // export var/let/const/function/class ...
865        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    /// `export` に続く宣言から公開すべき名前を先読みで収集する(カーソルは進めない)。
874    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                // function [*] name
879                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                // async function [*] name
889                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                // 単純な識別子束縛のみ収集(分割代入は対象外)。
904                let mut off = 1;
905                while let Token::Ident(n) = self.at(off) {
906                    names.push(n.clone());
907                    // 次が `,` なら継続。`=` 等が来たら打ち切る。
908                    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                // 想定外トークンはスキップして無限ループを避ける。
943                self.bump();
944                continue;
945            };
946            // 次の case/default/} までを本体として収集。
947            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    /// 束縛パターンをパース(識別子 / `{...}` / `[...]`)。
996    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; // rest は最後。
1020            }
1021            // 算出プロパティ名 `{[expr]: target}`。以前は一切非対応で、`[` に遭遇すると
1022            // どの分岐にも該当せず `_ => break` に落ち、以降のプロパティ(分割代入先の
1023            // 残り全部)が消え、パース位置もずれて後続の解析まで巻き込んで壊れる
1024            // バグだった(クラス/オブジェクトリテラルの async/generator 修飾子と同種)。
1025            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            // `key: target` で別名/ネスト、無ければ key 自身を束縛(算出キーの場合は
1052            // 仕様上 `: target` が必須なので、無ければ空の識別子にフォールバックする)。
1053            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                // 穴 [a, , b]
1084                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    // --- 式 ---
1116    pub fn parse_expression(&mut self) -> Expression {
1117        let first = self.parse_assignment();
1118        if !self.is_sym(",") {
1119            return first;
1120        }
1121        // カンマ演算子: 以前は後続の式で単純に上書きしており、先行する式(の副作用)が
1122        // AST から丸ごと消えてしまう重大なバグだった(`(a(), b())` が `a()` を一切
1123        // 呼ばないなど)。`Sequence` へ全要素を保持し、実行時に順番に評価する。
1124        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        // yield / yield* (generator 内、assignment レベル)。
1133        if self.is_kw("yield") {
1134            self.bump();
1135            let delegate = self.eat_sym("*");
1136            // 引数なし yield(`yield;` / `yield)` 等)を許容。
1137            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        // アロー関数の先読み。
1151        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        // `async` 接頭辞(async function は arrow ではないので除外)。
1172        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        // x => ...
1182        if let Token::Ident(name) = self.cur().clone() {
1183            if self.sym_at(1, "=>") {
1184                self.bump(); // ident
1185                self.bump(); // =>
1186                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        // ( params ) => ...
1202        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        // arrow ではなかった。consume した `async` を巻き戻す。
1220        self.pos = start;
1221        None
1222    }
1223
1224    /// 現在位置の `(` に対応する `)` のインデックスを返す。
1225    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(); // operator
1280            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    /// 現在のトークンが二項演算子なら、その文字列を返す(`instanceof`/`in` 含む)。
1302    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        // 前置演算子
1312        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(); // new
1367        // `new.target`(MetaProperty)。ドット直後が識別子 `target` の場合のみ該当し、
1368        // それ以外(`new Foo` 等の通常のコンストラクタ呼び出し)とは衝突しない。
1369        if self.is_sym(".") && self.ident_at(1, "target") {
1370            self.bump(); // .
1371            self.bump(); // target
1372            return self.parse_call_member_tail(Expression::NewTarget, true);
1373        }
1374        // callee は呼出を含まないメンバ式。
1375        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        // `new A(7).get()` の後続メンバ/呼出チェーンを継続。
1386        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    /// メンバ/添字/呼出のチェーン。`allow_call=false` で呼出を抑止(new 用)。
1405    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    /// 既存の式に続くメンバ/添字/呼出チェーンを消費する。
1411    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                // タグ付きテンプレート `` tag`...` ``。以前はこの分岐が無く、`Template`
1463                // トークンが式の直後に来ると(primary の再入り口が無いため)静かに
1464                // パースが打ち切られる/崩れるバグだった(本キャンペーンで見つけてきた
1465                // 「未知トークンでの黙示的パース破壊」系と同種)。
1466                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                            // テンプレート補間式の中の構文エラーも親へ引き継ぐ
1484                            // (別インスタンスで解析するため、捨てると誰も気づけない)。
1485                            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                            // 補間式は独立したサブパーサで構文解析する(外側の解析状態を
1546                            // 汚さない)。comma 演算子は非対応(assignment 式まで。関数
1547                            // 引数リストの各要素パースと同じ簡略方針)。
1548                            let mut sub = Parser::new(Lexer::new(&src));
1549                            exprs.push(sub.parse_assignment());
1550                            // テンプレート補間式の中の構文エラーも親へ引き継ぐ
1551                            // (別インスタンスで解析するため、捨てると誰も気づけない)。
1552                            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(); // async
1590                    self.parse_function_expression(true)
1591                }
1592                "class" => self.parse_class(),
1593                other => {
1594                    // 式の位置に来てはいけない予約語。従来は黙って
1595                    // `undefined` に置き換えていたため、`if` が消えるような
1596                    // 壊れ方をしても呼び出し側は何も気づけなかった。
1597                    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                    // 式として解釈できない記号(余分な `)` や `,` など)。
1614                    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(); // function
1626        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            // static 修飾子。以前は「次が `(` でなければ修飾子」という緩い判定で、
1667            // `class C { static = 5; }`("static" という名前のフィールド)まで
1668            // 修飾子と誤認識し、後続の `=` がどの分岐にも該当せず読み飛ばされて
1669            // パース結果が壊れるバグがあった(`async`/`*` 修飾子と同種)。次のトークンが
1670            // 実際にメソッド/フィールド名や `{`(static block)になり得る場合のみ
1671            // 修飾子として扱う。
1672            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            // `static { ... }`(ES2022 静的初期化ブロック)。
1685            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            // `async`/`*`(generator)修飾子。以前はどちらも一切認識されておらず、
1701            // `async method(){}`/`*method(){}` を含むクラス定義があると `key` の
1702            // マッチが `_ => { self.bump(); continue; }` に落ちてメソッド自体が
1703            // 丸ごと消え、パース位置がずれて後続メンバの解析も壊れるバグだった。
1704            // `async` の次が「メソッド名になり得るトークン」(識別子/キーワード/文字列/
1705            // 数値/`[`算出キー/`*`generator)でなければ、`async` 自身がプロパティ名
1706            // (`class C { async = 1; }` のようなフィールド名)と判断し、修飾子として
1707            // 消費しない(このガードが無いと `async` という名前のフィールドが壊れる)。
1708            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            // アクセサ修飾子(`get name() {...}` / `set name(v) {...}`)。次の2トークンが
1716            // 「プロパティ名になり得るトークン」+ `(` の場合のみアクセサとして扱う
1717            // (`get(){}`="get" という名前のメソッド、`get: 1`="get" という名前の
1718            // フィールドと衝突しないようにするため)。算出名 `get [expr](){}` も、
1719            // 次が `[` ならこの文法上アクセサ以外の解釈があり得ないため許可する
1720            // (以前はここが漏れており `get [Symbol.iterator](){}` のようなパターンが
1721            // getter として認識されず、"get" という名前の孤立フィールド+無関係な
1722            // 算出名メソッドという壊れた2メンバに分解されてしまっていた)。
1723            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            // メソッド名。`[expr]` は算出メソッド名(`[Symbol.iterator]` 等)。
1737            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                // メソッド(constructor 含む)。
1768                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                // フィールド宣言: `key = expr;` または `key;`(`#key` も同じ経路。
1791                // lexer が '#' を識別子の一部として読むため key にそのまま含まれる)。
1792                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                    // 算出フィールド名(`[expr] = init;`)は非対応(稀なパターンのため、
1801                    // メソッドの算出名 `[Symbol.iterator](){}` のみ対応する簡略化)。
1802                    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                // 穴あき配列 [1,,3] は undefined 扱い。
1827                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            // オブジェクトスプレッド {...o}
1849            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            // `async`/`*`(generator)修飾子(`{ async method(){} }`/`{ *gen(){} }`)。
1863            // クラスのメソッド修飾子と同じ理由で以前は一切認識されず、遭遇すると
1864            // キー解析が丸ごと失敗してオブジェクトリテラル全体のパースが壊れていた。
1865            // `{ async: 1 }`("async" という名前の通常プロパティ)との曖昧さ回避のため、
1866            // 次がメソッド名になり得るトークンの場合のみ修飾子として扱う
1867            // (クラス側の同種ガードと同じロジック)。
1868            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            // アクセサ修飾子(`{get name() {...}}` / `{set name(v) {...}}`)。クラスの
1876            // アクセサ判定と同じ2トークン先読み規則(`get`/`set` の次が「プロパティ名に
1877            // なり得るトークン」+ `(` の場合のみアクセサ扱い)。算出名
1878            // `{ get [expr](){} }` も、次が `[` ならアクセサ以外の解釈があり得ないため
1879            // 許可する(クラス側の同種修正と同じ理由)。
1880            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            // 算出キー {[expr]: v}
1894            let mut computed = None;
1895            // キー: 識別子 / 文字列 / 数値 / [computed]
1896            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                // メソッド短縮 key(){...}
1925                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                // 短縮プロパティ {x}
1937                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
1954// --- 演算子テーブル ---
1955
1956fn 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}