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::rc::Rc;
9use alloc::boxed::Box;
10use alloc::string::String;
11use alloc::vec::Vec;
12
13use super::ast::*;
14use super::lexer::{Lexer, Token};
15
16/// 回復して解析を続けた構文エラー 1 件。
17///
18/// 【2026-07-28】本パーサは「エラーを致命的にせずベストエフォートで継続」する
19/// 方針だが、従来は**回復したことを誰にも伝えていなかった**ため、壊れた
20/// スクリプトが「正常に解析できた」のと区別できなかった(`expect_sym` は
21/// `let _ = self.eat_sym(s);` と、期待した記号が無い事実を捨てていた)。
22/// 実行はこれまでどおり継続しつつ、**何をどこで諦めたのかは必ず呼び出し側へ
23/// 返す**ためにこの記録を持つ。
24#[derive(Debug, Clone, PartialEq)]
25pub struct ParseError {
26    /// 何を期待して何が来たか。
27    pub message: String,
28    /// トークン列上の位置(`Parser` 内部のトークン索引)。
29    pub token_index: usize,
30}
31
32/// 記録する構文エラーの上限。壊れきった入力で無制限にメモリを食わないため。
33const MAX_RECORDED_ERRORS: usize = 64;
34
35/// エラーメッセージ用にトークンを短く説明する。
36fn describe_token(t: &Token) -> String {
37    match t {
38        Token::Keyword(k) => alloc::format!("keyword '{}'", k),
39        Token::Ident(i) => alloc::format!("identifier '{}'", i),
40        Token::Num(n) => alloc::format!("number {}", n),
41        Token::BigIntLit(s) => alloc::format!("bigint {}", s),
42        Token::Str(_) => String::from("string literal"),
43        Token::Template(_) => String::from("template literal"),
44        Token::Sym(s) => alloc::format!("'{}'", s),
45        Token::Regex(_) => String::from("regex literal"),
46        Token::LazyBody(..) => String::from("function body"),
47        Token::Eof => String::from("end of input"),
48    }
49}
50
51/// 固定長の塊を並べた追記専用の配列(索引で引ける)。
52///
53/// 【2026-10-19】YouTube の視聴ページの kevlar_base(10.8MB、約 320 万トークン)で、
54/// `Vec<Token>` が倍々に伸びて 128MB の連続領域を要求し、ヒープ(512MB、使用 325MB)で
55/// 確保に失敗していた。塊(`CHUNK` 個)ごとに確保すれば、大きな連続領域も、伸長時の
56/// 旧・新の二重持ちも要らない。
57pub struct ChunkedVec<T> {
58    chunks: Vec<Vec<T>>,
59    len: usize,
60}
61
62impl<T> ChunkedVec<T> {
63    const SHIFT: usize = 14;
64    const CHUNK: usize = 1 << Self::SHIFT;
65
66    pub fn new() -> Self {
67        ChunkedVec { chunks: Vec::new(), len: 0 }
68    }
69
70    pub fn push(&mut self, v: T) {
71        let need_new = match self.chunks.last() {
72            Some(c) => c.len() >= Self::CHUNK,
73            None => true,
74        };
75        if need_new {
76            self.chunks.push(Vec::with_capacity(Self::CHUNK));
77        }
78        if let Some(c) = self.chunks.last_mut() {
79            c.push(v);
80            self.len += 1;
81        }
82    }
83
84    pub fn len(&self) -> usize {
85        self.len
86    }
87
88    pub fn is_empty(&self) -> bool {
89        self.len == 0
90    }
91
92    pub fn get(&self, i: usize) -> Option<&T> {
93        self.chunks.get(i >> Self::SHIFT)?.get(i & (Self::CHUNK - 1))
94    }
95
96    /// 位置 `from` 以降を(位置, 要素)で順に返す。
97    pub fn iter_from(&self, from: usize) -> impl Iterator<Item = (usize, &T)> {
98        (from..self.len).filter_map(move |i| self.get(i).map(|t| (i, t)))
99    }
100}
101
102impl<T> Default for ChunkedVec<T> {
103    fn default() -> Self {
104        Self::new()
105    }
106}
107
108pub struct Parser {
109    toks: ChunkedVec<Token>,
110    pos: usize,
111    /// 遅延解析(`new_lazy`)用: 各トークンの開始位置(文字単位)とソース。通常は空。
112    starts: ChunkedVec<u32>,
113    chars: Vec<char>,
114    lazy: bool,
115    /// 回復して解析を続けた構文エラーの記録(上限 `MAX_RECORDED_ERRORS` 件)。
116    errors: Vec<ParseError>,
117    /// 上限で切り捨てた分も含めた実際の検出件数。
118    error_count: usize,
119    /// いま解析している箇所が strict モードか(関数本体の `FnBody::strict` に記録する)。
120    strict: bool,
121}
122
123impl Parser {
124    pub fn new(lexer: Lexer) -> Self {
125        Self::build(lexer, false)
126    }
127
128    /// 関数本体を遅延解析するパーサ(大きな本体はソースだけ持ち、初回実行時に解析する)。
129    /// 本体の中の構文エラーは、その関数を初めて実行するときに報告される。
130    pub fn new_lazy(lexer: Lexer) -> Self {
131        Self::build(lexer, true)
132    }
133
134    fn build(mut lexer: Lexer, lazy: bool) -> Self {
135        let mut toks = ChunkedVec::new();
136        let mut starts = ChunkedVec::new();
137        // 遅延モード: 関数本体らしい `{`(制御構文でない `)` の直後、または `=>` の直後)の
138        // 中身が大きければ、トークンを貯めずに `LazyBody` 1 個に畳む。
139        // 【2026-10-19】YouTube の kevlar_base(10.8MB)は全体が 1 つの関数で、本体を読み
140        // 飛ばすためだけに 320 万トークン(約 186MB)を作っていた。
141        let mut parens: Vec<bool> = Vec::new(); // `(` ごとに「制御構文の括弧か」
142        let mut last_close_ctrl = false; // 直前の `)` が制御構文の括弧を閉じたか
143        let mut prev: Option<Token> = None;
144        let mut prev2: Option<Token> = None;
145        let mut heritage = false; // `extends` 以降、クラス本体の `{` までは畳まない
146        loop {
147            let t = lexer.next_token();
148            let start = lexer.token_start() as u32;
149            if lazy {
150                starts.push(start);
151            }
152            let eof = t == Token::Eof;
153            let mut fold = false;
154            if lazy {
155                match &t {
156                    Token::Sym("(") => {
157                        fn w(t: &Option<Token>) -> Option<&str> {
158                            match t {
159                                Some(Token::Keyword(k)) => Some(k),
160                                Some(Token::Ident(i)) => Some(i.as_str()),
161                                _ => None,
162                            }
163                        }
164                        let ctrl = matches!(w(&prev), Some("if" | "while" | "for" | "switch" | "catch" | "with"))
165                            || (w(&prev) == Some("await") && w(&prev2) == Some("for"));
166                        parens.push(ctrl);
167                    }
168                    Token::Sym(")") => last_close_ctrl = parens.pop().unwrap_or(false),
169                    Token::Keyword("extends") => heritage = true,
170                    Token::Sym("{") => {
171                        fold = !heritage
172                            && match &prev {
173                                Some(Token::Sym(")")) => !last_close_ctrl,
174                                Some(Token::Sym("=>")) => true,
175                                _ => false,
176                            };
177                        heritage = false;
178                    }
179                    _ => {}
180                }
181            }
182            prev2 = prev.replace(t.clone());
183            toks.push(t);
184            if eof {
185                break;
186            }
187            if fold {
188                Self::fold_body(&mut lexer, &mut toks, &mut starts, start);
189                // 畳んだ(または展開した)本体の後は閉じ `}` が直前のトークン。
190                prev2 = None;
191                prev = Some(Token::Sym("}"));
192            }
193        }
194        // 字句解析の異常(閉じ忘れの文字列・コメント、値が化けた数値リテラル)も
195        // 呼び出し側から見れば同じ「構文エラー」なので、ここで引き取る。
196        let lex_error_count = lexer.error_count();
197        let mut errors: Vec<ParseError> = lexer
198            .take_errors()
199            .into_iter()
200            .map(|e| ParseError {
201                message: e.message,
202                token_index: 0,
203            })
204            .collect();
205        errors.truncate(MAX_RECORDED_ERRORS);
206        let chars = if lazy { lexer.into_chars() } else { Vec::new() };
207        Self {
208            toks,
209            pos: 0,
210            starts,
211            chars,
212            lazy,
213            errors,
214            error_count: lex_error_count,
215            strict: false,
216        }
217    }
218
219    /// `{`(位置 `open_start`)の直後から対応する `}` までを読み、中身が `LAZY_MIN_TOKENS` 以上
220    /// なら `LazyBody` に畳み、少なければ普通に並べる。閉じ `}`(または Eof)まで積む。
221    fn fold_body(lexer: &mut Lexer, toks: &mut ChunkedVec<Token>, starts: &mut ChunkedVec<u32>, open_start: u32) {
222        let mut buf: Vec<(Token, u32)> = Vec::new();
223        let mut counting = false;
224        let mut use_strict = false;
225        let mut depth = 1usize;
226        loop {
227            let t = lexer.next_token();
228            let st = lexer.token_start() as u32;
229            match &t {
230                Token::Sym("{") => depth += 1,
231                Token::Sym("}") => depth -= 1,
232                _ => {}
233            }
234            let end = t == Token::Eof || depth == 0;
235            if end {
236                if counting && t != Token::Eof {
237                    toks.push(Token::LazyBody(open_start + 1, st, use_strict));
238                    starts.push(open_start + 1);
239                } else {
240                    // 小さい本体、または閉じられていない(Eof): 貯めたトークンをそのまま並べる。
241                    // Eof で畳めなかった場合、読み捨てた分は失われるが、閉じていない本体は
242                    // どのみち構文エラー。
243                    for (bt, bs) in buf.drain(..) {
244                        toks.push(bt);
245                        starts.push(bs);
246                    }
247                }
248                toks.push(t);
249                starts.push(st);
250                return;
251            }
252            if !counting {
253                buf.push((t, st));
254                if buf.len() >= LAZY_MIN_TOKENS {
255                    use_strict = matches!(buf.first(), Some((Token::Str(s), _)) if s == "use strict")
256                        && matches!(buf.get(1), Some((Token::Sym(";" | "}"), _)) | Some((Token::Str(_), _)));
257                    counting = true;
258                    buf = Vec::new();
259                }
260            }
261        }
262    }
263
264    /// `at` から始まる文の並びの先頭(指令プロローグ)に `"use strict"` があるか。
265    fn has_use_strict_directive(&self, mut at: usize) -> bool {
266        while let Some(Token::Str(s)) = self.toks.get(at) {
267            if s == "use strict" {
268                return true;
269            }
270            // 指令は文字列だけの式文。`;` か次の文字列で区切られる(`"a" + x` 等は指令ではない)。
271            match self.toks.get(at + 1) {
272                Some(Token::Sym(";")) => at += 2,
273                Some(Token::Str(_)) => at += 1,
274                _ => return false,
275            }
276        }
277        false
278    }
279
280    /// 関数本体(`{ ... }`)。遅延モードで本体が大きければ、対応する `}` まで読み飛ばして
281    /// 中身のソースだけ持つ。
282    fn parse_fn_body(&mut self) -> Rc<FnBody> {
283        if self.is_sym("{") {
284            if let (Token::LazyBody(a, b, us), true) = (self.at(1).clone(), self.sym_at(2, "}")) {
285                let strict = self.strict || us;
286                let (a, b) = (a as usize, b as usize);
287                if a <= b && b <= self.chars.len() {
288                    let src: String = self.chars[a..b].iter().collect();
289                    self.pos += 3;
290                    return FnBody::lazy(src, strict);
291                }
292            }
293        }
294        let strict = self.strict || (self.is_sym("{") && self.has_use_strict_directive(self.pos + 1));
295        if self.lazy && self.is_sym("{") {
296            if let Some(close) = self.matching_brace(self.pos) {
297                if close - self.pos > LAZY_MIN_TOKENS {
298                    let a = self.starts.get(self.pos).map_or(0, |&s| s as usize + 1);
299                    let b = self.starts.get(close).map_or(a, |&s| s as usize);
300                    if a <= b && b <= self.chars.len() {
301                        let src: String = self.chars[a..b].iter().collect();
302                        self.pos = close + 1;
303                        return FnBody::lazy(src, strict);
304                    }
305                }
306            }
307        }
308        let outer = core::mem::replace(&mut self.strict, strict);
309        let body = self.parse_brace_body();
310        self.strict = outer;
311        FnBody::parsed_with(body, strict)
312    }
313
314    /// `open` の `{` に対応する `}` のトークン位置(テンプレート・正規表現は 1 トークンなので
315    /// 中の括弧は数えない)。
316    fn matching_brace(&self, open: usize) -> Option<usize> {
317        let mut depth = 0usize;
318        for (i, t) in self.toks.iter_from(open) {
319            match t {
320                Token::Sym("{") => depth += 1,
321                Token::Sym("}") => {
322                    depth = depth.checked_sub(1)?;
323                    if depth == 0 {
324                        return Some(i);
325                    }
326                }
327                Token::Eof => return None,
328                _ => {}
329            }
330        }
331        None
332    }
333
334    /// 記録済みの構文エラー(上限まで)。
335    pub fn errors(&self) -> &[ParseError] {
336        &self.errors
337    }
338
339    /// 検出した構文エラーの総数(記録上限で切り捨てた分も含む)。
340    pub fn error_count(&self) -> usize {
341        self.error_count
342    }
343
344    /// 記録済みの構文エラーを取り出す(呼び出し側へ渡してログ出力する用途)。
345    pub fn take_errors(&mut self) -> Vec<ParseError> {
346        core::mem::take(&mut self.errors)
347    }
348
349    fn record_error(&mut self, message: String) {
350        self.error_count += 1;
351        if self.errors.len() < MAX_RECORDED_ERRORS {
352            // 【2026-09-05】トークン索引だけでは何が起きたか分からない。
353            //
354            // 実際に「`unexpected ':' in expression (token #34956)`」という
355            // 報告から原因の構文を突き止められず、候補を 16 種類も
356            // 試すはめになった(すべて外れ)。前後のトークンを添えれば
357            // どの構文で落ちたかがその場で分かる。
358            let msg = alloc::format!("{} 付近: {}", message, self.context_around(self.pos));
359            self.errors.push(ParseError {
360                message: msg,
361                token_index: self.pos,
362            });
363        }
364    }
365
366    /// エラー位置の前後のトークンを短い文字列にする。
367    ///
368    /// 前 6 個・後 3 個。落ちた位置は `»«` で囲む。
369    fn context_around(&self, at: usize) -> String {
370        let start = at.saturating_sub(6);
371        let end = (at + 4).min(self.toks.len());
372        let mut out = String::new();
373        for i in start..end {
374            let Some(t) = self.toks.get(i) else {
375                break;
376            };
377            if i == at {
378                out.push_str("»");
379                out.push_str(&describe_token(t));
380                out.push_str("«");
381            } else {
382                out.push_str(&describe_token(t));
383            }
384            out.push(' ');
385        }
386        out
387    }
388
389    /// 別インスタンス(テンプレート補間式などの副パーサ)が検出したエラーを
390    /// 自分の記録へ取り込む。位置は副パーサ内の索引なので、由来が分かるよう
391    /// 印を付ける。
392    fn absorb_errors(&mut self, mut sub: Parser) {
393        let count = sub.error_count();
394        if count == 0 {
395            return;
396        }
397        for e in sub.take_errors() {
398            self.record_error(alloc::format!("in template expression: {}", e.message));
399        }
400        // 記録上限を超えた分も総数には反映する。
401        if count > MAX_RECORDED_ERRORS {
402            self.error_count += count - MAX_RECORDED_ERRORS;
403        }
404    }
405
406    // --- トークンカーソル ---
407    fn cur(&self) -> &Token {
408        self.toks.get(self.pos).unwrap_or(&Token::Eof)
409    }
410    fn at(&self, off: usize) -> &Token {
411        self.toks.get(self.pos + off).unwrap_or(&Token::Eof)
412    }
413    fn bump(&mut self) -> Token {
414        let t = self.cur().clone();
415        if self.pos < self.toks.len() {
416            self.pos += 1;
417        }
418        t
419    }
420    fn is_eof(&self) -> bool {
421        matches!(self.cur(), Token::Eof)
422    }
423    fn is_sym(&self, s: &str) -> bool {
424        matches!(self.cur(), Token::Sym(x) if *x == s)
425    }
426    fn sym_at(&self, off: usize, s: &str) -> bool {
427        matches!(self.at(off), Token::Sym(x) if *x == s)
428    }
429    fn ident_at(&self, off: usize, s: &str) -> bool {
430        matches!(self.at(off), Token::Ident(x) if x == s)
431    }
432    fn kw_at(&self, off: usize, k: &str) -> bool {
433        matches!(self.at(off), Token::Keyword(x) if *x == k)
434    }
435    /// `off` の位置がオブジェクト/クラスのプロパティ名になり得るトークン
436    /// (識別子/予約語/文字列/数値)かどうか(`get`/`set` アクセサ判定の先読み用)。
437    fn is_property_key_token(&self, off: usize) -> bool {
438        matches!(
439            self.at(off),
440            Token::Ident(_) | Token::Keyword(_) | Token::Str(_) | Token::Num(_)
441        )
442    }
443    fn eat_sym(&mut self, s: &str) -> bool {
444        if self.is_sym(s) {
445            self.pos += 1;
446            true
447        } else {
448            false
449        }
450    }
451    /// 記号 `s` を消費する。無ければ**回復して継続しつつ構文エラーとして記録**する
452    /// (従来は `let _ =` で「無かった」事実ごと捨てていた)。
453    fn expect_sym(&mut self, s: &str) {
454        if !self.eat_sym(s) {
455            let found = describe_token(self.cur());
456            self.record_error(alloc::format!("expected '{}' but found {}", s, found));
457        }
458    }
459    fn is_kw(&self, k: &str) -> bool {
460        matches!(self.cur(), Token::Keyword(x) if *x == k)
461    }
462    fn eat_kw(&mut self, k: &str) -> bool {
463        if self.is_kw(k) {
464            self.pos += 1;
465            true
466        } else {
467            false
468        }
469    }
470    fn ident_name(&mut self) -> Option<String> {
471        match self.cur().clone() {
472            Token::Ident(n) => {
473                self.pos += 1;
474                Some(n)
475            }
476            // プロパティ名としてキーワードも許可 (obj.return 等)。
477            Token::Keyword(n) => {
478                self.pos += 1;
479                Some(String::from(n))
480            }
481            _ => None,
482        }
483    }
484
485    // --- プログラム ---
486    pub fn parse_program(&mut self) -> Program {
487        if self.has_use_strict_directive(self.pos) {
488            self.strict = true;
489        }
490        let mut body = Vec::new();
491        while !self.is_eof() {
492            let before = self.pos;
493            if let Some(stmt) = self.parse_statement() {
494                body.push(stmt);
495            }
496            // 前進保証(無限ループ防止)。ここへ来るのは「文として解釈できない
497            // トークンを読み飛ばした」場合であり、明確な構文エラーなので記録する。
498            if self.pos == before {
499                let found = describe_token(self.cur());
500                self.record_error(alloc::format!("unexpected {}", found));
501                self.pos += 1;
502            }
503        }
504        Program { body }
505    }
506
507    /// パースし、**AST と構文エラーの両方**を返す。
508    ///
509    /// AST は従来どおり常に返る(ベストエフォート動作を変えない)ので、
510    /// 呼び出し側は「実行はするが、壊れている事実は知っている」状態にできる。
511    pub fn parse_program_reporting(&mut self) -> (Program, Vec<ParseError>) {
512        let program = self.parse_program();
513        let errors = self.take_errors();
514        (program, errors)
515    }
516
517    // --- 文 ---
518    fn parse_statement(&mut self) -> Option<Statement> {
519        // セミコロン単独は空文。
520        if self.eat_sym(";") {
521            return Some(Statement::Empty);
522        }
523        if self.is_sym("{") {
524            return Some(self.parse_block());
525        }
526
527        // `using`/`await using` 宣言(Explicit Resource Management、ES2023→ES2026ベースライン)。
528        // `using` は予約語ではなく文脈依存キーワードのため、`using IDENT =` の形のときだけ
529        // 宣言として扱う(`using` という名前の普通の変数式文と衝突しないようにするため)。
530        if self.ident_at(0, "using")
531            && matches!(self.at(1), Token::Ident(_))
532            && self.sym_at(2, "=")
533        {
534            return self.parse_using_declaration(false);
535        }
536        if self.is_kw("await")
537            && self.ident_at(1, "using")
538            && matches!(self.at(2), Token::Ident(_))
539            && self.sym_at(3, "=")
540        {
541            self.bump(); // await
542            return self.parse_using_declaration(true);
543        }
544
545        // ラベル付き文 `label: statement`(主にループの `break label`/`continue label`
546        // ターゲット用)。識別子の直後が `:` の場合のみ(三項演算子の `:` は先頭識別子の
547        // 直後に来ないため衝突しない)。
548        if let Token::Ident(label) = self.cur().clone() {
549            if self.sym_at(1, ":") {
550                self.bump(); // label
551                self.bump(); // ':'
552                let inner = self.parse_statement().unwrap_or(Statement::Empty);
553                return Some(Statement::Labeled(label, Box::new(inner)));
554            }
555        }
556
557        match self.cur().clone() {
558            Token::Keyword(kw) => match kw {
559                "var" | "let" | "const" => self.parse_var_declaration(),
560                "if" => self.parse_if(),
561                "while" => self.parse_while(),
562                "do" => self.parse_do_while(),
563                "for" => self.parse_for(),
564                "function" => self.parse_function_declaration(false),
565                "async" if self.kw_at(1, "function") => {
566                    self.bump(); // async
567                    self.parse_function_declaration(true)
568                }
569                "return" => {
570                    self.bump();
571                    if self.is_sym(";") || self.is_sym("}") || self.is_eof() {
572                        self.eat_sym(";");
573                        Some(Statement::Return(None))
574                    } else {
575                        let e = self.parse_expression();
576                        self.eat_sym(";");
577                        Some(Statement::Return(Some(e)))
578                    }
579                }
580                "break" => {
581                    self.bump();
582                    // `break label;` — ASI の改行検知はこの字句解析器に無いため、次が
583                    // 識別子ならラベルとみなす(`break;\nfoo` のような稀なケースは
584                    // 非対応の簡略実装)。
585                    let label = if let Token::Ident(n) = self.cur().clone() {
586                        self.bump();
587                        Some(n)
588                    } else {
589                        None
590                    };
591                    self.eat_sym(";");
592                    Some(Statement::Break(label))
593                }
594                "continue" => {
595                    self.bump();
596                    let label = if let Token::Ident(n) = self.cur().clone() {
597                        self.bump();
598                        Some(n)
599                    } else {
600                        None
601                    };
602                    self.eat_sym(";");
603                    Some(Statement::Continue(label))
604                }
605                "throw" => {
606                    self.bump();
607                    let e = self.parse_expression();
608                    self.eat_sym(";");
609                    Some(Statement::Throw(e))
610                }
611                "try" => self.parse_try(),
612                "switch" => self.parse_switch(),
613                "import" => self.parse_import(),
614                "export" => self.parse_export(),
615                "class" => {
616                    // クラス宣言: `let Name = class ...` 相当に脱糖。
617                    let cls = self.parse_class();
618                    let name = if let Expression::Class { name: Some(n), .. } = &cls {
619                        n.clone()
620                    } else {
621                        String::new()
622                    };
623                    self.eat_sym(";");
624                    Some(Statement::VarDeclaration {
625                        kind: VarKind::Let,
626                        decls: alloc::vec![(Pattern::Identifier(name), Some(cls))],
627                    })
628                }
629                _ => self.parse_expression_statement(),
630            },
631            _ => self.parse_expression_statement(),
632        }
633    }
634
635    fn parse_block(&mut self) -> Statement {
636        // 組み立て時に畳んだ本体が関数以外の文脈(ASI で区切られた `f()\n{ … }` 等)に
637        // 現れたら、その場で中身を解析する。
638        if self.is_sym("{") {
639            if let (Token::LazyBody(a, b, us), true) = (self.at(1).clone(), self.sym_at(2, "}")) {
640                let (a, b) = (a as usize, b as usize);
641                if a <= b && b <= self.chars.len() {
642                    let src: String = self.chars[a..b].iter().collect();
643                    self.pos += 3;
644                    return Statement::Block(parse_function_body_source(&src, self.strict || us));
645                }
646            }
647        }
648        self.expect_sym("{");
649        let mut body = Vec::new();
650        while !self.is_sym("}") && !self.is_eof() {
651            let before = self.pos;
652            if let Some(s) = self.parse_statement() {
653                body.push(s);
654            }
655            if self.pos == before {
656                self.pos += 1;
657            }
658        }
659        self.expect_sym("}");
660        Statement::Block(body)
661    }
662
663    /// `{ ... }` の中身を Vec<Statement> として取り出す(関数本体用)。
664    fn parse_brace_body(&mut self) -> Vec<Statement> {
665        match self.parse_block() {
666            Statement::Block(b) => b,
667            _ => Vec::new(),
668        }
669    }
670
671    fn parse_var_declaration(&mut self) -> Option<Statement> {
672        let kind = match self.bump() {
673            Token::Keyword(k) => match k {
674                "let" => VarKind::Let,
675                "const" => VarKind::Const,
676                _ => VarKind::Var,
677            },
678            _ => VarKind::Var,
679        };
680        let mut decls = Vec::new();
681        loop {
682            if self.is_eof() || self.is_sym(";") {
683                break;
684            }
685            let pat = self.parse_pattern();
686            let init = if self.eat_sym("=") {
687                Some(self.parse_assignment())
688            } else {
689                None
690            };
691            decls.push((pat, init));
692            if !self.eat_sym(",") {
693                break;
694            }
695        }
696        self.eat_sym(";");
697        Some(Statement::VarDeclaration { kind, decls })
698    }
699
700    /// `using x = expr, y = expr2;` / `await using x = expr;`。
701    /// 仕様上バインディングは単純な識別子のみ(分割代入パターンは不可)。
702    fn parse_using_declaration(&mut self, is_await: bool) -> Option<Statement> {
703        self.bump(); // "using"
704        let kind = if is_await {
705            VarKind::AwaitUsing
706        } else {
707            VarKind::Using
708        };
709        let mut decls = Vec::new();
710        while let Some(name) = self.ident_name() {
711            let init = if self.eat_sym("=") {
712                Some(self.parse_assignment())
713            } else {
714                None
715            };
716            decls.push((Pattern::Identifier(name), init));
717            if !self.eat_sym(",") {
718                break;
719            }
720        }
721        self.eat_sym(";");
722        Some(Statement::VarDeclaration { kind, decls })
723    }
724
725    fn parse_if(&mut self) -> Option<Statement> {
726        self.bump(); // if
727        self.expect_sym("(");
728        let test = self.parse_expression();
729        self.expect_sym(")");
730        let consequent = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
731        let alternate = if self.eat_kw("else") {
732            Some(Box::new(self.parse_statement().unwrap_or(Statement::Empty)))
733        } else {
734            None
735        };
736        Some(Statement::If {
737            test,
738            consequent,
739            alternate,
740        })
741    }
742
743    fn parse_while(&mut self) -> Option<Statement> {
744        self.bump();
745        self.expect_sym("(");
746        let test = self.parse_expression();
747        self.expect_sym(")");
748        let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
749        Some(Statement::While { test, body })
750    }
751
752    fn parse_do_while(&mut self) -> Option<Statement> {
753        self.bump(); // do
754        let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
755        self.eat_kw("while");
756        self.expect_sym("(");
757        let test = self.parse_expression();
758        self.expect_sym(")");
759        self.eat_sym(";");
760        Some(Statement::DoWhile { body, test })
761    }
762
763    fn parse_for(&mut self) -> Option<Statement> {
764        self.bump(); // for
765        let is_await = self.eat_kw("await");
766        self.expect_sym("(");
767
768        // for-in / for-of を宣言形式で検出。
769        if self.is_kw("var") || self.is_kw("let") || self.is_kw("const") {
770            let decl_kind = match self.bump() {
771                Token::Keyword(k) => match k {
772                    "let" => VarKind::Let,
773                    "const" => VarKind::Const,
774                    _ => VarKind::Var,
775                },
776                _ => VarKind::Var,
777            };
778            let pat = self.parse_pattern();
779            if self.eat_kw("of") || self.is_kw("in") {
780                let of = !self.is_kw("in");
781                if !of {
782                    self.bump();
783                } // consume `in`
784                let object = self.parse_expression();
785                self.expect_sym(")");
786                let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
787                return Some(Statement::ForIn {
788                    decl_kind: Some(decl_kind),
789                    pattern: pat,
790                    object,
791                    body,
792                    of,
793                    is_await,
794                });
795            }
796            // C スタイル: 残りの宣言子を読む。
797            let init_expr = if self.eat_sym("=") {
798                Some(self.parse_assignment())
799            } else {
800                None
801            };
802            let mut decls = alloc::vec![(pat, init_expr)];
803            while self.eat_sym(",") {
804                let p = self.parse_pattern();
805                let i = if self.eat_sym("=") {
806                    Some(self.parse_assignment())
807                } else {
808                    None
809                };
810                decls.push((p, i));
811            }
812            self.eat_sym(";");
813            let init = Some(Box::new(Statement::VarDeclaration {
814                kind: decl_kind,
815                decls,
816            }));
817            return self.finish_c_for(init);
818        }
819
820        // 非宣言形式の for-of/for-in: `for (x of arr)` / `for (x in obj)`(x は単純識別子)。
821        // 一般の式パーサは `in` を二項演算子として消費してしまうため使えず、
822        // `IDENT of|in` の形を先読みで検出してから専用に処理する。
823        if let Token::Ident(name) = self.cur().clone() {
824            if self.kw_at(1, "of") || self.kw_at(1, "in") {
825                let of = self.kw_at(1, "of");
826                self.bump(); // ident
827                self.bump(); // of/in
828                let object = self.parse_expression();
829                self.expect_sym(")");
830                let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
831                return Some(Statement::ForIn {
832                    decl_kind: None,
833                    pattern: Pattern::Identifier(name),
834                    object,
835                    body,
836                    of,
837                    is_await,
838                });
839            }
840        }
841
842        // 非宣言形式の分割代入 for-of/for-in: `for ([a,b] of arr)` / `for ({a,b} of obj)`。
843        // `[`/`{` は for(...) の頭では値コンテキストなのでパターンとして一意に解釈できるが、
844        // `for ([a,b] = [1,2]; ...)` のような C 形式 for の可能性もあるため、
845        // パターンを試しにパースしてみて `of`/`in` が続かなければ巻き戻す。
846        if self.is_sym("[") || self.is_sym("{") {
847            let save = self.pos;
848            // 【2026-09-05】巻き戻すときは**記録したエラーも巻き戻す**。
849            // ここは「for-of/for-in か?」を試すだけの投機的な解析で、
850            // 外れたら位置を戻して C 形式として読み直す。ところが
851            // 位置しか戻していなかったため、試行中に出たエラーが残り、
852            // 実際には正しい構文まで構文エラーとして報告していた。
853            let err_save = (self.errors.len(), self.error_count);
854            let pat = self.parse_pattern();
855            if self.eat_kw("of") || self.is_kw("in") {
856                let of = !self.is_kw("in");
857                if !of {
858                    self.bump();
859                } // consume `in`
860                let object = self.parse_expression();
861                self.expect_sym(")");
862                let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
863                return Some(Statement::ForIn {
864                    decl_kind: None,
865                    pattern: pat,
866                    object,
867                    body,
868                    of,
869                    is_await,
870                });
871            }
872            self.pos = save;
873            self.errors.truncate(err_save.0);
874            // 件数も戻す(2026-09-26。記録だけ戻して件数を戻していなかったため、
875            // エラーの無い jQuery 1.8.2 で「42 syntax error(s)」と警告が出ていた)。
876            self.error_count = err_save.1;
877        }
878
879        // 非宣言形式のメンバー/添字式 for-of/for-in: `for (obj.prop of arr)` / `for (obj[k] of arr)`。
880        // `parse_call_member(false)`(呼出しは許可しない — member/index チェーンのみ)を使えば
881        // `in` を二項演算子として誤消費しない。結果が Member/Index で直後に of/in が続けば
882        // 採用し、そうでなければ(単純識別子や他の式だった場合)巻き戻して通常の C 形式へ。
883        if !self.is_kw("var") && !self.is_kw("let") && !self.is_kw("const") {
884            let save = self.pos;
885            // 同上。外れたら位置とエラーの両方を戻す。
886            // `for(;;)` は最初の `;` でここが失敗し、巻き戻した後は
887            // 正しく解析できるのに、残ったエラーのせいで
888            // 「式の位置に `;`」と報告されていた(jQuery 1.8.2 が
889            // `for(;;)` を使っており、本体が丸ごと構文エラー扱いになっていた)。
890            let err_save = (self.errors.len(), self.error_count);
891            let expr = self.parse_call_member(false);
892            let is_target = matches!(expr, Expression::Member { .. } | Expression::Index { .. });
893            if is_target && (self.eat_kw("of") || self.is_kw("in")) {
894                let of = !self.is_kw("in");
895                if !of {
896                    self.bump();
897                } // consume `in`
898                let object = self.parse_expression();
899                self.expect_sym(")");
900                let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
901                return Some(Statement::ForIn {
902                    decl_kind: None,
903                    pattern: Pattern::Expr(Box::new(expr)),
904                    object,
905                    body,
906                    of,
907                    is_await,
908                });
909            }
910            self.pos = save;
911            self.errors.truncate(err_save.0);
912            // 件数も戻す(2026-09-26。記録だけ戻して件数を戻していなかったため、
913            // エラーの無い jQuery 1.8.2 で「42 syntax error(s)」と警告が出ていた)。
914            self.error_count = err_save.1;
915        }
916
917        // init 式(無しの場合あり)
918        let init = if self.is_sym(";") {
919            None
920        } else {
921            let e = self.parse_expression();
922            Some(Box::new(Statement::Expression(e)))
923        };
924        self.eat_sym(";");
925        self.finish_c_for(init)
926    }
927
928    fn finish_c_for(&mut self, init: Option<Box<Statement>>) -> Option<Statement> {
929        // init の `;` は呼び出し側で消費済み。
930        let test = if self.is_sym(";") {
931            None
932        } else {
933            Some(self.parse_expression())
934        };
935        self.eat_sym(";");
936        let update = if self.is_sym(")") {
937            None
938        } else {
939            Some(self.parse_expression())
940        };
941        self.expect_sym(")");
942        let body = Box::new(self.parse_statement().unwrap_or(Statement::Empty));
943        Some(Statement::For {
944            init,
945            test,
946            update,
947            body,
948        })
949    }
950
951    fn parse_function_declaration(&mut self, is_async: bool) -> Option<Statement> {
952        self.bump(); // function
953        let is_generator = self.eat_sym("*");
954        let name = self.ident_name().unwrap_or_default();
955        let params = self.parse_param_list();
956        let body = self.parse_fn_body();
957        Some(Statement::FunctionDeclaration {
958            name,
959            params: Rc::new(params),
960            body,
961            is_async,
962            is_generator,
963        })
964    }
965
966    fn parse_try(&mut self) -> Option<Statement> {
967        self.bump(); // try
968        let block = self.parse_brace_body();
969        let mut catch_param = None;
970        let mut catch_block = None;
971        let mut finally_block = None;
972        if self.eat_kw("catch") {
973            if self.eat_sym("(") {
974                catch_param = Some(self.parse_pattern());
975                self.expect_sym(")");
976            }
977            catch_block = Some(self.parse_brace_body());
978        }
979        if self.eat_kw("finally") {
980            finally_block = Some(self.parse_brace_body());
981        }
982        Some(Statement::Try {
983            block,
984            catch_param,
985            catch_block,
986            finally_block,
987        })
988    }
989
990    /// 文字列指定子(module specifier)を読む。`from "mod"` の "mod" 部分など。
991    fn parse_module_specifier(&mut self) -> String {
992        match self.cur().clone() {
993            Token::Str(s) => {
994                self.bump();
995                s
996            }
997            _ => String::new(),
998        }
999    }
1000
1001    /// 文脈依存キーワード(`from`/`as`)を ident として消費する。一致したら true。
1002    fn eat_contextual(&mut self, word: &str) -> bool {
1003        if matches!(self.cur(), Token::Ident(x) if x == word) {
1004            self.pos += 1;
1005            true
1006        } else {
1007            false
1008        }
1009    }
1010
1011    /// `{ a, b as c }` の中身を (元名, ローカル名) ペアの列として読む。
1012    fn parse_named_specifiers(&mut self) -> Vec<(String, String)> {
1013        let mut out = Vec::new();
1014        self.expect_sym("{");
1015        while !self.is_sym("}") && !self.is_eof() {
1016            let orig = self.ident_name().unwrap_or_default();
1017            let local = if self.eat_contextual("as") {
1018                self.ident_name().unwrap_or_default()
1019            } else {
1020                orig.clone()
1021            };
1022            out.push((orig, local));
1023            if !self.eat_sym(",") {
1024                break;
1025            }
1026        }
1027        self.expect_sym("}");
1028        out
1029    }
1030
1031    /// `import` 宣言。
1032    /// 形態: `import "mod"` / `import def from "mod"` /
1033    /// `import * as ns from "mod"` / `import { a, b as c } from "mod"` /
1034    /// `import def, { a } from "mod"` / `import def, * as ns from "mod"`。
1035    fn parse_import(&mut self) -> Option<Statement> {
1036        self.bump(); // import
1037        let mut default = None;
1038        let mut namespace = None;
1039        let mut named = Vec::new();
1040
1041        // 副作用のみ: import "mod";
1042        if let Token::Str(s) = self.cur().clone() {
1043            self.bump();
1044            self.eat_sym(";");
1045            return Some(Statement::Import {
1046                source: s,
1047                default: None,
1048                namespace: None,
1049                named: Vec::new(),
1050                side_effect_only: true,
1051            });
1052        }
1053
1054        // default インポート(識別子)。
1055        if let Token::Ident(n) = self.cur().clone() {
1056            self.bump();
1057            default = Some(n);
1058            self.eat_sym(","); // default の後に名前空間/名前付きが続く場合
1059        }
1060
1061        // 名前空間 `* as ns`。
1062        if self.eat_sym("*") {
1063            self.eat_contextual("as");
1064            namespace = self.ident_name();
1065        } else if self.is_sym("{") {
1066            // 名前付き `{ a, b as c }`。
1067            named = self.parse_named_specifiers();
1068        }
1069
1070        self.eat_contextual("from");
1071        let source = self.parse_module_specifier();
1072        self.eat_sym(";");
1073        Some(Statement::Import {
1074            source,
1075            default,
1076            namespace,
1077            named,
1078            side_effect_only: false,
1079        })
1080    }
1081
1082    /// `export` 宣言。
1083    /// 形態: `export default <expr>` / `export { a, b as c }` /
1084    /// `export { a } from "mod"` / `export * from "mod"` /
1085    /// `export var/let/const/function/class ...`。
1086    fn parse_export(&mut self) -> Option<Statement> {
1087        self.bump(); // export
1088
1089        // export default <expr>;
1090        if self.eat_kw("default") {
1091            // default の後は関数/クラス宣言または式。
1092            let expr = if self.is_kw("function") {
1093                self.parse_function_expression(false)
1094            } else if self.is_kw("async") && self.kw_at(1, "function") {
1095                self.bump(); // async
1096                self.parse_function_expression(true)
1097            } else if self.is_kw("class") {
1098                self.parse_class()
1099            } else {
1100                self.parse_assignment()
1101            };
1102            self.eat_sym(";");
1103            return Some(Statement::ExportDefault(expr));
1104        }
1105
1106        // export * from "mod";
1107        if self.eat_sym("*") {
1108            self.eat_contextual("from");
1109            let source = self.parse_module_specifier();
1110            self.eat_sym(";");
1111            return Some(Statement::ExportAll { source });
1112        }
1113
1114        // export { a, b as c } [from "mod"];
1115        if self.is_sym("{") {
1116            // ここでの (orig, local) は (ローカル名, 公開名) に読み替える。
1117            let specs = self.parse_named_specifiers();
1118            let source = if self.eat_contextual("from") {
1119                Some(self.parse_module_specifier())
1120            } else {
1121                None
1122            };
1123            self.eat_sym(";");
1124            return Some(Statement::ExportNamed {
1125                specifiers: specs,
1126                source,
1127            });
1128        }
1129
1130        // export var/let/const/function/class ...
1131        let names = self.export_decl_names();
1132        let declaration = self.parse_statement().unwrap_or(Statement::Empty);
1133        Some(Statement::ExportDecl {
1134            declaration: Box::new(declaration),
1135            names,
1136        })
1137    }
1138
1139    /// `export` に続く宣言から公開すべき名前を先読みで収集する(カーソルは進めない)。
1140    fn export_decl_names(&self) -> Vec<String> {
1141        let mut names = Vec::new();
1142        match self.cur() {
1143            Token::Keyword(k) if *k == "function" => {
1144                // function [*] name
1145                let mut off = 1;
1146                if self.sym_at(off, "*") {
1147                    off += 1;
1148                }
1149                if let Token::Ident(n) = self.at(off) {
1150                    names.push(n.clone());
1151                }
1152            }
1153            Token::Keyword(k) if *k == "async" => {
1154                // async function [*] name
1155                let mut off = 2;
1156                if self.sym_at(off, "*") {
1157                    off += 1;
1158                }
1159                if let Token::Ident(n) = self.at(off) {
1160                    names.push(n.clone());
1161                }
1162            }
1163            Token::Keyword(k) if *k == "class" => {
1164                if let Token::Ident(n) = self.at(1) {
1165                    names.push(n.clone());
1166                }
1167            }
1168            Token::Keyword(k) if *k == "var" || *k == "let" || *k == "const" => {
1169                // 単純な識別子束縛のみ収集(分割代入は対象外)。
1170                let mut off = 1;
1171                while let Token::Ident(n) = self.at(off) {
1172                    names.push(n.clone());
1173                    // 次が `,` なら継続。`=` 等が来たら打ち切る。
1174                    if self.sym_at(off + 1, ",") {
1175                        off += 2;
1176                    } else {
1177                        break;
1178                    }
1179                }
1180            }
1181            _ => {}
1182        }
1183        names
1184    }
1185
1186    fn parse_expression_statement(&mut self) -> Option<Statement> {
1187        let e = self.parse_expression();
1188        self.eat_sym(";");
1189        Some(Statement::Expression(e))
1190    }
1191
1192    fn parse_switch(&mut self) -> Option<Statement> {
1193        self.eat_kw("switch");
1194        self.expect_sym("(");
1195        let discriminant = self.parse_expression();
1196        self.expect_sym(")");
1197        self.expect_sym("{");
1198        let mut cases = Vec::new();
1199        while !self.is_sym("}") && !self.is_eof() {
1200            let test = if self.eat_kw("case") {
1201                let t = self.parse_expression();
1202                self.expect_sym(":");
1203                Some(t)
1204            } else if self.eat_kw("default") {
1205                self.expect_sym(":");
1206                None
1207            } else {
1208                // 想定外トークンはスキップして無限ループを避ける。
1209                self.bump();
1210                continue;
1211            };
1212            // 次の case/default/} までを本体として収集。
1213            let mut body = Vec::new();
1214            while !self.is_kw("case")
1215                && !self.is_kw("default")
1216                && !self.is_sym("}")
1217                && !self.is_eof()
1218            {
1219                let before = self.pos;
1220                if let Some(s) = self.parse_statement() {
1221                    body.push(s);
1222                }
1223                if self.pos == before {
1224                    self.pos += 1;
1225                }
1226            }
1227            cases.push(crate::os_lib::js::ast::SwitchCase { test, body });
1228        }
1229        self.expect_sym("}");
1230        Some(Statement::Switch {
1231            discriminant,
1232            cases,
1233        })
1234    }
1235
1236    fn parse_param_list(&mut self) -> Vec<Param> {
1237        let mut params = Vec::new();
1238        if self.eat_sym("(") {
1239            while !self.is_sym(")") && !self.is_eof() {
1240                let is_rest = self.eat_sym("...");
1241                let pattern = self.parse_pattern();
1242                let default = if self.eat_sym("=") {
1243                    Some(self.parse_assignment())
1244                } else {
1245                    None
1246                };
1247                params.push(Param {
1248                    pattern,
1249                    default,
1250                    is_rest,
1251                });
1252                if !self.eat_sym(",") {
1253                    break;
1254                }
1255            }
1256            self.expect_sym(")");
1257        }
1258        params
1259    }
1260
1261    /// 束縛パターンをパース(識別子 / `{...}` / `[...]`)。
1262    fn parse_pattern(&mut self) -> Pattern {
1263        if self.is_sym("{") {
1264            return self.parse_object_pattern();
1265        }
1266        if self.is_sym("[") {
1267            return self.parse_array_pattern();
1268        }
1269        Pattern::Identifier(self.ident_name().unwrap_or_default())
1270    }
1271
1272    fn parse_object_pattern(&mut self) -> Pattern {
1273        self.expect_sym("{");
1274        let mut props = Vec::new();
1275        while !self.is_sym("}") && !self.is_eof() {
1276            if self.eat_sym("...") {
1277                let name = self.ident_name().unwrap_or_default();
1278                props.push(ObjPatProp {
1279                    key: String::new(),
1280                    computed_key: None,
1281                    value: Pattern::Identifier(name),
1282                    default: None,
1283                    is_rest: true,
1284                });
1285                break; // rest は最後。
1286            }
1287            // 算出プロパティ名 `{[expr]: target}`。以前は一切非対応で、`[` に遭遇すると
1288            // どの分岐にも該当せず `_ => break` に落ち、以降のプロパティ(分割代入先の
1289            // 残り全部)が消え、パース位置もずれて後続の解析まで巻き込んで壊れる
1290            // バグだった(クラス/オブジェクトリテラルの async/generator 修飾子と同種)。
1291            let (key, computed_key) = if self.eat_sym("[") {
1292                let ce = self.parse_assignment();
1293                self.expect_sym("]");
1294                (String::new(), Some(ce))
1295            } else {
1296                let k = match self.cur().clone() {
1297                    Token::Ident(n) => {
1298                        self.bump();
1299                        n
1300                    }
1301                    Token::Keyword(n) => {
1302                        self.bump();
1303                        String::from(n)
1304                    }
1305                    Token::Str(s) => {
1306                        self.bump();
1307                        s
1308                    }
1309                    Token::Num(n) => {
1310                        self.bump();
1311                        super::value::fmt_number(n)
1312                    }
1313                    _ => break,
1314                };
1315                (k, None)
1316            };
1317            // `key: target` で別名/ネスト、無ければ key 自身を束縛(算出キーの場合は
1318            // 仕様上 `: target` が必須なので、無ければ空の識別子にフォールバックする)。
1319            let value = if self.eat_sym(":") {
1320                self.parse_pattern()
1321            } else {
1322                Pattern::Identifier(key.clone())
1323            };
1324            let default = if self.eat_sym("=") {
1325                Some(self.parse_assignment())
1326            } else {
1327                None
1328            };
1329            props.push(ObjPatProp {
1330                key,
1331                computed_key,
1332                value,
1333                default,
1334                is_rest: false,
1335            });
1336            if !self.eat_sym(",") {
1337                break;
1338            }
1339        }
1340        self.expect_sym("}");
1341        Pattern::Object(props)
1342    }
1343
1344    fn parse_array_pattern(&mut self) -> Pattern {
1345        self.expect_sym("[");
1346        let mut elems = Vec::new();
1347        while !self.is_sym("]") && !self.is_eof() {
1348            if self.is_sym(",") {
1349                // 穴 [a, , b]
1350                elems.push(ArrPatElem {
1351                    pattern: None,
1352                    default: None,
1353                    is_rest: false,
1354                });
1355                self.bump();
1356                continue;
1357            }
1358            let is_rest = self.eat_sym("...");
1359            let pat = self.parse_pattern();
1360            let default = if !is_rest && self.eat_sym("=") {
1361                Some(self.parse_assignment())
1362            } else {
1363                None
1364            };
1365            elems.push(ArrPatElem {
1366                pattern: Some(pat),
1367                default,
1368                is_rest,
1369            });
1370            if is_rest {
1371                break;
1372            }
1373            if !self.eat_sym(",") {
1374                break;
1375            }
1376        }
1377        self.expect_sym("]");
1378        Pattern::Array(elems)
1379    }
1380
1381    // --- 式 ---
1382    pub fn parse_expression(&mut self) -> Expression {
1383        let first = self.parse_assignment();
1384        if !self.is_sym(",") {
1385            return first;
1386        }
1387        // カンマ演算子: 以前は後続の式で単純に上書きしており、先行する式(の副作用)が
1388        // AST から丸ごと消えてしまう重大なバグだった(`(a(), b())` が `a()` を一切
1389        // 呼ばないなど)。`Sequence` へ全要素を保持し、実行時に順番に評価する。
1390        let mut items = alloc::vec![first];
1391        while self.eat_sym(",") {
1392            items.push(self.parse_assignment());
1393        }
1394        Expression::Sequence(items)
1395    }
1396
1397    fn parse_assignment(&mut self) -> Expression {
1398        // yield / yield* (generator 内、assignment レベル)。
1399        if self.is_kw("yield") {
1400            self.bump();
1401            let delegate = self.eat_sym("*");
1402            // 引数なし yield(`yield;` / `yield)` 等)を許容。
1403            let argument = if self.is_sym(";")
1404                || self.is_sym(")")
1405                || self.is_sym("]")
1406                || self.is_sym("}")
1407                || self.is_sym(",")
1408                || self.is_eof()
1409            {
1410                None
1411            } else {
1412                Some(Box::new(self.parse_assignment()))
1413            };
1414            return Expression::Yield { argument, delegate };
1415        }
1416        // アロー関数の先読み。
1417        if let Some(arrow) = self.try_parse_arrow() {
1418            return arrow;
1419        }
1420        let left = self.parse_conditional();
1421        if let Token::Sym(op) = self.cur().clone() {
1422            if is_assign_op(op) {
1423                self.bump();
1424                let value = self.parse_assignment();
1425                return Expression::Assign {
1426                    op: String::from(op),
1427                    target: Box::new(left),
1428                    value: Box::new(value),
1429                };
1430            }
1431        }
1432        left
1433    }
1434
1435    fn try_parse_arrow(&mut self) -> Option<Expression> {
1436        let start = self.pos;
1437        // `async` 接頭辞(async function は arrow ではないので除外)。
1438        let is_async = if self.is_kw("async") {
1439            if self.kw_at(1, "function") {
1440                return None;
1441            }
1442            self.bump();
1443            true
1444        } else {
1445            false
1446        };
1447        // x => ...
1448        if let Token::Ident(name) = self.cur().clone() {
1449            if self.sym_at(1, "=>") {
1450                self.bump(); // ident
1451                self.bump(); // =>
1452                let body = self.parse_arrow_body();
1453                return Some(Expression::Function {
1454                    name: None,
1455                    params: Rc::new(alloc::vec![Param {
1456                        pattern: Pattern::Identifier(name),
1457                        default: None,
1458                        is_rest: false
1459                    }]),
1460                    body,
1461                    is_arrow: true,
1462                    is_async,
1463                    is_generator: false,
1464                });
1465            }
1466        }
1467        // ( params ) => ...
1468        if self.is_sym("(") {
1469            if let Some(close) = self.matching_paren() {
1470                if matches!(self.toks.get(close + 1), Some(Token::Sym(s)) if *s == "=>") {
1471                    let params = self.parse_param_list();
1472                    self.expect_sym("=>");
1473                    let body = self.parse_arrow_body();
1474                    return Some(Expression::Function {
1475                        name: None,
1476                        params: Rc::new(params),
1477                        body,
1478                        is_arrow: true,
1479                        is_async,
1480                        is_generator: false,
1481                    });
1482                }
1483            }
1484        }
1485        // arrow ではなかった。consume した `async` を巻き戻す。
1486        self.pos = start;
1487        None
1488    }
1489
1490    /// 現在位置の `(` に対応する `)` のインデックスを返す。
1491    fn matching_paren(&self) -> Option<usize> {
1492        let mut depth = 0i32;
1493        let mut i = self.pos;
1494        while let Some(t) = self.toks.get(i) {
1495            match t {
1496                Token::Sym(s) if *s == "(" => depth += 1,
1497                Token::Sym(s) if *s == ")" => {
1498                    depth -= 1;
1499                    if depth == 0 {
1500                        return Some(i);
1501                    }
1502                }
1503                Token::Eof => return None,
1504                _ => {}
1505            }
1506            i += 1;
1507        }
1508        None
1509    }
1510
1511    fn parse_arrow_body(&mut self) -> Rc<FnBody> {
1512        if self.is_sym("{") {
1513            self.parse_fn_body()
1514        } else {
1515            let e = self.parse_assignment();
1516            FnBody::parsed_with(alloc::vec![Statement::Return(Some(e))], self.strict)
1517        }
1518    }
1519
1520    fn parse_conditional(&mut self) -> Expression {
1521        let test = self.parse_binary(0);
1522        if self.eat_sym("?") {
1523            let consequent = self.parse_assignment();
1524            self.expect_sym(":");
1525            let alternate = self.parse_assignment();
1526            return Expression::Conditional {
1527                test: Box::new(test),
1528                consequent: Box::new(consequent),
1529                alternate: Box::new(alternate),
1530            };
1531        }
1532        test
1533    }
1534
1535    fn parse_binary(&mut self, min_prec: u8) -> Expression {
1536        let mut left = self.parse_unary();
1537        while let Some(op) = self.current_binop_str() {
1538            let prec = match bin_prec(&op) {
1539                Some(p) => p,
1540                None => break,
1541            };
1542            if prec < min_prec {
1543                break;
1544            }
1545            self.bump(); // operator
1546            let next_min = if is_right_assoc(&op) { prec } else { prec + 1 };
1547            let right = self.parse_binary(next_min);
1548            left = if let Some(lop) = to_logical(&op) {
1549                Expression::Logical {
1550                    op: lop,
1551                    left: Box::new(left),
1552                    right: Box::new(right),
1553                }
1554            } else if let Some(bop) = to_binop(&op) {
1555                Expression::Binary {
1556                    op: bop,
1557                    left: Box::new(left),
1558                    right: Box::new(right),
1559                }
1560            } else {
1561                left
1562            };
1563        }
1564        left
1565    }
1566
1567    /// 現在のトークンが二項演算子なら、その文字列を返す(`instanceof`/`in` 含む)。
1568    fn current_binop_str(&self) -> Option<String> {
1569        match self.cur() {
1570            Token::Sym(s) if bin_prec(s).is_some() => Some(String::from(*s)),
1571            Token::Keyword(k) if *k == "instanceof" || *k == "in" => Some(String::from(*k)),
1572            _ => None,
1573        }
1574    }
1575
1576    fn parse_unary(&mut self) -> Expression {
1577        // 前置演算子
1578        if let Token::Sym(s) = self.cur().clone() {
1579            let uop = match s {
1580                "!" => Some(UnaryOp::Not),
1581                "-" => Some(UnaryOp::Neg),
1582                "+" => Some(UnaryOp::Pos),
1583                "~" => Some(UnaryOp::BitNot),
1584                _ => None,
1585            };
1586            if let Some(op) = uop {
1587                self.bump();
1588                let expr = self.parse_unary();
1589                return Expression::Unary {
1590                    op,
1591                    expr: Box::new(expr),
1592                };
1593            }
1594            if s == "++" || s == "--" {
1595                self.bump();
1596                let target = self.parse_unary();
1597                return Expression::Update {
1598                    op: String::from(s),
1599                    prefix: true,
1600                    target: Box::new(target),
1601                };
1602            }
1603        }
1604        if let Token::Keyword(k) = self.cur().clone() {
1605            let uop = match k {
1606                "typeof" => Some(UnaryOp::TypeOf),
1607                "void" => Some(UnaryOp::Void),
1608                "delete" => Some(UnaryOp::Delete),
1609                _ => None,
1610            };
1611            if let Some(op) = uop {
1612                self.bump();
1613                let expr = self.parse_unary();
1614                return Expression::Unary {
1615                    op,
1616                    expr: Box::new(expr),
1617                };
1618            }
1619            if k == "await" {
1620                self.bump();
1621                let expr = self.parse_unary();
1622                return Expression::Await(Box::new(expr));
1623            }
1624            if k == "new" {
1625                return self.parse_new();
1626            }
1627        }
1628        self.parse_postfix()
1629    }
1630
1631    fn parse_new(&mut self) -> Expression {
1632        self.bump(); // new
1633        // `new.target`(MetaProperty)。ドット直後が識別子 `target` の場合のみ該当し、
1634        // それ以外(`new Foo` 等の通常のコンストラクタ呼び出し)とは衝突しない。
1635        if self.is_sym(".") && self.ident_at(1, "target") {
1636            self.bump(); // .
1637            self.bump(); // target
1638            return self.parse_call_member_tail(Expression::NewTarget, true);
1639        }
1640        // callee は呼出を含まないメンバ式。
1641        let callee = self.parse_call_member(false);
1642        let arguments = if self.is_sym("(") {
1643            self.parse_arguments()
1644        } else {
1645            Vec::new()
1646        };
1647        let new_expr = Expression::New {
1648            callee: Box::new(callee),
1649            arguments,
1650        };
1651        // `new A(7).get()` の後続メンバ/呼出チェーンを継続。
1652        self.parse_call_member_tail(new_expr, true)
1653    }
1654
1655    fn parse_postfix(&mut self) -> Expression {
1656        let expr = self.parse_call_member(true);
1657        if let Token::Sym(s) = self.cur().clone() {
1658            if s == "++" || s == "--" {
1659                self.bump();
1660                return Expression::Update {
1661                    op: String::from(s),
1662                    prefix: false,
1663                    target: Box::new(expr),
1664                };
1665            }
1666        }
1667        expr
1668    }
1669
1670    /// メンバ/添字/呼出のチェーン。`allow_call=false` で呼出を抑止(new 用)。
1671    fn parse_call_member(&mut self, allow_call: bool) -> Expression {
1672        let expr = self.parse_primary();
1673        self.parse_call_member_tail(expr, allow_call)
1674    }
1675
1676    /// 既存の式に続くメンバ/添字/呼出チェーンを消費する。
1677    fn parse_call_member_tail(&mut self, mut expr: Expression, allow_call: bool) -> Expression {
1678        loop {
1679            if self.eat_sym(".") {
1680                let prop = self.ident_name().unwrap_or_default();
1681                expr = Expression::Member {
1682                    object: Box::new(expr),
1683                    property: prop,
1684                    optional: false,
1685                };
1686            } else if self.is_sym("?.") {
1687                self.bump();
1688                if self.is_sym("(") && allow_call {
1689                    let arguments = self.parse_arguments();
1690                    expr = Expression::Call {
1691                        callee: Box::new(expr),
1692                        arguments,
1693                        optional: true,
1694                    };
1695                } else if self.is_sym("[") {
1696                    self.bump();
1697                    let index = self.parse_expression();
1698                    self.expect_sym("]");
1699                    expr = Expression::Index {
1700                        object: Box::new(expr),
1701                        index: Box::new(index),
1702                        optional: true,
1703                    };
1704                } else {
1705                    let prop = self.ident_name().unwrap_or_default();
1706                    expr = Expression::Member {
1707                        object: Box::new(expr),
1708                        property: prop,
1709                        optional: true,
1710                    };
1711                }
1712            } else if self.eat_sym("[") {
1713                let index = self.parse_expression();
1714                self.expect_sym("]");
1715                expr = Expression::Index {
1716                    object: Box::new(expr),
1717                    index: Box::new(index),
1718                    optional: false,
1719                };
1720            } else if self.is_sym("(") && allow_call {
1721                let arguments = self.parse_arguments();
1722                expr = Expression::Call {
1723                    callee: Box::new(expr),
1724                    arguments,
1725                    optional: false,
1726                };
1727            } else if allow_call && matches!(self.cur(), Token::Template(_)) {
1728                // タグ付きテンプレート `` tag`...` ``。以前はこの分岐が無く、`Template`
1729                // トークンが式の直後に来ると(primary の再入り口が無いため)静かに
1730                // パースが打ち切られる/崩れるバグだった(本キャンペーンで見つけてきた
1731                // 「未知トークンでの黙示的パース破壊」系と同種)。
1732                let parts = match self.cur().clone() {
1733                    Token::Template(p) => p,
1734                    _ => unreachable!(),
1735                };
1736                self.bump();
1737                let mut quasis = Vec::new();
1738                let mut raw = Vec::new();
1739                let mut exprs = Vec::new();
1740                for part in parts {
1741                    match part {
1742                        super::lexer::TemplatePart::Quasi(s, r) => {
1743                            quasis.push(s);
1744                            raw.push(r);
1745                        }
1746                        super::lexer::TemplatePart::Expr(src) => {
1747                            let mut sub = Parser::new(Lexer::new(&src));
1748                            exprs.push(sub.parse_assignment());
1749                            // テンプレート補間式の中の構文エラーも親へ引き継ぐ
1750                            // (別インスタンスで解析するため、捨てると誰も気づけない)。
1751                            self.absorb_errors(sub);
1752                        }
1753                    }
1754                }
1755                expr = Expression::TaggedTemplate {
1756                    tag: Box::new(expr),
1757                    quasis,
1758                    raw,
1759                    exprs,
1760                };
1761            } else {
1762                break;
1763            }
1764        }
1765        expr
1766    }
1767
1768    fn parse_arguments(&mut self) -> Vec<Expression> {
1769        let mut args = Vec::new();
1770        self.expect_sym("(");
1771        while !self.is_sym(")") && !self.is_eof() {
1772            if self.eat_sym("...") {
1773                args.push(Expression::Spread(Box::new(self.parse_assignment())));
1774            } else {
1775                args.push(self.parse_assignment());
1776            }
1777            if !self.eat_sym(",") {
1778                break;
1779            }
1780        }
1781        self.expect_sym(")");
1782        args
1783    }
1784
1785    fn parse_primary(&mut self) -> Expression {
1786        match self.cur().clone() {
1787            Token::Num(n) => {
1788                self.bump();
1789                Expression::Number(n)
1790            }
1791            Token::BigIntLit(s) => {
1792                self.bump();
1793                Expression::BigIntLit(s)
1794            }
1795            Token::Str(s) => {
1796                self.bump();
1797                Expression::Str(s)
1798            }
1799            Token::Regex(rf) => {
1800                self.bump();
1801                let (p, f) = *rf;
1802                Expression::Regex(p, f)
1803            }
1804            Token::Template(parts) => {
1805                self.bump();
1806                let mut quasis = Vec::new();
1807                let mut exprs = Vec::new();
1808                for part in parts {
1809                    match part {
1810                        super::lexer::TemplatePart::Quasi(s, _raw) => quasis.push(s),
1811                        super::lexer::TemplatePart::Expr(src) => {
1812                            // 補間式は独立したサブパーサで構文解析する(外側の解析状態を
1813                            // 汚さない)。comma 演算子は非対応(assignment 式まで。関数
1814                            // 引数リストの各要素パースと同じ簡略方針)。
1815                            let mut sub = Parser::new(Lexer::new(&src));
1816                            exprs.push(sub.parse_assignment());
1817                            // テンプレート補間式の中の構文エラーも親へ引き継ぐ
1818                            // (別インスタンスで解析するため、捨てると誰も気づけない)。
1819                            self.absorb_errors(sub);
1820                        }
1821                    }
1822                }
1823                Expression::TemplateLiteral { quasis, exprs }
1824            }
1825            Token::Ident(name) => {
1826                self.bump();
1827                Expression::Identifier(name)
1828            }
1829            Token::Keyword(kw) => match kw {
1830                "true" => {
1831                    self.bump();
1832                    Expression::Bool(true)
1833                }
1834                "false" => {
1835                    self.bump();
1836                    Expression::Bool(false)
1837                }
1838                "null" => {
1839                    self.bump();
1840                    Expression::Null
1841                }
1842                "undefined" => {
1843                    self.bump();
1844                    Expression::Undefined
1845                }
1846                "this" => {
1847                    self.bump();
1848                    Expression::This
1849                }
1850                "super" => {
1851                    self.bump();
1852                    Expression::Super
1853                }
1854                "function" => self.parse_function_expression(false),
1855                "async" if self.kw_at(1, "function") => {
1856                    self.bump(); // async
1857                    self.parse_function_expression(true)
1858                }
1859                "class" => self.parse_class(),
1860                // `of` は予約語ではない(for-of の文脈でだけ意味を持つ)。式の位置では普通の識別子
1861                // (2026-09-26。OpenStreetMap 埋め込みの JS が `new Uint8Array(of)` を使っていた)。
1862                "of" => {
1863                    self.bump();
1864                    Expression::Identifier(String::from("of"))
1865                }
1866                other => {
1867                    // 式の位置に来てはいけない予約語。従来は黙って
1868                    // `undefined` に置き換えていたため、`if` が消えるような
1869                    // 壊れ方をしても呼び出し側は何も気づけなかった。
1870                    let msg = alloc::format!("unexpected keyword '{}' in expression", other);
1871                    self.record_error(msg);
1872                    self.bump();
1873                    Expression::Undefined
1874                }
1875            },
1876            Token::Sym(s) => match s {
1877                "(" => {
1878                    self.bump();
1879                    let e = self.parse_expression();
1880                    self.expect_sym(")");
1881                    e
1882                }
1883                "[" => self.parse_array_literal(),
1884                "{" => self.parse_object_literal(),
1885                other => {
1886                    // 式として解釈できない記号(余分な `)` や `,` など)。
1887                    let msg = alloc::format!("unexpected '{}' in expression", other);
1888                    self.record_error(msg);
1889                    self.bump();
1890                    Expression::Undefined
1891                }
1892            },
1893            Token::Eof | Token::LazyBody(..) => Expression::Undefined,
1894        }
1895    }
1896
1897    fn parse_function_expression(&mut self, is_async: bool) -> Expression {
1898        self.bump(); // function
1899        let is_generator = self.eat_sym("*");
1900        let name = match self.cur().clone() {
1901            Token::Ident(n) => {
1902                self.bump();
1903                Some(n)
1904            }
1905            _ => None,
1906        };
1907        let params = self.parse_param_list();
1908        let body = self.parse_fn_body();
1909        Expression::Function {
1910            name,
1911            params: Rc::new(params),
1912            body,
1913            is_arrow: false,
1914            is_async,
1915            is_generator,
1916        }
1917    }
1918
1919    /// クラス(本体は常に strict モード)。
1920    fn parse_class(&mut self) -> Expression {
1921        let outer = core::mem::replace(&mut self.strict, true);
1922        let e = self.parse_class_inner();
1923        self.strict = outer;
1924        e
1925    }
1926
1927    fn parse_class_inner(&mut self) -> Expression {
1928        self.eat_kw("class");
1929        let name = match self.cur().clone() {
1930            Token::Ident(n) => {
1931                self.bump();
1932                Some(n)
1933            }
1934            _ => None,
1935        };
1936        let superclass = if self.eat_kw("extends") {
1937            Some(Box::new(self.parse_conditional()))
1938        } else {
1939            None
1940        };
1941        self.expect_sym("{");
1942        let mut members = Vec::new();
1943        while !self.is_sym("}") && !self.is_eof() {
1944            if self.eat_sym(";") {
1945                continue;
1946            }
1947            // static 修飾子。以前は「次が `(` でなければ修飾子」という緩い判定で、
1948            // `class C { static = 5; }`("static" という名前のフィールド)まで
1949            // 修飾子と誤認識し、後続の `=` がどの分岐にも該当せず読み飛ばされて
1950            // パース結果が壊れるバグがあった(`async`/`*` 修飾子と同種)。次のトークンが
1951            // 実際にメソッド/フィールド名や `{`(static block)になり得る場合のみ
1952            // 修飾子として扱う。
1953            let is_static = if let Token::Ident(n) = self.cur().clone() {
1954                n == "static"
1955                    && (self.is_property_key_token(1)
1956                        || self.sym_at(1, "[")
1957                        || self.sym_at(1, "*")
1958                        || self.sym_at(1, "{"))
1959            } else {
1960                false
1961            };
1962            if is_static {
1963                self.bump();
1964            }
1965            // `static { ... }`(ES2022 静的初期化ブロック)。
1966            if is_static && self.is_sym("{") {
1967                let body = self.parse_fn_body();
1968                members.push(ClassMember {
1969                    key: String::new(),
1970                    computed_key: None,
1971                    kind: MethodKind::StaticBlock,
1972                    params: Rc::new(Vec::new()),
1973                    body,
1974                    is_static: true,
1975                    field_init: None,
1976                    is_async: false,
1977                    is_generator: false,
1978                });
1979                continue;
1980            }
1981            // `async`/`*`(generator)修飾子。以前はどちらも一切認識されておらず、
1982            // `async method(){}`/`*method(){}` を含むクラス定義があると `key` の
1983            // マッチが `_ => { self.bump(); continue; }` に落ちてメソッド自体が
1984            // 丸ごと消え、パース位置がずれて後続メンバの解析も壊れるバグだった。
1985            // `async` の次が「メソッド名になり得るトークン」(識別子/キーワード/文字列/
1986            // 数値/`[`算出キー/`*`generator)でなければ、`async` 自身がプロパティ名
1987            // (`class C { async = 1; }` のようなフィールド名)と判断し、修飾子として
1988            // 消費しない(このガードが無いと `async` という名前のフィールドが壊れる)。
1989            let async_modifier_ok =
1990                self.is_property_key_token(1) || self.sym_at(1, "[") || self.sym_at(1, "*");
1991            let is_async = self.is_kw("async") && async_modifier_ok;
1992            if is_async {
1993                self.bump();
1994            }
1995            let is_generator = self.eat_sym("*");
1996            // アクセサ修飾子(`get name() {...}` / `set name(v) {...}`)。次の2トークンが
1997            // 「プロパティ名になり得るトークン」+ `(` の場合のみアクセサとして扱う
1998            // (`get(){}`="get" という名前のメソッド、`get: 1`="get" という名前の
1999            // フィールドと衝突しないようにするため)。算出名 `get [expr](){}` も、
2000            // 次が `[` ならこの文法上アクセサ以外の解釈があり得ないため許可する
2001            // (以前はここが漏れており `get [Symbol.iterator](){}` のようなパターンが
2002            // getter として認識されず、"get" という名前の孤立フィールド+無関係な
2003            // 算出名メソッドという壊れた2メンバに分解されてしまっていた)。
2004            let accessor_kind = if let Token::Ident(n) = self.cur().clone() {
2005                if (n == "get" || n == "set")
2006                    && (self.sym_at(1, "[")
2007                        || (self.is_property_key_token(1) && self.sym_at(2, "(")))
2008                {
2009                    self.bump();
2010                    Some(n == "get")
2011                } else {
2012                    None
2013                }
2014            } else {
2015                None
2016            };
2017            // メソッド名。`[expr]` は算出メソッド名(`[Symbol.iterator]` 等)。
2018            let mut computed_key = None;
2019            let key = match self.cur().clone() {
2020                Token::Ident(n) => {
2021                    self.bump();
2022                    n
2023                }
2024                Token::Keyword(n) => {
2025                    self.bump();
2026                    String::from(n)
2027                }
2028                Token::Str(s) => {
2029                    self.bump();
2030                    s
2031                }
2032                Token::Num(n) => {
2033                    self.bump();
2034                    super::value::fmt_number(n)
2035                }
2036                Token::Sym("[") => {
2037                    self.bump();
2038                    computed_key = Some(self.parse_assignment());
2039                    self.expect_sym("]");
2040                    String::new()
2041                }
2042                _ => {
2043                    self.bump();
2044                    continue;
2045                }
2046            };
2047            if self.is_sym("(") {
2048                // メソッド(constructor 含む)。
2049                let params = self.parse_param_list();
2050                let body = self.parse_fn_body();
2051                let kind = match accessor_kind {
2052                    Some(true) => MethodKind::Getter,
2053                    Some(false) => MethodKind::Setter,
2054                    None if computed_key.is_none() && key == "constructor" => {
2055                        MethodKind::Constructor
2056                    }
2057                    None => MethodKind::Method,
2058                };
2059                members.push(ClassMember {
2060                    key,
2061                    computed_key,
2062                    kind,
2063                    params: Rc::new(params),
2064                    body,
2065                    is_static,
2066                    field_init: None,
2067                    is_async,
2068                    is_generator,
2069                });
2070            } else {
2071                // フィールド宣言: `key = expr;` または `key;`(`#key` も同じ経路。
2072                // lexer が '#' を識別子の一部として読むため key にそのまま含まれる)。
2073                let init = if self.eat_sym("=") {
2074                    Some(self.parse_assignment())
2075                } else {
2076                    None
2077                };
2078                self.eat_sym(";");
2079                members.push(ClassMember {
2080                    key,
2081                    // 算出フィールド名(`[expr] = init;`)は非対応(稀なパターンのため、
2082                    // メソッドの算出名 `[Symbol.iterator](){}` のみ対応する簡略化)。
2083                    computed_key: None,
2084                    kind: MethodKind::Field,
2085                    params: Rc::new(Vec::new()),
2086                    body: FnBody::parsed_with(Vec::new(), true),
2087                    is_static,
2088                    field_init: init,
2089                    is_async: false,
2090                    is_generator: false,
2091                });
2092            }
2093        }
2094        self.expect_sym("}");
2095        Expression::Class {
2096            name,
2097            superclass,
2098            members,
2099        }
2100    }
2101
2102    fn parse_array_literal(&mut self) -> Expression {
2103        self.expect_sym("[");
2104        let mut items = Vec::new();
2105        while !self.is_sym("]") && !self.is_eof() {
2106            if self.is_sym(",") {
2107                // 穴あき配列 [1,,3] は undefined 扱い。
2108                items.push(Expression::Undefined);
2109                self.bump();
2110                continue;
2111            }
2112            if self.eat_sym("...") {
2113                items.push(Expression::Spread(Box::new(self.parse_assignment())));
2114            } else {
2115                items.push(self.parse_assignment());
2116            }
2117            if !self.eat_sym(",") {
2118                break;
2119            }
2120        }
2121        self.expect_sym("]");
2122        Expression::Array(items)
2123    }
2124
2125    fn parse_object_literal(&mut self) -> Expression {
2126        self.expect_sym("{");
2127        let mut props = Vec::new();
2128        while !self.is_sym("}") && !self.is_eof() {
2129            // オブジェクトスプレッド {...o}
2130            if self.eat_sym("...") {
2131                let value = self.parse_assignment();
2132                props.push(Property {
2133                    key: String::from(crate::os_lib::js::ast::OBJECT_SPREAD_KEY),
2134                    value,
2135                    computed: None,
2136                    accessor: None,
2137                });
2138                if !self.eat_sym(",") {
2139                    break;
2140                }
2141                continue;
2142            }
2143            // `async`/`*`(generator)修飾子(`{ async method(){} }`/`{ *gen(){} }`)。
2144            // クラスのメソッド修飾子と同じ理由で以前は一切認識されず、遭遇すると
2145            // キー解析が丸ごと失敗してオブジェクトリテラル全体のパースが壊れていた。
2146            // `{ async: 1 }`("async" という名前の通常プロパティ)との曖昧さ回避のため、
2147            // 次がメソッド名になり得るトークンの場合のみ修飾子として扱う
2148            // (クラス側の同種ガードと同じロジック)。
2149            let async_modifier_ok =
2150                self.is_property_key_token(1) || self.sym_at(1, "[") || self.sym_at(1, "*");
2151            let is_async = self.is_kw("async") && async_modifier_ok;
2152            if is_async {
2153                self.bump();
2154            }
2155            let is_generator = self.eat_sym("*");
2156            // アクセサ修飾子(`{get name() {...}}` / `{set name(v) {...}}`)。クラスの
2157            // アクセサ判定と同じ2トークン先読み規則(`get`/`set` の次が「プロパティ名に
2158            // なり得るトークン」+ `(` の場合のみアクセサ扱い)。算出名
2159            // `{ get [expr](){} }` も、次が `[` ならアクセサ以外の解釈があり得ないため
2160            // 許可する(クラス側の同種修正と同じ理由)。
2161            let accessor_kind = if let Token::Ident(n) = self.cur().clone() {
2162                if (n == "get" || n == "set")
2163                    && (self.sym_at(1, "[")
2164                        || (self.is_property_key_token(1) && self.sym_at(2, "(")))
2165                {
2166                    self.bump();
2167                    Some(n == "get")
2168                } else {
2169                    None
2170                }
2171            } else {
2172                None
2173            };
2174            // 算出キー {[expr]: v}
2175            let mut computed = None;
2176            // キー: 識別子 / 文字列 / 数値 / [computed]
2177            let key = match self.cur().clone() {
2178                Token::Ident(n) => {
2179                    self.bump();
2180                    n
2181                }
2182                Token::Keyword(n) => {
2183                    self.bump();
2184                    String::from(n)
2185                }
2186                Token::Str(s) => {
2187                    self.bump();
2188                    s
2189                }
2190                Token::Num(n) => {
2191                    self.bump();
2192                    super::value::fmt_number(n)
2193                }
2194                Token::Sym("[") => {
2195                    self.bump();
2196                    computed = Some(self.parse_assignment());
2197                    self.expect_sym("]");
2198                    String::new()
2199                }
2200                _ => break,
2201            };
2202            let value = if self.eat_sym(":") {
2203                self.parse_assignment()
2204            } else if self.is_sym("(") {
2205                // メソッド短縮 key(){...}
2206                let params = self.parse_param_list();
2207                let body = self.parse_fn_body();
2208                Expression::Function {
2209                    name: Some(key.clone()),
2210                    params: Rc::new(params),
2211                    body,
2212                    is_arrow: false,
2213                    is_async,
2214                    is_generator,
2215                }
2216            } else {
2217                // 短縮プロパティ {x}
2218                Expression::Identifier(key.clone())
2219            };
2220            props.push(Property {
2221                key,
2222                value,
2223                computed,
2224                accessor: accessor_kind,
2225            });
2226            if !self.eat_sym(",") {
2227                break;
2228            }
2229        }
2230        self.expect_sym("}");
2231        Expression::Object(props)
2232    }
2233}
2234
2235// --- 演算子テーブル ---
2236
2237fn is_assign_op(op: &str) -> bool {
2238    matches!(
2239        op,
2240        "=" | "+="
2241            | "-="
2242            | "*="
2243            | "/="
2244            | "%="
2245            | "**="
2246            | "&="
2247            | "|="
2248            | "^="
2249            | "<<="
2250            | ">>="
2251            | ">>>="
2252            | "&&="
2253            | "||="
2254            | "??="
2255    )
2256}
2257
2258fn bin_prec(op: &str) -> Option<u8> {
2259    Some(match op {
2260        "??" => 1,
2261        "||" => 2,
2262        "&&" => 3,
2263        "|" => 4,
2264        "^" => 5,
2265        "&" => 6,
2266        "==" | "!=" | "===" | "!==" => 7,
2267        "<" | ">" | "<=" | ">=" | "instanceof" | "in" => 8,
2268        "<<" | ">>" | ">>>" => 9,
2269        "+" | "-" => 10,
2270        "*" | "/" | "%" => 11,
2271        "**" => 12,
2272        _ => return None,
2273    })
2274}
2275
2276fn is_right_assoc(op: &str) -> bool {
2277    op == "**"
2278}
2279
2280fn to_logical(op: &str) -> Option<LogicalOp> {
2281    match op {
2282        "&&" => Some(LogicalOp::And),
2283        "||" => Some(LogicalOp::Or),
2284        "??" => Some(LogicalOp::Nullish),
2285        _ => None,
2286    }
2287}
2288
2289fn to_binop(op: &str) -> Option<BinaryOp> {
2290    Some(match op {
2291        "+" => BinaryOp::Add,
2292        "-" => BinaryOp::Sub,
2293        "*" => BinaryOp::Mul,
2294        "/" => BinaryOp::Div,
2295        "%" => BinaryOp::Mod,
2296        "**" => BinaryOp::Pow,
2297        "==" => BinaryOp::Eq,
2298        "!=" => BinaryOp::NotEq,
2299        "===" => BinaryOp::StrictEq,
2300        "!==" => BinaryOp::StrictNotEq,
2301        "<" => BinaryOp::Lt,
2302        ">" => BinaryOp::Gt,
2303        "<=" => BinaryOp::LtEq,
2304        ">=" => BinaryOp::GtEq,
2305        "&" => BinaryOp::BitAnd,
2306        "|" => BinaryOp::BitOr,
2307        "^" => BinaryOp::BitXor,
2308        "<<" => BinaryOp::Shl,
2309        ">>" => BinaryOp::Shr,
2310        ">>>" => BinaryOp::UShr,
2311        "instanceof" => BinaryOp::InstanceOf,
2312        "in" => BinaryOp::In,
2313        _ => return None,
2314    })
2315}
2316
2317/// これ未満のトークン数の関数本体は遅延させずにその場で解析する(小さい関数は保持コストの方が大きい)。
2318const LAZY_MIN_TOKENS: usize = 24;
2319
2320/// 遅延した関数本体のソース(`{` と `}` の内側)を解析する。入れ子の関数もまた遅延する。
2321pub fn parse_function_body_source(src: &str, strict: bool) -> Vec<Statement> {
2322    let mut p = Parser::new_lazy(Lexer::new(src));
2323    p.strict = strict;
2324    let mut body = Vec::new();
2325    while !p.is_eof() {
2326        let before = p.pos;
2327        if let Some(s) = p.parse_statement() {
2328            body.push(s);
2329        }
2330        if p.pos == before {
2331            p.pos += 1;
2332        }
2333    }
2334    if p.error_count() > 0 {
2335        crate::warn!("[JS] {} syntax error(s) in lazily parsed function body", p.error_count());
2336    }
2337    body
2338}