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(), self.error_count);
594            let pat = self.parse_pattern();
595            if self.eat_kw("of") || self.is_kw("in") {
596                let of = !self.is_kw("in");
597                if !of {
598                    self.bump();
599                } // 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.0);
614            // 件数も戻す(2026-09-26。記録だけ戻して件数を戻していなかったため、
615            // エラーの無い jQuery 1.8.2 で「42 syntax error(s)」と警告が出ていた)。
616            self.error_count = err_save.1;
617        }
618
619        // 非宣言形式のメンバー/添字式 for-of/for-in: `for (obj.prop of arr)` / `for (obj[k] of arr)`。
620        // `parse_call_member(false)`(呼出しは許可しない — member/index チェーンのみ)を使えば
621        // `in` を二項演算子として誤消費しない。結果が Member/Index で直後に of/in が続けば
622        // 採用し、そうでなければ(単純識別子や他の式だった場合)巻き戻して通常の C 形式へ。
623        if !self.is_kw("var") && !self.is_kw("let") && !self.is_kw("const") {
624            let save = self.pos;
625            // 同上。外れたら位置とエラーの両方を戻す。
626            // `for(;;)` は最初の `;` でここが失敗し、巻き戻した後は
627            // 正しく解析できるのに、残ったエラーのせいで
628            // 「式の位置に `;`」と報告されていた(jQuery 1.8.2 が
629            // `for(;;)` を使っており、本体が丸ごと構文エラー扱いになっていた)。
630            let err_save = (self.errors.len(), self.error_count);
631            let expr = self.parse_call_member(false);
632            let is_target = matches!(expr, Expression::Member { .. } | Expression::Index { .. });
633            if is_target && (self.eat_kw("of") || self.is_kw("in")) {
634                let of = !self.is_kw("in");
635                if !of {
636                    self.bump();
637                } // consume `in`
638                let object = self.parse_expression();
639                self.expect_sym(")");
640                let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
641                return Some(Statement::ForIn {
642                    decl_kind: None,
643                    pattern: Pattern::Expr(Box::new(expr)),
644                    object,
645                    body,
646                    of,
647                    is_await,
648                });
649            }
650            self.pos = save;
651            self.errors.truncate(err_save.0);
652            // 件数も戻す(2026-09-26。記録だけ戻して件数を戻していなかったため、
653            // エラーの無い jQuery 1.8.2 で「42 syntax error(s)」と警告が出ていた)。
654            self.error_count = err_save.1;
655        }
656
657        // init 式(無しの場合あり)
658        let init = if self.is_sym(";") {
659            None
660        } else {
661            let e = self.parse_expression();
662            Some(Box::new(Statement::Expression(e)))
663        };
664        self.eat_sym(";");
665        self.finish_c_for(init)
666    }
667
668    fn finish_c_for(&mut self, init: Option<Box<Statement>>) -> Option<Statement> {
669        // init の `;` は呼び出し側で消費済み。
670        let test = if self.is_sym(";") {
671            None
672        } else {
673            Some(self.parse_expression())
674        };
675        self.eat_sym(";");
676        let update = if self.is_sym(")") {
677            None
678        } else {
679            Some(self.parse_expression())
680        };
681        self.expect_sym(")");
682        let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
683        Some(Statement::For {
684            init,
685            test,
686            update,
687            body,
688        })
689    }
690
691    fn parse_function_declaration(&mut self, is_async: bool) -> Option<Statement> {
692        self.bump(); // function
693        let is_generator = self.eat_sym("*");
694        let name = self.ident_name().unwrap_or_default();
695        let params = self.parse_param_list();
696        let body = self.parse_brace_body();
697        Some(Statement::FunctionDeclaration {
698            name,
699            params,
700            body,
701            is_async,
702            is_generator,
703        })
704    }
705
706    fn parse_try(&mut self) -> Option<Statement> {
707        self.bump(); // try
708        let block = self.parse_brace_body();
709        let mut catch_param = None;
710        let mut catch_block = None;
711        let mut finally_block = None;
712        if self.eat_kw("catch") {
713            if self.eat_sym("(") {
714                catch_param = Some(self.parse_pattern());
715                self.expect_sym(")");
716            }
717            catch_block = Some(self.parse_brace_body());
718        }
719        if self.eat_kw("finally") {
720            finally_block = Some(self.parse_brace_body());
721        }
722        Some(Statement::Try {
723            block,
724            catch_param,
725            catch_block,
726            finally_block,
727        })
728    }
729
730    /// 文字列指定子(module specifier)を読む。`from "mod"` の "mod" 部分など。
731    fn parse_module_specifier(&mut self) -> String {
732        match self.cur().clone() {
733            Token::Str(s) => {
734                self.bump();
735                s
736            }
737            _ => String::new(),
738        }
739    }
740
741    /// 文脈依存キーワード(`from`/`as`)を ident として消費する。一致したら true。
742    fn eat_contextual(&mut self, word: &str) -> bool {
743        if matches!(self.cur(), Token::Ident(x) if x == word) {
744            self.pos += 1;
745            true
746        } else {
747            false
748        }
749    }
750
751    /// `{ a, b as c }` の中身を (元名, ローカル名) ペアの列として読む。
752    fn parse_named_specifiers(&mut self) -> Vec<(String, String)> {
753        let mut out = Vec::new();
754        self.expect_sym("{");
755        while !self.is_sym("}") && !self.is_eof() {
756            let orig = self.ident_name().unwrap_or_default();
757            let local = if self.eat_contextual("as") {
758                self.ident_name().unwrap_or_default()
759            } else {
760                orig.clone()
761            };
762            out.push((orig, local));
763            if !self.eat_sym(",") {
764                break;
765            }
766        }
767        self.expect_sym("}");
768        out
769    }
770
771    /// `import` 宣言。
772    /// 形態: `import "mod"` / `import def from "mod"` /
773    /// `import * as ns from "mod"` / `import { a, b as c } from "mod"` /
774    /// `import def, { a } from "mod"` / `import def, * as ns from "mod"`。
775    fn parse_import(&mut self) -> Option<Statement> {
776        self.bump(); // import
777        let mut default = None;
778        let mut namespace = None;
779        let mut named = Vec::new();
780
781        // 副作用のみ: import "mod";
782        if let Token::Str(s) = self.cur().clone() {
783            self.bump();
784            self.eat_sym(";");
785            return Some(Statement::Import {
786                source: s,
787                default: None,
788                namespace: None,
789                named: Vec::new(),
790                side_effect_only: true,
791            });
792        }
793
794        // default インポート(識別子)。
795        if let Token::Ident(n) = self.cur().clone() {
796            self.bump();
797            default = Some(n);
798            self.eat_sym(","); // default の後に名前空間/名前付きが続く場合
799        }
800
801        // 名前空間 `* as ns`。
802        if self.eat_sym("*") {
803            self.eat_contextual("as");
804            namespace = self.ident_name();
805        } else if self.is_sym("{") {
806            // 名前付き `{ a, b as c }`。
807            named = self.parse_named_specifiers();
808        }
809
810        self.eat_contextual("from");
811        let source = self.parse_module_specifier();
812        self.eat_sym(";");
813        Some(Statement::Import {
814            source,
815            default,
816            namespace,
817            named,
818            side_effect_only: false,
819        })
820    }
821
822    /// `export` 宣言。
823    /// 形態: `export default <expr>` / `export { a, b as c }` /
824    /// `export { a } from "mod"` / `export * from "mod"` /
825    /// `export var/let/const/function/class ...`。
826    fn parse_export(&mut self) -> Option<Statement> {
827        self.bump(); // export
828
829        // export default <expr>;
830        if self.eat_kw("default") {
831            // default の後は関数/クラス宣言または式。
832            let expr = if self.is_kw("function") {
833                self.parse_function_expression(false)
834            } else if self.is_kw("async") && self.kw_at(1, "function") {
835                self.bump(); // async
836                self.parse_function_expression(true)
837            } else if self.is_kw("class") {
838                self.parse_class()
839            } else {
840                self.parse_assignment()
841            };
842            self.eat_sym(";");
843            return Some(Statement::ExportDefault(expr));
844        }
845
846        // export * from "mod";
847        if self.eat_sym("*") {
848            self.eat_contextual("from");
849            let source = self.parse_module_specifier();
850            self.eat_sym(";");
851            return Some(Statement::ExportAll { source });
852        }
853
854        // export { a, b as c } [from "mod"];
855        if self.is_sym("{") {
856            // ここでの (orig, local) は (ローカル名, 公開名) に読み替える。
857            let specs = self.parse_named_specifiers();
858            let source = if self.eat_contextual("from") {
859                Some(self.parse_module_specifier())
860            } else {
861                None
862            };
863            self.eat_sym(";");
864            return Some(Statement::ExportNamed {
865                specifiers: specs,
866                source,
867            });
868        }
869
870        // export var/let/const/function/class ...
871        let names = self.export_decl_names();
872        let declaration = self.parse_statement().unwrap_or(Statement::Empty);
873        Some(Statement::ExportDecl {
874            declaration: Box::new(declaration),
875            names,
876        })
877    }
878
879    /// `export` に続く宣言から公開すべき名前を先読みで収集する(カーソルは進めない)。
880    fn export_decl_names(&self) -> Vec<String> {
881        let mut names = Vec::new();
882        match self.cur() {
883            Token::Keyword(k) if k == "function" => {
884                // function [*] name
885                let mut off = 1;
886                if self.sym_at(off, "*") {
887                    off += 1;
888                }
889                if let Token::Ident(n) = self.at(off) {
890                    names.push(n.clone());
891                }
892            }
893            Token::Keyword(k) if k == "async" => {
894                // async function [*] name
895                let mut off = 2;
896                if self.sym_at(off, "*") {
897                    off += 1;
898                }
899                if let Token::Ident(n) = self.at(off) {
900                    names.push(n.clone());
901                }
902            }
903            Token::Keyword(k) if k == "class" => {
904                if let Token::Ident(n) = self.at(1) {
905                    names.push(n.clone());
906                }
907            }
908            Token::Keyword(k) if k == "var" || k == "let" || k == "const" => {
909                // 単純な識別子束縛のみ収集(分割代入は対象外)。
910                let mut off = 1;
911                while let Token::Ident(n) = self.at(off) {
912                    names.push(n.clone());
913                    // 次が `,` なら継続。`=` 等が来たら打ち切る。
914                    if self.sym_at(off + 1, ",") {
915                        off += 2;
916                    } else {
917                        break;
918                    }
919                }
920            }
921            _ => {}
922        }
923        names
924    }
925
926    fn parse_expression_statement(&mut self) -> Option<Statement> {
927        let e = self.parse_expression();
928        self.eat_sym(";");
929        Some(Statement::Expression(e))
930    }
931
932    fn parse_switch(&mut self) -> Option<Statement> {
933        self.eat_kw("switch");
934        self.expect_sym("(");
935        let discriminant = self.parse_expression();
936        self.expect_sym(")");
937        self.expect_sym("{");
938        let mut cases = Vec::new();
939        while !self.is_sym("}") && !self.is_eof() {
940            let test = if self.eat_kw("case") {
941                let t = self.parse_expression();
942                self.expect_sym(":");
943                Some(t)
944            } else if self.eat_kw("default") {
945                self.expect_sym(":");
946                None
947            } else {
948                // 想定外トークンはスキップして無限ループを避ける。
949                self.bump();
950                continue;
951            };
952            // 次の case/default/} までを本体として収集。
953            let mut body = Vec::new();
954            while !self.is_kw("case")
955                && !self.is_kw("default")
956                && !self.is_sym("}")
957                && !self.is_eof()
958            {
959                let before = self.pos;
960                if let Some(s) = self.parse_statement() {
961                    body.push(s);
962                }
963                if self.pos == before {
964                    self.pos += 1;
965                }
966            }
967            cases.push(crate::os_lib::js::ast::SwitchCase { test, body });
968        }
969        self.expect_sym("}");
970        Some(Statement::Switch {
971            discriminant,
972            cases,
973        })
974    }
975
976    fn parse_param_list(&mut self) -> Vec<Param> {
977        let mut params = Vec::new();
978        if self.eat_sym("(") {
979            while !self.is_sym(")") && !self.is_eof() {
980                let is_rest = self.eat_sym("...");
981                let pattern = self.parse_pattern();
982                let default = if self.eat_sym("=") {
983                    Some(self.parse_assignment())
984                } else {
985                    None
986                };
987                params.push(Param {
988                    pattern,
989                    default,
990                    is_rest,
991                });
992                if !self.eat_sym(",") {
993                    break;
994                }
995            }
996            self.expect_sym(")");
997        }
998        params
999    }
1000
1001    /// 束縛パターンをパース(識別子 / `{...}` / `[...]`)。
1002    fn parse_pattern(&mut self) -> Pattern {
1003        if self.is_sym("{") {
1004            return self.parse_object_pattern();
1005        }
1006        if self.is_sym("[") {
1007            return self.parse_array_pattern();
1008        }
1009        Pattern::Identifier(self.ident_name().unwrap_or_default())
1010    }
1011
1012    fn parse_object_pattern(&mut self) -> Pattern {
1013        self.expect_sym("{");
1014        let mut props = Vec::new();
1015        while !self.is_sym("}") && !self.is_eof() {
1016            if self.eat_sym("...") {
1017                let name = self.ident_name().unwrap_or_default();
1018                props.push(ObjPatProp {
1019                    key: String::new(),
1020                    computed_key: None,
1021                    value: Pattern::Identifier(name),
1022                    default: None,
1023                    is_rest: true,
1024                });
1025                break; // rest は最後。
1026            }
1027            // 算出プロパティ名 `{[expr]: target}`。以前は一切非対応で、`[` に遭遇すると
1028            // どの分岐にも該当せず `_ => break` に落ち、以降のプロパティ(分割代入先の
1029            // 残り全部)が消え、パース位置もずれて後続の解析まで巻き込んで壊れる
1030            // バグだった(クラス/オブジェクトリテラルの async/generator 修飾子と同種)。
1031            let (key, computed_key) = if self.eat_sym("[") {
1032                let ce = self.parse_assignment();
1033                self.expect_sym("]");
1034                (String::new(), Some(ce))
1035            } else {
1036                let k = match self.cur().clone() {
1037                    Token::Ident(n) => {
1038                        self.bump();
1039                        n
1040                    }
1041                    Token::Keyword(n) => {
1042                        self.bump();
1043                        n
1044                    }
1045                    Token::Str(s) => {
1046                        self.bump();
1047                        s
1048                    }
1049                    Token::Num(n) => {
1050                        self.bump();
1051                        super::value::fmt_number(n)
1052                    }
1053                    _ => break,
1054                };
1055                (k, None)
1056            };
1057            // `key: target` で別名/ネスト、無ければ key 自身を束縛(算出キーの場合は
1058            // 仕様上 `: target` が必須なので、無ければ空の識別子にフォールバックする)。
1059            let value = if self.eat_sym(":") {
1060                self.parse_pattern()
1061            } else {
1062                Pattern::Identifier(key.clone())
1063            };
1064            let default = if self.eat_sym("=") {
1065                Some(self.parse_assignment())
1066            } else {
1067                None
1068            };
1069            props.push(ObjPatProp {
1070                key,
1071                computed_key,
1072                value,
1073                default,
1074                is_rest: false,
1075            });
1076            if !self.eat_sym(",") {
1077                break;
1078            }
1079        }
1080        self.expect_sym("}");
1081        Pattern::Object(props)
1082    }
1083
1084    fn parse_array_pattern(&mut self) -> Pattern {
1085        self.expect_sym("[");
1086        let mut elems = Vec::new();
1087        while !self.is_sym("]") && !self.is_eof() {
1088            if self.is_sym(",") {
1089                // 穴 [a, , b]
1090                elems.push(ArrPatElem {
1091                    pattern: None,
1092                    default: None,
1093                    is_rest: false,
1094                });
1095                self.bump();
1096                continue;
1097            }
1098            let is_rest = self.eat_sym("...");
1099            let pat = self.parse_pattern();
1100            let default = if !is_rest && self.eat_sym("=") {
1101                Some(self.parse_assignment())
1102            } else {
1103                None
1104            };
1105            elems.push(ArrPatElem {
1106                pattern: Some(pat),
1107                default,
1108                is_rest,
1109            });
1110            if is_rest {
1111                break;
1112            }
1113            if !self.eat_sym(",") {
1114                break;
1115            }
1116        }
1117        self.expect_sym("]");
1118        Pattern::Array(elems)
1119    }
1120
1121    // --- 式 ---
1122    pub fn parse_expression(&mut self) -> Expression {
1123        let first = self.parse_assignment();
1124        if !self.is_sym(",") {
1125            return first;
1126        }
1127        // カンマ演算子: 以前は後続の式で単純に上書きしており、先行する式(の副作用)が
1128        // AST から丸ごと消えてしまう重大なバグだった(`(a(), b())` が `a()` を一切
1129        // 呼ばないなど)。`Sequence` へ全要素を保持し、実行時に順番に評価する。
1130        let mut items = alloc::vec![first];
1131        while self.eat_sym(",") {
1132            items.push(self.parse_assignment());
1133        }
1134        Expression::Sequence(items)
1135    }
1136
1137    fn parse_assignment(&mut self) -> Expression {
1138        // yield / yield* (generator 内、assignment レベル)。
1139        if self.is_kw("yield") {
1140            self.bump();
1141            let delegate = self.eat_sym("*");
1142            // 引数なし yield(`yield;` / `yield)` 等)を許容。
1143            let argument = if self.is_sym(";")
1144                || self.is_sym(")")
1145                || self.is_sym("]")
1146                || self.is_sym("}")
1147                || self.is_sym(",")
1148                || self.is_eof()
1149            {
1150                None
1151            } else {
1152                Some(Box::new(self.parse_assignment()))
1153            };
1154            return Expression::Yield { argument, delegate };
1155        }
1156        // アロー関数の先読み。
1157        if let Some(arrow) = self.try_parse_arrow() {
1158            return arrow;
1159        }
1160        let left = self.parse_conditional();
1161        if let Token::Sym(op) = self.cur().clone() {
1162            if is_assign_op(&op) {
1163                self.bump();
1164                let value = self.parse_assignment();
1165                return Expression::Assign {
1166                    op,
1167                    target: Box::new(left),
1168                    value: Box::new(value),
1169                };
1170            }
1171        }
1172        left
1173    }
1174
1175    fn try_parse_arrow(&mut self) -> Option<Expression> {
1176        let start = self.pos;
1177        // `async` 接頭辞(async function は arrow ではないので除外)。
1178        let is_async = if self.is_kw("async") {
1179            if self.kw_at(1, "function") {
1180                return None;
1181            }
1182            self.bump();
1183            true
1184        } else {
1185            false
1186        };
1187        // x => ...
1188        if let Token::Ident(name) = self.cur().clone() {
1189            if self.sym_at(1, "=>") {
1190                self.bump(); // ident
1191                self.bump(); // =>
1192                let body = self.parse_arrow_body();
1193                return Some(Expression::Function {
1194                    name: None,
1195                    params: alloc::vec![Param {
1196                        pattern: Pattern::Identifier(name),
1197                        default: None,
1198                        is_rest: false
1199                    }],
1200                    body,
1201                    is_arrow: true,
1202                    is_async,
1203                    is_generator: false,
1204                });
1205            }
1206        }
1207        // ( params ) => ...
1208        if self.is_sym("(") {
1209            if let Some(close) = self.matching_paren() {
1210                if matches!(self.toks.get(close + 1), Some(Token::Sym(s)) if s == "=>") {
1211                    let params = self.parse_param_list();
1212                    self.expect_sym("=>");
1213                    let body = self.parse_arrow_body();
1214                    return Some(Expression::Function {
1215                        name: None,
1216                        params,
1217                        body,
1218                        is_arrow: true,
1219                        is_async,
1220                        is_generator: false,
1221                    });
1222                }
1223            }
1224        }
1225        // arrow ではなかった。consume した `async` を巻き戻す。
1226        self.pos = start;
1227        None
1228    }
1229
1230    /// 現在位置の `(` に対応する `)` のインデックスを返す。
1231    fn matching_paren(&self) -> Option<usize> {
1232        let mut depth = 0i32;
1233        let mut i = self.pos;
1234        while i < self.toks.len() {
1235            match &self.toks[i] {
1236                Token::Sym(s) if s == "(" => depth += 1,
1237                Token::Sym(s) if s == ")" => {
1238                    depth -= 1;
1239                    if depth == 0 {
1240                        return Some(i);
1241                    }
1242                }
1243                Token::Eof => return None,
1244                _ => {}
1245            }
1246            i += 1;
1247        }
1248        None
1249    }
1250
1251    fn parse_arrow_body(&mut self) -> Vec<Statement> {
1252        if self.is_sym("{") {
1253            self.parse_brace_body()
1254        } else {
1255            let e = self.parse_assignment();
1256            alloc::vec![Statement::Return(Some(e))]
1257        }
1258    }
1259
1260    fn parse_conditional(&mut self) -> Expression {
1261        let test = self.parse_binary(0);
1262        if self.eat_sym("?") {
1263            let consequent = self.parse_assignment();
1264            self.expect_sym(":");
1265            let alternate = self.parse_assignment();
1266            return Expression::Conditional {
1267                test: Box::new(test),
1268                consequent: Box::new(consequent),
1269                alternate: Box::new(alternate),
1270            };
1271        }
1272        test
1273    }
1274
1275    fn parse_binary(&mut self, min_prec: u8) -> Expression {
1276        let mut left = self.parse_unary();
1277        while let Some(op) = self.current_binop_str() {
1278            let prec = match bin_prec(&op) {
1279                Some(p) => p,
1280                None => break,
1281            };
1282            if prec < min_prec {
1283                break;
1284            }
1285            self.bump(); // operator
1286            let next_min = if is_right_assoc(&op) { prec } else { prec + 1 };
1287            let right = self.parse_binary(next_min);
1288            left = if let Some(lop) = to_logical(&op) {
1289                Expression::Logical {
1290                    op: lop,
1291                    left: Box::new(left),
1292                    right: Box::new(right),
1293                }
1294            } else if let Some(bop) = to_binop(&op) {
1295                Expression::Binary {
1296                    op: bop,
1297                    left: Box::new(left),
1298                    right: Box::new(right),
1299                }
1300            } else {
1301                left
1302            };
1303        }
1304        left
1305    }
1306
1307    /// 現在のトークンが二項演算子なら、その文字列を返す(`instanceof`/`in` 含む)。
1308    fn current_binop_str(&self) -> Option<String> {
1309        match self.cur() {
1310            Token::Sym(s) if bin_prec(s).is_some() => Some(s.clone()),
1311            Token::Keyword(k) if k == "instanceof" || k == "in" => Some(k.clone()),
1312            _ => None,
1313        }
1314    }
1315
1316    fn parse_unary(&mut self) -> Expression {
1317        // 前置演算子
1318        if let Token::Sym(s) = self.cur().clone() {
1319            let uop = match s.as_str() {
1320                "!" => Some(UnaryOp::Not),
1321                "-" => Some(UnaryOp::Neg),
1322                "+" => Some(UnaryOp::Pos),
1323                "~" => Some(UnaryOp::BitNot),
1324                _ => None,
1325            };
1326            if let Some(op) = uop {
1327                self.bump();
1328                let expr = self.parse_unary();
1329                return Expression::Unary {
1330                    op,
1331                    expr: Box::new(expr),
1332                };
1333            }
1334            if s == "++" || s == "--" {
1335                self.bump();
1336                let target = self.parse_unary();
1337                return Expression::Update {
1338                    op: s,
1339                    prefix: true,
1340                    target: Box::new(target),
1341                };
1342            }
1343        }
1344        if let Token::Keyword(k) = self.cur().clone() {
1345            let uop = match k.as_str() {
1346                "typeof" => Some(UnaryOp::TypeOf),
1347                "void" => Some(UnaryOp::Void),
1348                "delete" => Some(UnaryOp::Delete),
1349                _ => None,
1350            };
1351            if let Some(op) = uop {
1352                self.bump();
1353                let expr = self.parse_unary();
1354                return Expression::Unary {
1355                    op,
1356                    expr: Box::new(expr),
1357                };
1358            }
1359            if k == "await" {
1360                self.bump();
1361                let expr = self.parse_unary();
1362                return Expression::Await(Box::new(expr));
1363            }
1364            if k == "new" {
1365                return self.parse_new();
1366            }
1367        }
1368        self.parse_postfix()
1369    }
1370
1371    fn parse_new(&mut self) -> Expression {
1372        self.bump(); // new
1373        // `new.target`(MetaProperty)。ドット直後が識別子 `target` の場合のみ該当し、
1374        // それ以外(`new Foo` 等の通常のコンストラクタ呼び出し)とは衝突しない。
1375        if self.is_sym(".") && self.ident_at(1, "target") {
1376            self.bump(); // .
1377            self.bump(); // target
1378            return self.parse_call_member_tail(Expression::NewTarget, true);
1379        }
1380        // callee は呼出を含まないメンバ式。
1381        let callee = self.parse_call_member(false);
1382        let arguments = if self.is_sym("(") {
1383            self.parse_arguments()
1384        } else {
1385            Vec::new()
1386        };
1387        let new_expr = Expression::New {
1388            callee: Box::new(callee),
1389            arguments,
1390        };
1391        // `new A(7).get()` の後続メンバ/呼出チェーンを継続。
1392        self.parse_call_member_tail(new_expr, true)
1393    }
1394
1395    fn parse_postfix(&mut self) -> Expression {
1396        let expr = self.parse_call_member(true);
1397        if let Token::Sym(s) = self.cur().clone() {
1398            if s == "++" || s == "--" {
1399                self.bump();
1400                return Expression::Update {
1401                    op: s,
1402                    prefix: false,
1403                    target: Box::new(expr),
1404                };
1405            }
1406        }
1407        expr
1408    }
1409
1410    /// メンバ/添字/呼出のチェーン。`allow_call=false` で呼出を抑止(new 用)。
1411    fn parse_call_member(&mut self, allow_call: bool) -> Expression {
1412        let expr = self.parse_primary();
1413        self.parse_call_member_tail(expr, allow_call)
1414    }
1415
1416    /// 既存の式に続くメンバ/添字/呼出チェーンを消費する。
1417    fn parse_call_member_tail(&mut self, mut expr: Expression, allow_call: bool) -> Expression {
1418        loop {
1419            if self.eat_sym(".") {
1420                let prop = self.ident_name().unwrap_or_default();
1421                expr = Expression::Member {
1422                    object: Box::new(expr),
1423                    property: prop,
1424                    optional: false,
1425                };
1426            } else if self.is_sym("?.") {
1427                self.bump();
1428                if self.is_sym("(") && allow_call {
1429                    let arguments = self.parse_arguments();
1430                    expr = Expression::Call {
1431                        callee: Box::new(expr),
1432                        arguments,
1433                        optional: true,
1434                    };
1435                } else if self.is_sym("[") {
1436                    self.bump();
1437                    let index = self.parse_expression();
1438                    self.expect_sym("]");
1439                    expr = Expression::Index {
1440                        object: Box::new(expr),
1441                        index: Box::new(index),
1442                        optional: true,
1443                    };
1444                } else {
1445                    let prop = self.ident_name().unwrap_or_default();
1446                    expr = Expression::Member {
1447                        object: Box::new(expr),
1448                        property: prop,
1449                        optional: true,
1450                    };
1451                }
1452            } else if self.eat_sym("[") {
1453                let index = self.parse_expression();
1454                self.expect_sym("]");
1455                expr = Expression::Index {
1456                    object: Box::new(expr),
1457                    index: Box::new(index),
1458                    optional: false,
1459                };
1460            } else if self.is_sym("(") && allow_call {
1461                let arguments = self.parse_arguments();
1462                expr = Expression::Call {
1463                    callee: Box::new(expr),
1464                    arguments,
1465                    optional: false,
1466                };
1467            } else if allow_call && matches!(self.cur(), Token::Template(_)) {
1468                // タグ付きテンプレート `` tag`...` ``。以前はこの分岐が無く、`Template`
1469                // トークンが式の直後に来ると(primary の再入り口が無いため)静かに
1470                // パースが打ち切られる/崩れるバグだった(本キャンペーンで見つけてきた
1471                // 「未知トークンでの黙示的パース破壊」系と同種)。
1472                let parts = match self.cur().clone() {
1473                    Token::Template(p) => p,
1474                    _ => unreachable!(),
1475                };
1476                self.bump();
1477                let mut quasis = Vec::new();
1478                let mut raw = Vec::new();
1479                let mut exprs = Vec::new();
1480                for part in parts {
1481                    match part {
1482                        super::lexer::TemplatePart::Quasi(s, r) => {
1483                            quasis.push(s);
1484                            raw.push(r);
1485                        }
1486                        super::lexer::TemplatePart::Expr(src) => {
1487                            let mut sub = Parser::new(Lexer::new(&src));
1488                            exprs.push(sub.parse_assignment());
1489                            // テンプレート補間式の中の構文エラーも親へ引き継ぐ
1490                            // (別インスタンスで解析するため、捨てると誰も気づけない)。
1491                            self.absorb_errors(sub);
1492                        }
1493                    }
1494                }
1495                expr = Expression::TaggedTemplate {
1496                    tag: Box::new(expr),
1497                    quasis,
1498                    raw,
1499                    exprs,
1500                };
1501            } else {
1502                break;
1503            }
1504        }
1505        expr
1506    }
1507
1508    fn parse_arguments(&mut self) -> Vec<Expression> {
1509        let mut args = Vec::new();
1510        self.expect_sym("(");
1511        while !self.is_sym(")") && !self.is_eof() {
1512            if self.eat_sym("...") {
1513                args.push(Expression::Spread(Box::new(self.parse_assignment())));
1514            } else {
1515                args.push(self.parse_assignment());
1516            }
1517            if !self.eat_sym(",") {
1518                break;
1519            }
1520        }
1521        self.expect_sym(")");
1522        args
1523    }
1524
1525    fn parse_primary(&mut self) -> Expression {
1526        match self.cur().clone() {
1527            Token::Num(n) => {
1528                self.bump();
1529                Expression::Number(n)
1530            }
1531            Token::BigIntLit(s) => {
1532                self.bump();
1533                Expression::BigIntLit(s)
1534            }
1535            Token::Str(s) => {
1536                self.bump();
1537                Expression::Str(s)
1538            }
1539            Token::Regex(p, f) => {
1540                self.bump();
1541                Expression::Regex(p, f)
1542            }
1543            Token::Template(parts) => {
1544                self.bump();
1545                let mut quasis = Vec::new();
1546                let mut exprs = Vec::new();
1547                for part in parts {
1548                    match part {
1549                        super::lexer::TemplatePart::Quasi(s, _raw) => quasis.push(s),
1550                        super::lexer::TemplatePart::Expr(src) => {
1551                            // 補間式は独立したサブパーサで構文解析する(外側の解析状態を
1552                            // 汚さない)。comma 演算子は非対応(assignment 式まで。関数
1553                            // 引数リストの各要素パースと同じ簡略方針)。
1554                            let mut sub = Parser::new(Lexer::new(&src));
1555                            exprs.push(sub.parse_assignment());
1556                            // テンプレート補間式の中の構文エラーも親へ引き継ぐ
1557                            // (別インスタンスで解析するため、捨てると誰も気づけない)。
1558                            self.absorb_errors(sub);
1559                        }
1560                    }
1561                }
1562                Expression::TemplateLiteral { quasis, exprs }
1563            }
1564            Token::Ident(name) => {
1565                self.bump();
1566                Expression::Identifier(name)
1567            }
1568            Token::Keyword(kw) => match kw.as_str() {
1569                "true" => {
1570                    self.bump();
1571                    Expression::Bool(true)
1572                }
1573                "false" => {
1574                    self.bump();
1575                    Expression::Bool(false)
1576                }
1577                "null" => {
1578                    self.bump();
1579                    Expression::Null
1580                }
1581                "undefined" => {
1582                    self.bump();
1583                    Expression::Undefined
1584                }
1585                "this" => {
1586                    self.bump();
1587                    Expression::This
1588                }
1589                "super" => {
1590                    self.bump();
1591                    Expression::Super
1592                }
1593                "function" => self.parse_function_expression(false),
1594                "async" if self.kw_at(1, "function") => {
1595                    self.bump(); // async
1596                    self.parse_function_expression(true)
1597                }
1598                "class" => self.parse_class(),
1599                // `of` は予約語ではない(for-of の文脈でだけ意味を持つ)。式の位置では普通の識別子
1600                // (2026-09-26。OpenStreetMap 埋め込みの JS が `new Uint8Array(of)` を使っていた)。
1601                "of" => {
1602                    self.bump();
1603                    Expression::Identifier(String::from("of"))
1604                }
1605                other => {
1606                    // 式の位置に来てはいけない予約語。従来は黙って
1607                    // `undefined` に置き換えていたため、`if` が消えるような
1608                    // 壊れ方をしても呼び出し側は何も気づけなかった。
1609                    let msg = alloc::format!("unexpected keyword '{}' in expression", other);
1610                    self.record_error(msg);
1611                    self.bump();
1612                    Expression::Undefined
1613                }
1614            },
1615            Token::Sym(s) => match s.as_str() {
1616                "(" => {
1617                    self.bump();
1618                    let e = self.parse_expression();
1619                    self.expect_sym(")");
1620                    e
1621                }
1622                "[" => self.parse_array_literal(),
1623                "{" => self.parse_object_literal(),
1624                other => {
1625                    // 式として解釈できない記号(余分な `)` や `,` など)。
1626                    let msg = alloc::format!("unexpected '{}' in expression", other);
1627                    self.record_error(msg);
1628                    self.bump();
1629                    Expression::Undefined
1630                }
1631            },
1632            Token::Eof => Expression::Undefined,
1633        }
1634    }
1635
1636    fn parse_function_expression(&mut self, is_async: bool) -> Expression {
1637        self.bump(); // function
1638        let is_generator = self.eat_sym("*");
1639        let name = match self.cur().clone() {
1640            Token::Ident(n) => {
1641                self.bump();
1642                Some(n)
1643            }
1644            _ => None,
1645        };
1646        let params = self.parse_param_list();
1647        let body = self.parse_brace_body();
1648        Expression::Function {
1649            name,
1650            params,
1651            body,
1652            is_arrow: false,
1653            is_async,
1654            is_generator,
1655        }
1656    }
1657
1658    fn parse_class(&mut self) -> Expression {
1659        self.eat_kw("class");
1660        let name = match self.cur().clone() {
1661            Token::Ident(n) => {
1662                self.bump();
1663                Some(n)
1664            }
1665            _ => None,
1666        };
1667        let superclass = if self.eat_kw("extends") {
1668            Some(Box::new(self.parse_conditional()))
1669        } else {
1670            None
1671        };
1672        self.expect_sym("{");
1673        let mut members = Vec::new();
1674        while !self.is_sym("}") && !self.is_eof() {
1675            if self.eat_sym(";") {
1676                continue;
1677            }
1678            // static 修飾子。以前は「次が `(` でなければ修飾子」という緩い判定で、
1679            // `class C { static = 5; }`("static" という名前のフィールド)まで
1680            // 修飾子と誤認識し、後続の `=` がどの分岐にも該当せず読み飛ばされて
1681            // パース結果が壊れるバグがあった(`async`/`*` 修飾子と同種)。次のトークンが
1682            // 実際にメソッド/フィールド名や `{`(static block)になり得る場合のみ
1683            // 修飾子として扱う。
1684            let is_static = if let Token::Ident(n) = self.cur().clone() {
1685                n == "static"
1686                    && (self.is_property_key_token(1)
1687                        || self.sym_at(1, "[")
1688                        || self.sym_at(1, "*")
1689                        || self.sym_at(1, "{"))
1690            } else {
1691                false
1692            };
1693            if is_static {
1694                self.bump();
1695            }
1696            // `static { ... }`(ES2022 静的初期化ブロック)。
1697            if is_static && self.is_sym("{") {
1698                let body = self.parse_brace_body();
1699                members.push(ClassMember {
1700                    key: String::new(),
1701                    computed_key: None,
1702                    kind: MethodKind::StaticBlock,
1703                    params: Vec::new(),
1704                    body,
1705                    is_static: true,
1706                    field_init: None,
1707                    is_async: false,
1708                    is_generator: false,
1709                });
1710                continue;
1711            }
1712            // `async`/`*`(generator)修飾子。以前はどちらも一切認識されておらず、
1713            // `async method(){}`/`*method(){}` を含むクラス定義があると `key` の
1714            // マッチが `_ => { self.bump(); continue; }` に落ちてメソッド自体が
1715            // 丸ごと消え、パース位置がずれて後続メンバの解析も壊れるバグだった。
1716            // `async` の次が「メソッド名になり得るトークン」(識別子/キーワード/文字列/
1717            // 数値/`[`算出キー/`*`generator)でなければ、`async` 自身がプロパティ名
1718            // (`class C { async = 1; }` のようなフィールド名)と判断し、修飾子として
1719            // 消費しない(このガードが無いと `async` という名前のフィールドが壊れる)。
1720            let async_modifier_ok =
1721                self.is_property_key_token(1) || self.sym_at(1, "[") || self.sym_at(1, "*");
1722            let is_async = self.is_kw("async") && async_modifier_ok;
1723            if is_async {
1724                self.bump();
1725            }
1726            let is_generator = self.eat_sym("*");
1727            // アクセサ修飾子(`get name() {...}` / `set name(v) {...}`)。次の2トークンが
1728            // 「プロパティ名になり得るトークン」+ `(` の場合のみアクセサとして扱う
1729            // (`get(){}`="get" という名前のメソッド、`get: 1`="get" という名前の
1730            // フィールドと衝突しないようにするため)。算出名 `get [expr](){}` も、
1731            // 次が `[` ならこの文法上アクセサ以外の解釈があり得ないため許可する
1732            // (以前はここが漏れており `get [Symbol.iterator](){}` のようなパターンが
1733            // getter として認識されず、"get" という名前の孤立フィールド+無関係な
1734            // 算出名メソッドという壊れた2メンバに分解されてしまっていた)。
1735            let accessor_kind = if let Token::Ident(n) = self.cur().clone() {
1736                if (n == "get" || n == "set")
1737                    && (self.sym_at(1, "[")
1738                        || (self.is_property_key_token(1) && self.sym_at(2, "(")))
1739                {
1740                    self.bump();
1741                    Some(n == "get")
1742                } else {
1743                    None
1744                }
1745            } else {
1746                None
1747            };
1748            // メソッド名。`[expr]` は算出メソッド名(`[Symbol.iterator]` 等)。
1749            let mut computed_key = None;
1750            let key = match self.cur().clone() {
1751                Token::Ident(n) => {
1752                    self.bump();
1753                    n
1754                }
1755                Token::Keyword(n) => {
1756                    self.bump();
1757                    n
1758                }
1759                Token::Str(s) => {
1760                    self.bump();
1761                    s
1762                }
1763                Token::Num(n) => {
1764                    self.bump();
1765                    super::value::fmt_number(n)
1766                }
1767                Token::Sym(s) if s == "[" => {
1768                    self.bump();
1769                    computed_key = Some(self.parse_assignment());
1770                    self.expect_sym("]");
1771                    String::new()
1772                }
1773                _ => {
1774                    self.bump();
1775                    continue;
1776                }
1777            };
1778            if self.is_sym("(") {
1779                // メソッド(constructor 含む)。
1780                let params = self.parse_param_list();
1781                let body = self.parse_brace_body();
1782                let kind = match accessor_kind {
1783                    Some(true) => MethodKind::Getter,
1784                    Some(false) => MethodKind::Setter,
1785                    None if computed_key.is_none() && key == "constructor" => {
1786                        MethodKind::Constructor
1787                    }
1788                    None => MethodKind::Method,
1789                };
1790                members.push(ClassMember {
1791                    key,
1792                    computed_key,
1793                    kind,
1794                    params,
1795                    body,
1796                    is_static,
1797                    field_init: None,
1798                    is_async,
1799                    is_generator,
1800                });
1801            } else {
1802                // フィールド宣言: `key = expr;` または `key;`(`#key` も同じ経路。
1803                // lexer が '#' を識別子の一部として読むため key にそのまま含まれる)。
1804                let init = if self.eat_sym("=") {
1805                    Some(self.parse_assignment())
1806                } else {
1807                    None
1808                };
1809                self.eat_sym(";");
1810                members.push(ClassMember {
1811                    key,
1812                    // 算出フィールド名(`[expr] = init;`)は非対応(稀なパターンのため、
1813                    // メソッドの算出名 `[Symbol.iterator](){}` のみ対応する簡略化)。
1814                    computed_key: None,
1815                    kind: MethodKind::Field,
1816                    params: Vec::new(),
1817                    body: Vec::new(),
1818                    is_static,
1819                    field_init: init,
1820                    is_async: false,
1821                    is_generator: false,
1822                });
1823            }
1824        }
1825        self.expect_sym("}");
1826        Expression::Class {
1827            name,
1828            superclass,
1829            members,
1830        }
1831    }
1832
1833    fn parse_array_literal(&mut self) -> Expression {
1834        self.expect_sym("[");
1835        let mut items = Vec::new();
1836        while !self.is_sym("]") && !self.is_eof() {
1837            if self.is_sym(",") {
1838                // 穴あき配列 [1,,3] は undefined 扱い。
1839                items.push(Expression::Undefined);
1840                self.bump();
1841                continue;
1842            }
1843            if self.eat_sym("...") {
1844                items.push(Expression::Spread(Box::new(self.parse_assignment())));
1845            } else {
1846                items.push(self.parse_assignment());
1847            }
1848            if !self.eat_sym(",") {
1849                break;
1850            }
1851        }
1852        self.expect_sym("]");
1853        Expression::Array(items)
1854    }
1855
1856    fn parse_object_literal(&mut self) -> Expression {
1857        self.expect_sym("{");
1858        let mut props = Vec::new();
1859        while !self.is_sym("}") && !self.is_eof() {
1860            // オブジェクトスプレッド {...o}
1861            if self.eat_sym("...") {
1862                let value = self.parse_assignment();
1863                props.push(Property {
1864                    key: String::from(crate::os_lib::js::ast::OBJECT_SPREAD_KEY),
1865                    value,
1866                    computed: None,
1867                    accessor: None,
1868                });
1869                if !self.eat_sym(",") {
1870                    break;
1871                }
1872                continue;
1873            }
1874            // `async`/`*`(generator)修飾子(`{ async method(){} }`/`{ *gen(){} }`)。
1875            // クラスのメソッド修飾子と同じ理由で以前は一切認識されず、遭遇すると
1876            // キー解析が丸ごと失敗してオブジェクトリテラル全体のパースが壊れていた。
1877            // `{ async: 1 }`("async" という名前の通常プロパティ)との曖昧さ回避のため、
1878            // 次がメソッド名になり得るトークンの場合のみ修飾子として扱う
1879            // (クラス側の同種ガードと同じロジック)。
1880            let async_modifier_ok =
1881                self.is_property_key_token(1) || self.sym_at(1, "[") || self.sym_at(1, "*");
1882            let is_async = self.is_kw("async") && async_modifier_ok;
1883            if is_async {
1884                self.bump();
1885            }
1886            let is_generator = self.eat_sym("*");
1887            // アクセサ修飾子(`{get name() {...}}` / `{set name(v) {...}}`)。クラスの
1888            // アクセサ判定と同じ2トークン先読み規則(`get`/`set` の次が「プロパティ名に
1889            // なり得るトークン」+ `(` の場合のみアクセサ扱い)。算出名
1890            // `{ get [expr](){} }` も、次が `[` ならアクセサ以外の解釈があり得ないため
1891            // 許可する(クラス側の同種修正と同じ理由)。
1892            let accessor_kind = if let Token::Ident(n) = self.cur().clone() {
1893                if (n == "get" || n == "set")
1894                    && (self.sym_at(1, "[")
1895                        || (self.is_property_key_token(1) && self.sym_at(2, "(")))
1896                {
1897                    self.bump();
1898                    Some(n == "get")
1899                } else {
1900                    None
1901                }
1902            } else {
1903                None
1904            };
1905            // 算出キー {[expr]: v}
1906            let mut computed = None;
1907            // キー: 識別子 / 文字列 / 数値 / [computed]
1908            let key = match self.cur().clone() {
1909                Token::Ident(n) => {
1910                    self.bump();
1911                    n
1912                }
1913                Token::Keyword(n) => {
1914                    self.bump();
1915                    n
1916                }
1917                Token::Str(s) => {
1918                    self.bump();
1919                    s
1920                }
1921                Token::Num(n) => {
1922                    self.bump();
1923                    super::value::fmt_number(n)
1924                }
1925                Token::Sym(s) if s == "[" => {
1926                    self.bump();
1927                    computed = Some(self.parse_assignment());
1928                    self.expect_sym("]");
1929                    String::new()
1930                }
1931                _ => break,
1932            };
1933            let value = if self.eat_sym(":") {
1934                self.parse_assignment()
1935            } else if self.is_sym("(") {
1936                // メソッド短縮 key(){...}
1937                let params = self.parse_param_list();
1938                let body = self.parse_brace_body();
1939                Expression::Function {
1940                    name: Some(key.clone()),
1941                    params,
1942                    body,
1943                    is_arrow: false,
1944                    is_async,
1945                    is_generator,
1946                }
1947            } else {
1948                // 短縮プロパティ {x}
1949                Expression::Identifier(key.clone())
1950            };
1951            props.push(Property {
1952                key,
1953                value,
1954                computed,
1955                accessor: accessor_kind,
1956            });
1957            if !self.eat_sym(",") {
1958                break;
1959            }
1960        }
1961        self.expect_sym("}");
1962        Expression::Object(props)
1963    }
1964}
1965
1966// --- 演算子テーブル ---
1967
1968fn is_assign_op(op: &str) -> bool {
1969    matches!(
1970        op,
1971        "=" | "+="
1972            | "-="
1973            | "*="
1974            | "/="
1975            | "%="
1976            | "**="
1977            | "&="
1978            | "|="
1979            | "^="
1980            | "<<="
1981            | ">>="
1982            | ">>>="
1983            | "&&="
1984            | "||="
1985            | "??="
1986    )
1987}
1988
1989fn bin_prec(op: &str) -> Option<u8> {
1990    Some(match op {
1991        "??" => 1,
1992        "||" => 2,
1993        "&&" => 3,
1994        "|" => 4,
1995        "^" => 5,
1996        "&" => 6,
1997        "==" | "!=" | "===" | "!==" => 7,
1998        "<" | ">" | "<=" | ">=" | "instanceof" | "in" => 8,
1999        "<<" | ">>" | ">>>" => 9,
2000        "+" | "-" => 10,
2001        "*" | "/" | "%" => 11,
2002        "**" => 12,
2003        _ => return None,
2004    })
2005}
2006
2007fn is_right_assoc(op: &str) -> bool {
2008    op == "**"
2009}
2010
2011fn to_logical(op: &str) -> Option<LogicalOp> {
2012    match op {
2013        "&&" => Some(LogicalOp::And),
2014        "||" => Some(LogicalOp::Or),
2015        "??" => Some(LogicalOp::Nullish),
2016        _ => None,
2017    }
2018}
2019
2020fn to_binop(op: &str) -> Option<BinaryOp> {
2021    Some(match op {
2022        "+" => BinaryOp::Add,
2023        "-" => BinaryOp::Sub,
2024        "*" => BinaryOp::Mul,
2025        "/" => BinaryOp::Div,
2026        "%" => BinaryOp::Mod,
2027        "**" => BinaryOp::Pow,
2028        "==" => BinaryOp::Eq,
2029        "!=" => BinaryOp::NotEq,
2030        "===" => BinaryOp::StrictEq,
2031        "!==" => BinaryOp::StrictNotEq,
2032        "<" => BinaryOp::Lt,
2033        ">" => BinaryOp::Gt,
2034        "<=" => BinaryOp::LtEq,
2035        ">=" => BinaryOp::GtEq,
2036        "&" => BinaryOp::BitAnd,
2037        "|" => BinaryOp::BitOr,
2038        "^" => BinaryOp::BitXor,
2039        "<<" => BinaryOp::Shl,
2040        ">>" => BinaryOp::Shr,
2041        ">>>" => BinaryOp::UShr,
2042        "instanceof" => BinaryOp::InstanceOf,
2043        "in" => BinaryOp::In,
2044        _ => return None,
2045    })
2046}