Skip to main content

parser/
lib.rs

1use std::{collections::BTreeSet, fmt::Debug};
2
3use anyhow::{Result, anyhow};
4use dynamic::{ConstIntOp, Dynamic, Type};
5use smol_str::SmolStr;
6
7mod expr;
8pub use expr::{BinaryOp, Expr, ExprKind, UnaryOp};
9
10mod pattern;
11pub use pattern::{Pattern, PatternKind};
12
13mod stmt;
14pub use stmt::{Stmt, StmtKind};
15
16#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
17pub struct Span {
18    pub start: usize,
19    pub end: usize,
20}
21
22impl Span {
23    pub const fn new(start: usize, end: usize) -> Self {
24        Self { start, end }
25    }
26
27    pub const fn empty(pos: usize) -> Self {
28        Self { start: pos, end: pos }
29    }
30
31    pub fn merge(self, other: Self) -> Self {
32        Self { start: self.start.min(other.start), end: self.end.max(other.end) }
33    }
34}
35
36#[derive(Debug)]
37/// 解析器内的作用域嵌套深度。把同类 depth 字段打包成一个子结构,
38/// 让 Parser struct 字段更扁平、四个 depth 字段不再散落、调用方一看就懂这是"嵌套深度"
39/// 而不是别的状态。
40#[derive(Default, Clone)]
41pub(crate) struct ScopeDepths {
42    /// impl 体嵌套深度。>0 表示当前 stmt 处于 `impl { ... }` 内,
43    /// 拒绝嵌套 `struct / impl / const / static`(fn 仍允许,即方法)。
44    pub(crate) impl_depth: usize,
45    /// impl body 嵌套深度,和 impl_depth 同周期,但语义不同:
46    /// 允许方法定义,只拒绝 struct/impl/const/static。
47    pub(crate) impl_body_depth: usize,
48    /// 函数体嵌套深度。>0 表示当前 stmt 处于某个 `fn body` 内,需要拒绝
49    /// `fn / struct / impl / const / static` 等顶层声明关键字。
50    pub(crate) fn_body_depth: usize,
51    /// 当前表达式/语句递归深度,防止恶意深嵌套输入打爆调用栈
52    pub(crate) depth: usize,
53}
54
55pub struct Parser {
56    pos: usize,   //当前解析的位置
57    buf: Vec<u8>, //待解析的字符串
58    spans: Vec<usize>,
59    decl_scopes: Vec<BTreeSet<SmolStr>>,
60    scope_depths: ScopeDepths,
61    /// `match` 块顶层临时变量(__m_scrut_N / __m_done_N / __m_out_N)的后缀计数器,
62    /// 用于避免嵌套 match 重名。
63    pub(crate) match_counter: usize,
64    fatal: bool,  //递归过深等不可恢复错误;置位后所有解析入口立即失败,避免回溯重试导致死循环
65}
66
67/// [`Parser::spans`] 的 RAII 守卫。
68///
69/// 由 [`Parser::with_stmt_span`] 创建。Drop 时无论如何(包括错误冒泡)都会
70/// 弹出一个栈帧,保证 spans 不会跨 stmt 累积。
71///
72/// 设计要点:`parser` 字段不持有 `&mut Parser`(那会阻塞 stmt 内部其他
73/// `&mut self` 调用),而是用 `*mut Parser` 配合 `unsafe` 在 drop 时调用 `pop`。
74/// `stmt()` 是唯一调用点,且调用顺序是:`push` → 内部全部 `&mut self` 操作
75/// → drop 时再 `pop`,保证 pop 永远发生在最后一次 `&mut self` 之后。
76struct SpanGuard {
77    parser: *mut Parser,
78}
79
80// SAFETY:`SpanGuard` 只在单线程的解析器栈里使用,`stmt()` 是同步代码,
81// `parser` 在 drop 之前不会被其他代码路径释放。Drop 只调用 `Vec::pop`,
82// 不读 `Parser` 的任何其他字段。
83unsafe impl Send for SpanGuard {}
84unsafe impl Sync for SpanGuard {}
85
86impl Drop for SpanGuard {
87    fn drop(&mut self) {
88        // SAFETY:`parser` 来自 `with_stmt_span` 的入参,生命周期与 guard 一致;
89        // stmt() 退出时 guard 才 drop,期间无其他借用。
90        unsafe {
91            if !(*self.parser).spans.is_empty() {
92                (*self.parser).spans.pop();
93            }
94        }
95    }
96}
97
98/// 解析递归深度上限。超过即返回 [`ParserErr::TooDeep`],把"栈溢出崩溃"降级为
99/// 普通解析错误。
100///
101/// 单层 `expr_with_min_weight` 帧约 7KB,worker 线程默认栈仅 2MB,因此上限取
102/// 128(与 rustc 默认 `recursion_limit` 一致):128×7KB≈0.9MB,在最小栈上仍有
103/// 余量,而正常代码极少超过几十层嵌套。
104pub const MAX_PARSE_DEPTH: usize = 128;
105
106const NOT_IDENT: &[u8] = &[b' ', b'\t', b'\n', b'\r', b'/', b'*', b'+', b'-', b'=', b'(', b')', b'{', b'}', b'[', b']', b';', b':', b',', b'.', b'<', b'>', b'!', b'#', b'$', b'%', b'^', b'&', b'|', b'\\', b'"', b'\''];
107const WHITE_SPACE: &[u8] = &[b' ', b'\t', b'\n', b'\r'];
108const TYPES: &[(&str, Type)] = &[
109    ("bool", Type::Bool),
110    ("string", Type::Str),
111    ("i8", Type::I8),
112    ("i16", Type::I16),
113    ("i32", Type::I32),
114    ("i64", Type::I64),
115    ("u8", Type::U8),
116    ("u16", Type::U16),
117    ("u32", Type::U32),
118    ("u64", Type::U64),
119    ("f16", Type::F16),
120    ("f32", Type::F32),
121    ("f64", Type::F64),
122];
123const KEYWORDS: &[&str] = &["true", "false", "null", "let", "if", "else", "for", "in", "while", "loop", "pub", "fn", "struct", "impl", "const", "static", "continue", "return", "break", "match"];
124
125#[macro_export]
126macro_rules! parse_list {
127    ($self: ident, $start: expr, $end: expr, $sep: expr, $item_expr: expr) => {{
128        let mut items = $start;
129        loop {
130            $self.whitespace()?;
131            if $self.get()? == $end {
132                $self.pos += 1;
133                break;
134            }
135            let item = $item_expr;
136            items.push(item);
137            $self.whitespace()?;
138            if $self.get()? == $sep {
139                $self.pos += 1;
140            }
141        }
142        items
143    }};
144}
145
146#[macro_export]
147macro_rules! try_parse {
148    ($self: ident, $method: expr) => {{
149        let save_pos = $self.pos; //保存当前 pos
150        let save_decl_scopes = $self.decl_scopes.clone();
151        let save_impl_depth = $self.scope_depths.impl_depth;
152        let save_match_counter = $self.match_counter;
153        match $method {
154            Ok(expr) => Ok(expr),
155            // fatal(如递归过深)不可恢复:不回退 pos,直接上抛,避免外层换产生式重试导致死循环
156            Err(e) if $self.fatal => Err(e),
157            Err(e) => {
158                $self.pos = save_pos;
159                $self.decl_scopes = save_decl_scopes;
160                $self.scope_depths.impl_depth = save_impl_depth;
161                // 回退 match_counter,避免失败路径推进了计数器导致后续 __m_scrut_N 跳号。
162                $self.match_counter = save_match_counter;
163                Err(e)
164            }
165        }
166    }};
167}
168
169#[derive(Debug, thiserror::Error)]
170pub enum ParserErr {
171    #[error("{message}")]
172    Spanned { message: String, span: Span },
173}
174
175impl ParserErr {
176    /// 构造携带 span 的解析错误。所有 ParserErr 错误都应该走这个构造。
177    pub fn new(message: impl Into<String>, span: Span) -> Self {
178        Self::Spanned { message: message.into(), span }
179    }
180
181    /// 便捷构造:span 是 [pos, pos) 的零长 span,用于"在当前位置报错"的场景。
182    pub fn at(message: impl Into<String>, pos: usize) -> Self {
183        Self::Spanned { message: message.into(), span: Span::new(pos, pos) }
184    }
185
186    pub fn span(&self) -> Span {
187        match self {
188            Self::Spanned { span, .. } => *span,
189        }
190    }
191
192    pub fn message(&self) -> &str {
193        match self {
194            Self::Spanned { message, .. } => message,
195        }
196    }
197}
198
199/// 在 ParserErr 基础上附带 parser 当前光标位置。
200/// parse_code 顶层 downcast 此类型,做精确的 LSP-style 错误高亮。
201#[derive(Debug, thiserror::Error)]
202#[error("{err}")]
203pub struct SpannedParseError {
204    pub err: ParserErr,
205    pub pos: usize,
206}
207
208impl SpannedParseError {
209    pub fn new(err: ParserErr, pos: usize) -> Self {
210        Self { err, pos }
211    }
212}
213
214impl Parser {
215    pub fn new(buf: Vec<u8>) -> Self {
216        Self { pos: 0, buf, spans: Vec::new(), decl_scopes: vec![BTreeSet::new()], scope_depths: ScopeDepths::default(), match_counter: 0, fatal: false }
217    }
218
219    /// RAII 守卫:在构造时把当前 `pos` 推入 `spans`,在 drop 时弹出。
220    ///
221    /// 设计动机:`spans` 栈之前是手动 `push` + `pop`,但 `stmt()` 内部有十多个
222    /// `?` 提前返回路径(import / let / fn …),任何一条错误路径走完时都
223    /// 不会清理 `spans`,导致下次错误消息的 [`error_stmt`] 把上一个 stmt 的
224    /// 内容误当成当前错误的上下文 —— 错误定位严重漂移。
225    ///
226    /// 用 RAII guard:无论函数是 `Ok` 还是 `Err` 返回,`Drop` 总会清理栈帧,
227    /// 把 `spans.last()` 始终精确指向"当前正在解析的 stmt"。
228    ///
229    /// 实现细节:guard 持有 `*mut Parser` 而不是 `&mut Parser`,这样不阻塞
230    /// stmt 内部其他 `&mut self` 调用(否则 borrow checker 会失败)。
231    fn with_stmt_span(&mut self) -> SpanGuard {
232        self.spans.push(self.pos);
233        SpanGuard { parser: self as *mut Parser }
234    }
235
236    /// 进入一层递归:自增深度并校验上限。配合 [`Parser::exit_depth`] 使用。
237    ///
238    /// 超限时置 [`Parser::fatal`]:这是不可恢复错误。否则 `try_parse!` 的回溯会
239    /// 把 [`ParserErr::TooDeep`] 当成"换个产生式再试",pos 回退后外层循环原地重试,
240    /// 形成死循环。置位后 [`Parser::check_fatal`] 让每个解析入口立即失败,错误一路
241    /// 通过 `?` 上抛终止解析。
242    fn enter_depth(&mut self) -> Result<()> {
243        self.scope_depths.depth += 1;
244        if self.scope_depths.depth > MAX_PARSE_DEPTH {
245            self.scope_depths.depth -= 1;
246            self.fatal = true;
247            return Err(ParserErr::at("表达式嵌套过深", self.current_pos()).into());
248        }
249        Ok(())
250    }
251
252    fn exit_depth(&mut self) {
253        self.scope_depths.depth = self.scope_depths.depth.saturating_sub(1);
254    }
255
256    /// 解析入口的快速失败检查:一旦进入 fatal 状态,立即返回错误,阻止任何回溯重试。
257    fn check_fatal(&self) -> Result<()> {
258        if self.fatal { Err(ParserErr::at("表达式嵌套过深", self.current_pos()).into()) } else { Ok(()) }
259    }
260
261    pub(crate) fn push_decl_scope(&mut self) {
262        self.decl_scopes.push(BTreeSet::new());
263    }
264
265    pub(crate) fn pop_decl_scope(&mut self) {
266        if self.decl_scopes.len() > 1 {
267            self.decl_scopes.pop();
268        }
269    }
270
271    fn declare_symbol(&mut self, name: &SmolStr) -> Result<()> {
272        if name.is_empty() {
273            return Ok(());
274        }
275        if self.decl_scopes.iter().rev().any(|scope| scope.contains(name)) {
276            return Err(ParserErr::at(format!("符号 {} 已经声明", name), self.current_pos()).into());
277        }
278        self.decl_scopes.last_mut().expect("parser always has a declaration scope").insert(name.clone());
279        Ok(())
280    }
281
282    pub(crate) fn declare_symbol_in_current_scope(&mut self, name: &SmolStr) -> Result<()> {
283        if name.is_empty() {
284            return Ok(());
285        }
286        let scope = self.decl_scopes.last_mut().expect("parser always has a declaration scope");
287        if scope.contains(name) {
288            return Err(ParserErr::at(format!("符号 {} 已经声明", name), self.current_pos()).into());
289        }
290        scope.insert(name.clone());
291        Ok(())
292    }
293
294    fn declare_function_name(&mut self, name: &SmolStr) -> Result<()> {
295        if self.scope_depths.impl_depth > 0 { self.declare_symbol_in_current_scope(name) } else { self.declare_symbol(name) }
296    }
297
298    fn declare_args(&mut self, args: &[(SmolStr, Type)]) -> Result<()> {
299        for (name, _) in args {
300            self.declare_symbol(name)?;
301        }
302        Ok(())
303    }
304
305    pub(crate) fn declare_pattern_symbols(&mut self, pat: &Pattern) -> Result<()> {
306        match &pat.kind {
307            PatternKind::Ident { name, .. } => self.declare_symbol_in_current_scope(name),
308            PatternKind::Tuple(items) => {
309                for item in items {
310                    self.declare_pattern_symbols(item)?;
311                }
312                Ok(())
313            }
314            PatternKind::List { elems, .. } => {
315                for item in elems {
316                    self.declare_pattern_symbols(item)?;
317                }
318                Ok(())
319            }
320            PatternKind::Struct { fields, .. } => {
321                for (name, sub) in fields {
322                    if let Some(sub) = sub {
323                        self.declare_pattern_symbols(sub)?;
324                    } else {
325                        self.declare_symbol_in_current_scope(name)?;
326                    }
327                }
328                Ok(())
329            }
330            PatternKind::Wildcard | PatternKind::Var { .. } | PatternKind::Literal(_) | PatternKind::Member(_, _) | PatternKind::Idx(_, _) => Ok(()),
331        }
332    }
333
334    fn function_body(&mut self, args: &[(SmolStr, Type)]) -> Result<Stmt> {
335        self.push_decl_scope();
336        self.scope_depths.fn_body_depth += 1;
337        let result = (|| {
338            self.declare_args(args)?;
339            self.block()
340        })();
341        self.scope_depths.fn_body_depth -= 1;
342        self.pop_decl_scope();
343        result
344    }
345
346    fn impl_body(&mut self) -> Result<Stmt> {
347        self.push_decl_scope();
348        self.scope_depths.impl_depth += 1;
349        self.scope_depths.impl_body_depth += 1;
350        let result = self.block();
351        self.scope_depths.impl_body_depth -= 1;
352        self.scope_depths.impl_depth -= 1;
353        self.pop_decl_scope();
354        result
355    }
356
357    pub fn is_eof(&self) -> bool {
358        self.pos >= self.buf.len()
359    }
360
361    pub fn get(&self) -> Result<u8> {
362        //查看当前字符
363        self.buf.get(self.pos).cloned().ok_or_else(|| ParserErr::at("输入结束", self.pos).into())
364    }
365
366    pub fn take(&mut self, ch: u8) -> Result<()> {
367        //如果当前字符为 ch 消费该字符 返回 Ok(())
368        if self.buf.get(self.pos).map(|b| *b == ch).unwrap_or(false) {
369            self.pos += 1;
370            Ok(())
371        } else {
372            // 修复:EOF 时 `buf.get(self.pos)` 返回 None,原代码用 `unwrap_or(0)`
373            // 把字符报成 `\0`(控制字符),误导用户。改为显式判断 EOF,报"已到文件末尾"。
374            let actual_desc = match self.buf.get(self.pos) {
375                Some(byte) => format!("实际字符 {}", *byte as char),
376                None => "已到文件末尾".to_string(),
377            };
378            Err(SpannedParseError::new(ParserErr::at(format!("期望字符 {} {}", ch as char, actual_desc), self.pos), self.pos).into())
379        }
380    }
381
382    pub fn until(&mut self, ch: u8) -> Result<()> {
383        //消费直到指定字符 ch 忽略空白和注释
384        self.whitespace()?;
385        self.take(ch)
386    }
387
388    pub fn ahead(&self) -> Result<u8> {
389        //朝前看
390        self.buf.get(self.pos + 1).cloned().ok_or_else(|| ParserErr::at("输入结束", self.pos).into())
391    }
392
393    pub fn get_str(&self, start: usize, stop: usize) -> SmolStr {
394        SmolStr::from(String::from_utf8_lossy(&self.buf[start..stop]))
395    }
396
397    pub fn error_stmt(&self) -> SmolStr {
398        SmolStr::from(String::from_utf8_lossy(&self.buf[self.spans.last().cloned().unwrap_or(0)..self.pos]))
399    }
400
401    pub fn current_pos(&self) -> usize {
402        self.pos
403    }
404
405    pub fn span_from(&self, start: usize) -> Span {
406        Span::new(start, self.pos)
407    }
408
409    pub fn collect<F: Fn(u8) -> bool>(&mut self, f: F) -> Result<(usize, usize)> {
410        let start = self.pos;
411        while self.pos < self.buf.len() && f(self.buf[self.pos]) {
412            self.pos += 1;
413        }
414        if self.pos > start { Ok((start, self.pos)) } else { Err(ParserErr::at("未发现期望字符", start).into()) }
415    }
416
417    pub fn just(&mut self, pattern: &str) -> Result<()> {
418        if self.buf.len() - self.pos >= pattern.len() && self.buf[self.pos..self.pos + pattern.len()].eq(pattern.as_bytes()) {
419            self.pos += pattern.len();
420            Ok(())
421        } else {
422            Err(ParserErr::at(format!("期望字符串 {}", pattern), self.pos).into())
423        }
424    }
425
426    pub fn keyword(&mut self, pattern: &str) -> Result<()> {
427        self.just(pattern)?;
428        if self.pos < self.buf.len() && !NOT_IDENT.contains(&self.buf[self.pos]) {
429            self.pos -= pattern.len();
430            return Err(ParserErr::at(format!("期望字符串 {}", pattern), self.pos).into());
431        }
432        Ok(())
433    }
434
435    pub fn get_type(&mut self) -> Result<Type> {
436        self.whitespace()?;
437        if self.get()? == b'[' {
438            self.pos += 1;
439            let ty = self.get_type()?;
440            self.until(b';')?;
441            self.whitespace()?;
442            let len = self.get_type_param()?;
443            self.until(b']')?;
444            if let Type::ConstInt(number) = len {
445                let number = u32::try_from(number).map_err(|_| anyhow!("数组长度超出 u32 范围"))?;
446                Ok(Type::Array(std::rc::Rc::new(ty), number))
447            } else {
448                Ok(Type::ArrayParam(std::rc::Rc::new(ty), std::rc::Rc::new(len)))
449            }
450        } else {
451            for ty in TYPES {
452                if self.just(ty.0).is_ok() {
453                    return Ok(ty.1.clone());
454                }
455            }
456            let name = self.ident()?;
457            if self.take(b'<').is_ok() {
458                let params = crate::parse_list!(self, Vec::new(), b'>', b',', self.get_type_param()?);
459                Ok(Type::Ident { name, params })
460            } else {
461                Ok(Type::Ident { name, params: Vec::new() })
462            }
463        }
464    }
465
466    pub fn get_type_param(&mut self) -> Result<Type> {
467        self.const_type_param_add()
468    }
469
470    fn const_type_param_add(&mut self) -> Result<Type> {
471        let mut left = self.const_type_param_mul()?;
472        loop {
473            self.whitespace()?;
474            let op = if self.take(b'+').is_ok() {
475                Some(ConstIntOp::Add)
476            } else if self.take(b'-').is_ok() {
477                Some(ConstIntOp::Sub)
478            } else {
479                None
480            };
481            let Some(op) = op else { break };
482            let right = self.const_type_param_mul()?;
483            left = Self::fold_const_type_binary(op, left, right)?;
484        }
485        Ok(left)
486    }
487
488    fn const_type_param_mul(&mut self) -> Result<Type> {
489        let mut left = self.const_type_param_primary()?;
490        loop {
491            self.whitespace()?;
492            let op = if self.take(b'*').is_ok() {
493                Some(ConstIntOp::Mul)
494            } else if self.take(b'/').is_ok() {
495                Some(ConstIntOp::Div)
496            } else if self.take(b'%').is_ok() {
497                Some(ConstIntOp::Mod)
498            } else {
499                None
500            };
501            let Some(op) = op else { break };
502            let right = self.const_type_param_primary()?;
503            left = Self::fold_const_type_binary(op, left, right)?;
504        }
505        Ok(left)
506    }
507
508    fn const_type_param_primary(&mut self) -> Result<Type> {
509        self.whitespace()?;
510        if self.take(b'(').is_ok() {
511            let ty = self.get_type_param()?;
512            self.until(b')')?;
513            return Ok(ty);
514        }
515        if self.get()?.is_ascii_digit() {
516            let value = self.number()?;
517            if let Some(value) = value.as_uint() {
518                let value = i64::try_from(value).map_err(|_| anyhow!("模板数字参数超出 i64 范围"))?;
519                Ok(Type::ConstInt(value))
520            } else if let Some(value) = value.as_int() {
521                Ok(Type::ConstInt(value))
522            } else {
523                Err(anyhow!("模板数字参数必须是整数"))
524            }
525        } else {
526            self.get_type()
527        }
528    }
529
530    fn fold_const_type_binary(op: ConstIntOp, left: Type, right: Type) -> Result<Type> {
531        if let (Type::ConstInt(left), Type::ConstInt(right)) = (&left, &right) {
532            let value = match op {
533                ConstIntOp::Add => left + right,
534                ConstIntOp::Sub => left - right,
535                ConstIntOp::Mul => left * right,
536                ConstIntOp::Div => {
537                    if *right == 0 {
538                        return Err(anyhow!("模板整数除以 0"));
539                    }
540                    left / right
541                }
542                ConstIntOp::Mod => {
543                    if *right == 0 {
544                        return Err(anyhow!("模板整数取模 0"));
545                    }
546                    left % right
547                }
548            };
549            Ok(Type::ConstInt(value))
550        } else {
551            Ok(Type::ConstBinary { op, left: std::rc::Rc::new(left), right: std::rc::Rc::new(right) })
552        }
553    }
554
555    pub fn comment(&mut self) -> Result<()> {
556        if self.get()? == b'/' && self.ahead()? == b'/' {
557            self.pos += 2;
558            while self.pos < self.buf.len() && self.buf[self.pos] != b'\n' {
559                self.pos += 1;
560            }
561            Ok(())
562        } else if self.get()? == b'/' && self.ahead()? == b'*' {
563            self.pos += 2;
564            while self.pos + 1 < self.buf.len() {
565                if self.buf[self.pos] == b'*' && self.buf[self.pos + 1] == b'/' {
566                    self.pos += 2;
567                    return Ok(());
568                }
569                self.pos += 1;
570            }
571            Err(ParserErr::at("未关闭的注释", self.pos).into())
572        } else {
573            Ok(())
574        }
575    }
576
577    pub fn whitespace(&mut self) -> Result<()> {
578        while self.pos < self.buf.len() {
579            self.comment()?;
580            if self.pos >= self.buf.len() || !WHITE_SPACE.contains(&self.buf[self.pos]) {
581                break;
582            }
583            self.pos += 1;
584        }
585        Ok(())
586    }
587
588    pub fn ident(&mut self) -> Result<SmolStr> {
589        let (start, mut stop) = self.collect(|ch| !NOT_IDENT.contains(&ch))?;
590        loop {
591            let save_pos = self.pos;
592            if self.just("::").is_err() {
593                break;
594            }
595            match self.collect(|ch| !NOT_IDENT.contains(&ch)) {
596                Ok((_, next_stop)) => {
597                    stop = next_stop;
598                }
599                Err(_) => {
600                    self.pos = save_pos;
601                    break;
602                }
603            }
604        }
605        if KEYWORDS.iter().position(|k| k.as_bytes() == &self.buf[start..stop]).is_some() {
606            return Err(anyhow!("发现关键字{}", String::from_utf8_lossy(&self.buf[start..stop])));
607        }
608        Ok(self.get_str(start, stop))
609    }
610
611    pub fn string(&mut self) -> Result<SmolStr> {
612        if self.get()? != b'"' {
613            return Err(ParserErr::at("非字符串", self.current_pos()).into());
614        }
615        self.pos += 1;
616        let mut text_buf = Vec::new();
617        while self.pos < self.buf.len() {
618            if self.buf[self.pos] == b'\\' {
619                //转义字符
620                self.pos += 1;
621                // 反斜杠后直接 EOF(如 "abc\):pos 已越界,报错而非 panic。
622                if self.pos >= self.buf.len() {
623                    return Err(ParserErr::at("未完成的转义序列", self.pos).into());
624                }
625                match self.buf[self.pos] {
626                    b'n' => {
627                        text_buf.push(b'\n');
628                        self.pos += 1;
629                    }
630                    b'r' => {
631                        text_buf.push(b'\r');
632                        self.pos += 1;
633                    }
634                    b't' => {
635                        text_buf.push(b'\t');
636                        self.pos += 1;
637                    }
638                    ch @ (b'\\' | b'"') => {
639                        text_buf.push(ch);
640                        self.pos += 1;
641                    }
642                    b'u' => {
643                        self.pos += 1;
644                        let unicode = if self.take(b'{').is_ok() {
645                            let code = self.hex()?;
646                            self.pos += 1;
647                            code
648                        } else {
649                            self.hex()?
650                        };
651                        let ch = char::from_u32(unicode as u32).ok_or(anyhow!("非法 unicode {}", unicode))?;
652                        let mut utf8_buf = [0u8; 4];
653                        let s = ch.encode_utf8(&mut utf8_buf);
654                        text_buf.extend_from_slice(s.as_bytes());
655                    }
656                    b'x' => {
657                        self.pos += 1;
658                        if self.pos + 2 > self.buf.len() {
659                            return Err(anyhow!("非法 \\x 转义:需要 2 位十六进制"));
660                        }
661                        let start = self.pos;
662                        self.pos += 2;
663                        let hex = &self.buf[start..self.pos];
664                        if hex.iter().any(|b| !b.is_ascii_hexdigit()) {
665                            return Err(anyhow!("非法 \\x 转义:仅允许十六进制字符"));
666                        }
667                        let code = u32::from_str_radix(String::from_utf8_lossy(hex).as_ref(), 16)?;
668                        if code > 0xFF {
669                            return Err(anyhow!("\\x 转义值 0x{:02X} 超出 0xFF", code));
670                        }
671                        text_buf.push(code as u8);
672                    }
673                    other => {
674                        return Err(anyhow!("invalid escape character: {}", other as char));
675                    }
676                }
677            } else {
678                if self.buf[self.pos] == b'"' {
679                    self.pos += 1;
680                    return Ok(String::from_utf8(text_buf)?.into());
681                }
682                text_buf.push(self.buf[self.pos]);
683                self.pos += 1;
684            }
685        }
686        Err(ParserErr::at("未关闭字符串", self.pos).into())
687    }
688
689    pub fn text(&mut self) -> Result<SmolStr> {
690        if self.get()? == b'r' && [b'#', b'"'].contains(&self.ahead()?) {
691            self.pos += 1;
692            // 收集 `#` 前缀:`r#####` 是 Rust 风格的原始字符串语法。原先
693            // 漏掉 `self.pos < self.buf.len()` 边界检查,会在 `r##` /
694            // `r#####` 后跟 EOF(没有匹配的 `"`)时越过 buf 末尾 panic。
695            // 用 `lookahead == b'#'` 判断继续/停止,免去直接下标的越界。
696            let mut hash_count: usize = 0;
697            while self.pos < self.buf.len() && self.buf[self.pos] == b'#' {
698                hash_count += 1;
699                self.pos += 1;
700            }
701            // `r#"(abc)` 形式 — 若下一个字符不是 `"`,直接报错。不强行构造 end,
702            // 因为后面若抛错,builder 也用不到 end,避免再触发"start>stop" panic。
703            if self.get()? != b'"' {
704                return Err(ParserErr::at("非法的原始字符串", self.current_pos()).into());
705            }
706            self.pos += 1;
707            // 收尾的 `#...#"` 序列必须与前缀数量一致才算闭合。注意顺序:
708            // 闭合是 `"` 在前、N 个 `#` 在后(`r#"..."#` 的右边是 `"#`),
709            // 不是 `#"#`(前者才是 Rust/曾用方案的形态)。
710            let mut end: Vec<u8> = Vec::with_capacity(hash_count + 1);
711            end.push(b'"');
712            for _ in 0..hash_count {
713                end.push(b'#');
714            }
715            let start_pos = self.pos;
716            while self.pos < self.buf.len() {
717                if self.pos + end.len() <= self.buf.len() && self.buf[self.pos..self.pos + end.len()].eq(&end) {
718                    break;
719                }
720                self.pos += 1;
721            }
722            // 走到末尾仍未闭合 — 报"未关闭字符串"而不是悄悄 panic。
723            if self.pos + end.len() > self.buf.len() {
724                return Err(ParserErr::at("未关闭字符串", self.current_pos()).into());
725            }
726            // 这里一定有 `self.pos <= start_pos`(闭合,内层可能就直接相等)。
727            let stop = self.pos;
728            self.pos += end.len();
729            Ok(self.get_str(start_pos, stop))
730        } else {
731            self.string()
732        }
733    }
734
735    fn hex(&mut self) -> Result<i32> {
736        //注意 hex 会消耗当前字符 设置新的 self.pos
737        let (start, stop) = self.collect(|ch| (ch >= b'0' && ch <= b'9') || (ch >= b'a' && ch <= b'f') || (ch >= b'A' && ch <= b'F'))?;
738        Ok(i32::from_str_radix(&String::from_utf8_lossy(&self.buf[start..stop]), 16)?)
739    }
740
741    fn numeric_suffix(&mut self) -> Option<Type> {
742        let save = self.pos;
743        for (name, ty) in TYPES {
744            if !ty.is_native() {
745                continue;
746            }
747            if self.buf.len() >= self.pos + name.len() && self.buf[self.pos..self.pos + name.len()].eq(name.as_bytes()) {
748                // 校验后继字符不是 ident 字符,
749                // 避免 123i8x 匹配 i8 留下 x 导致后续解析错乱。
750                let after = self.pos + name.len();
751                let ok = after >= self.buf.len() || NOT_IDENT.contains(&self.buf[after]);
752                if ok {
753                    self.pos = after;
754                    return Some(ty.clone());
755                }
756            }
757        }
758        self.pos = save;
759        None
760    }
761
762    fn int_literal(&mut self, digits: &str, radix: u32, suffix: Option<Type>) -> Result<Dynamic> {
763        // 默认整数类型为 I64:常见的较大十进制数(如 30 亿)不再静默回绕成负数。
764        let ty = suffix.unwrap_or(Type::I64);
765        // 负号由一元运算符单独解析,这里的字面量恒为非负,因此统一解析成 u128。
766        let magnitude = u128::from_str_radix(digits, radix).map_err(|_| anyhow!("整数字面量 {} 超出可表示范围", digits))?;
767        let (signed, bits) = match ty {
768            Type::I8 => (true, 8u32),
769            Type::I16 => (true, 16),
770            Type::I32 => (true, 32),
771            Type::I64 => (true, 64),
772            Type::U8 => (false, 8),
773            Type::U16 => (false, 16),
774            Type::U32 => (false, 32),
775            Type::U64 => (false, 64),
776            Type::F16 => return Ok(Dynamic::F16(dynamic::f64_to_f16(magnitude as f64))),
777            Type::F32 => return Ok(Dynamic::F32(magnitude as f32)),
778            Type::F64 => return Ok(Dynamic::F64(magnitude as f64)),
779            ty => return Err(anyhow!("{:?} 不能作为数字后缀", ty)),
780        };
781        let unsigned_max = (1u128 << bits) - 1;
782        // 十进制按数值语义判界(有符号允许到 |MIN|,即 2^(bits-1),以支持 -128i8、i64::MIN);
783        // 十六/八/二进制按位模式语义判界,允许写满整型位宽(如 0xFFFFFFFF 仍是合法的位掩码)。
784        let max_allowed = if radix == 10 { if signed { unsigned_max / 2 + 1 } else { unsigned_max } } else { unsigned_max };
785        if magnitude > max_allowed {
786            return Err(anyhow!("整数字面量 {} 超出 {:?} 的范围", digits, ty));
787        }
788        Ok(match ty {
789            Type::I8 => Dynamic::I8(magnitude as i8),
790            Type::I16 => Dynamic::I16(magnitude as i16),
791            Type::I32 => Dynamic::I32(magnitude as i32),
792            Type::I64 => Dynamic::I64(magnitude as i64),
793            Type::U8 => Dynamic::U8(magnitude as u8),
794            Type::U16 => Dynamic::U16(magnitude as u16),
795            Type::U32 => Dynamic::U32(magnitude as u32),
796            Type::U64 => Dynamic::U64(magnitude as u64),
797            _ => unreachable!(),
798        })
799    }
800
801    fn float_literal(&mut self, digits: &str, suffix: Option<Type>) -> Result<Dynamic> {
802        let value: f64 = digits.parse()?;
803        if let Some(ref ty) = suffix {
804            // 整数类后缀:校验是否在目标范围内。NaN / Inf 一律拒绝;
805            // 不允许小数部分。F16/F32/F64 不做范围 / 整数性校验。
806            let is_int_suffix = matches!(ty, Type::I8 | Type::I16 | Type::I32 | Type::I64 | Type::U8 | Type::U16 | Type::U32 | Type::U64);
807            if is_int_suffix {
808                let (min, max): (f64, f64) = match ty {
809                    Type::I8 => (i8::MIN as f64, i8::MAX as f64),
810                    Type::I16 => (i16::MIN as f64, i16::MAX as f64),
811                    Type::I32 => (i32::MIN as f64, i32::MAX as f64),
812                    Type::I64 => (i64::MIN as f64, i64::MAX as f64),
813                    Type::U8 => (0.0, u8::MAX as f64),
814                    Type::U16 => (0.0, u16::MAX as f64),
815                    Type::U32 => (0.0, u32::MAX as f64),
816                    Type::U64 => (0.0, u64::MAX as f64),
817                    _ => unreachable!(),
818                };
819                if !value.is_finite() || value < min || value > max || value.fract() != 0.0 {
820                    return Err(anyhow!("浮点字面量 {:?} 超出 {:?} 范围", value, ty));
821                }
822            } else if !value.is_finite() {
823                return Err(anyhow!("非法浮点字面量: {:?}", value));
824            }
825        }
826        Ok(match suffix.unwrap_or(Type::F32) {
827            Type::I8 => Dynamic::I8(value as i8),
828            Type::I16 => Dynamic::I16(value as i16),
829            Type::I32 => Dynamic::I32(value as i32),
830            Type::I64 => Dynamic::I64(value as i64),
831            Type::U8 => Dynamic::U8(value as u8),
832            Type::U16 => Dynamic::U16(value as u16),
833            Type::U32 => Dynamic::U32(value as u32),
834            Type::U64 => Dynamic::U64(value as u64),
835            Type::F16 => Dynamic::F16(dynamic::f64_to_f16(value)),
836            Type::F32 => Dynamic::F32(value as f32),
837            Type::F64 => Dynamic::F64(value),
838            ty => return Err(anyhow!("{:?} 不能作为浮点数字后缀", ty)),
839        })
840    }
841
842    pub fn number(&mut self) -> Result<Dynamic> {
843        if self.get()? == b'0' {
844            if [b'b', b'B'].contains(&self.ahead()?) {
845                self.pos += 2;
846                let (start, stop) = self.collect(|ch| ch == b'0' || ch == b'1')?;
847                let s = String::from_utf8_lossy(&self.buf[start..stop]).to_string();
848                let suffix = self.numeric_suffix();
849                return self.int_literal(&s, 2, suffix);
850            } else if [b'o', b'O'].contains(&self.ahead()?) {
851                self.pos += 2;
852                let (start, stop) = self.collect(|ch| ch >= b'0' && ch <= b'7')?;
853                let s = String::from_utf8_lossy(&self.buf[start..stop]).to_string();
854                let suffix = self.numeric_suffix();
855                return self.int_literal(&s, 8, suffix);
856            } else if [b'x', b'X'].contains(&self.ahead()?) {
857                self.pos += 2;
858                let (start, stop) = self.collect(|ch| (ch >= b'0' && ch <= b'9') || (ch >= b'a' && ch <= b'f') || (ch >= b'A' && ch <= b'F'))?;
859                let s = String::from_utf8_lossy(&self.buf[start..stop]).to_string();
860                let suffix = self.numeric_suffix();
861                return self.int_literal(&s, 16, suffix);
862            }
863        }
864        let start = self.pos;
865        while self.pos < self.buf.len() && self.buf[self.pos] <= b'9' && self.buf[self.pos] >= b'0' {
866            self.pos += 1;
867        }
868        let mut is_float = false;
869        if self.pos < self.buf.len() && self.buf[self.pos] == b'.' && self.ahead().map(|ch| ch <= b'9' && ch >= b'0').unwrap_or(false) {
870            is_float = true;
871            self.pos += 1;
872            while self.pos < self.buf.len() && self.buf[self.pos] <= b'9' && self.buf[self.pos] >= b'0' {
873                self.pos += 1;
874            }
875        }
876        if self.pos < self.buf.len() && (self.buf[self.pos] == b'e' || self.buf[self.pos] == b'E') {
877            let mut exp_pos = self.pos + 1;
878            if exp_pos < self.buf.len() && (self.buf[exp_pos] == b'+' || self.buf[exp_pos] == b'-') {
879                exp_pos += 1;
880            }
881            if exp_pos < self.buf.len() && self.buf[exp_pos] <= b'9' && self.buf[exp_pos] >= b'0' {
882                is_float = true;
883                self.pos = exp_pos + 1;
884                while self.pos < self.buf.len() && self.buf[self.pos] <= b'9' && self.buf[self.pos] >= b'0' {
885                    self.pos += 1;
886                }
887            }
888        }
889        if self.pos > start {
890            let text = String::from_utf8_lossy(&self.buf[start..self.pos]).to_string();
891            let suffix = self.numeric_suffix();
892            if is_float {
893                return self.float_literal(&text, suffix);
894            }
895            return self.int_literal(&text, 10, suffix);
896        }
897        Err(ParserErr::at("非数字", start).into())
898    }
899}
900
901#[cfg(test)]
902mod tests {
903    use super::*;
904
905    fn parse_all(code: &str) -> Result<Vec<Stmt>> {
906        let mut parser = Parser::new(code.as_bytes().to_vec());
907        let mut stmts = Vec::new();
908        loop {
909            match parser.stmt(false) {
910                Ok(stmt) => stmts.push(stmt),
911                Err(err) => {
912                    if parser.is_eof() {
913                        return Ok(stmts);
914                    }
915                    return Err(err);
916                }
917            }
918        }
919    }
920
921    // 调试构建里单帧约 16KB,病态深嵌套即便有深度守卫也会在守卫触发"之前"打爆
922    // 测试线程默认 2MB 栈;因此用大栈线程跑,验证守卫确实返回 TooDeep(而非崩溃)。
923    // 生产是 release 构建,单帧仅数 KB,128 层上限在 8MB 主栈上余量充足。
924    fn run_with_big_stack(f: impl FnOnce() + Send + 'static) {
925        std::thread::Builder::new().stack_size(64 * 1024 * 1024).spawn(f).unwrap().join().unwrap();
926    }
927
928    #[test]
929    fn deeply_nested_parens_error_instead_of_stack_overflow() {
930        run_with_big_stack(|| {
931            let depth = MAX_PARSE_DEPTH + 50;
932            let code = format!("{}1{}", "(".repeat(depth), ")".repeat(depth));
933            let mut parser = Parser::new(code.into_bytes());
934            let err = parser.get_expr().unwrap_err();
935            assert!(err.to_string().contains("嵌套过深"), "got: {err}");
936        });
937    }
938
939    #[test]
940    fn deeply_nested_blocks_error_instead_of_stack_overflow() {
941        run_with_big_stack(|| {
942            let depth = MAX_PARSE_DEPTH + 50;
943            let code = format!("fn f() {}{}{}", "{".repeat(depth), "1", "}".repeat(depth));
944            let err = parse_all(&code).unwrap_err();
945            assert!(err.to_string().contains("嵌套过深"), "got: {err}");
946        });
947    }
948
949    #[test]
950    fn normal_nesting_within_limit_parses() {
951        // 远低于上限的正常嵌套不受影响
952        let code = format!("{}1{}", "(".repeat(32), ")".repeat(32));
953        let mut parser = Parser::new(code.into_bytes());
954        parser.get_expr().unwrap();
955    }
956
957    fn parse_literal(code: &str) -> Result<Dynamic> {
958        let mut parser = Parser::new(code.as_bytes().to_vec());
959        match parser.get_expr()?.kind {
960            crate::ExprKind::Value(value) => Ok(value),
961            other => Err(anyhow!("不是字面量: {:?}", other)),
962        }
963    }
964
965    #[test]
966    fn unsuffixed_integer_defaults_to_i64() {
967        assert_eq!(parse_literal("5").unwrap(), Dynamic::I64(5));
968        // 30 亿:旧的 I32 默认会静默回绕成负数,I64 默认保留正确数值
969        assert_eq!(parse_literal("3000000000").unwrap(), Dynamic::I64(3000000000));
970    }
971
972    #[test]
973    fn out_of_range_integer_literals_error() {
974        // 超出 u64,连 i128 解析也容纳不下 → 报错而非回绕
975        assert!(parse_literal("99999999999999999999999999999999999999999").is_err());
976        // 窄后缀越界
977        assert!(parse_literal("255i8").unwrap_err().to_string().contains("超出"));
978        assert!(parse_literal("70000i16").unwrap_err().to_string().contains("超出"));
979        assert!(parse_literal("256u8").unwrap_err().to_string().contains("超出"));
980    }
981
982    #[test]
983    fn signed_min_magnitude_literals_allowed() {
984        // -128i8 由一元负号 + 字面量 128 组成,字面量 128 必须可被接受
985        assert_eq!(parse_literal("128i8").unwrap(), Dynamic::I8(-128));
986        assert_eq!(parse_literal("9223372036854775808").unwrap(), Dynamic::I64(i64::MIN));
987    }
988
989    #[test]
990    fn hex_literals_keep_bit_pattern() {
991        // 十六进制按位模式语义:0xFFFFFFFF 是合法掩码,默认 I64 容纳为正值
992        assert_eq!(parse_literal("0xFFFFFFFF").unwrap(), Dynamic::I64(0xFFFFFFFF));
993        // 写满目标位宽的掩码允许通过(0xFF -> i8 的 -1)
994        assert_eq!(parse_literal("0xFFi8").unwrap(), Dynamic::I8(-1));
995        assert_eq!(parse_literal("0xFFFFFFFFu32").unwrap(), Dynamic::U32(u32::MAX));
996    }
997
998    // 把表达式 AST 渲染成 S 表达式,用来锁定优先级/结合性(expr.rs 手写树旋转逻辑)。
999    fn shape(code: &str) -> String {
1000        let mut parser = Parser::new(code.as_bytes().to_vec());
1001        let expr = parser.get_expr().expect("parse");
1002        fmt_shape(&expr)
1003    }
1004
1005    fn binop_sym(op: &crate::BinaryOp) -> &'static str {
1006        op.symbol()
1007    }
1008
1009    fn fmt_shape(expr: &crate::Expr) -> String {
1010        use crate::ExprKind::*;
1011        match &expr.kind {
1012            Value(v) => format!("{:?}", v).replace("I64(", "").replace("I32(", "").trim_end_matches(')').to_string(),
1013            Ident(name) => name.to_string(),
1014            Unary { op, value } => {
1015                let s = if matches!(op, crate::UnaryOp::Neg) { "-" } else { "!" };
1016                format!("({} {})", s, fmt_shape(value))
1017            }
1018            Binary { left, op, right } => format!("({} {} {})", binop_sym(op), fmt_shape(left), fmt_shape(right)),
1019            Range { start, stop, inclusive } => format!("({} {} {})", if *inclusive { "..=" } else { ".." }, fmt_shape(start), fmt_shape(stop)),
1020            Typed { value, ty } => format!("(as {} {:?})", fmt_shape(value), ty),
1021            other => format!("{:?}", other),
1022        }
1023    }
1024
1025    #[test]
1026    fn precedence_and_associativity_golden() {
1027        // 乘法高于加法
1028        assert_eq!(shape("1 + 2 * 3"), "(+ 1 (* 2 3))");
1029        assert_eq!(shape("1 * 2 + 3"), "(+ (* 1 2) 3)");
1030        // 同级左结合
1031        assert_eq!(shape("1 - 2 - 3"), "(- (- 1 2) 3)");
1032        assert_eq!(shape("8 / 4 / 2"), "(/ (/ 8 4) 2)");
1033        // 移位低于加法
1034        assert_eq!(shape("2 + 3 << 4"), "(<< (+ 2 3) 4)");
1035        // 位运算优先级:& 高于 ^ 高于 |
1036        assert_eq!(shape("1 | 2 ^ 3 & 4"), "(| 1 (^ 2 (& 3 4)))");
1037        // 比较低于算术
1038        assert_eq!(shape("1 + 2 == 3"), "(== (+ 1 2) 3)");
1039        // 逻辑:&& 高于 ||
1040        assert_eq!(shape("a && b || c"), "(|| (&& a b) c)");
1041        // 一元高于乘法
1042        assert_eq!(shape("-a * b"), "(* (- a) b)");
1043        assert_eq!(shape("!a == b"), "(== (! a) b)");
1044    }
1045
1046    #[test]
1047    fn assignment_range_and_as_precedence_golden() {
1048        // 赋值最低优先级,右结合
1049        assert_eq!(shape("a = b + c"), "(= a (+ b c))");
1050        assert_eq!(shape("a = b = c"), "(= a (= b c))");
1051        assert_eq!(shape("a = b = c = d"), "(= a (= b (= c d)))");
1052        // 复合赋值
1053        assert_eq!(shape("a += b * c"), "(+= a (* b c))");
1054        // range 边界是完整算术表达式(上界按完整子表达式解析)
1055        assert_eq!(shape("1 + 1 .. n * 2"), "(.. (+ 1 1) (* n 2))");
1056        assert_eq!(shape("0 ..= n - 1"), "(..= 0 (- n 1))");
1057        // as 紧绑定到操作数,优先级高于二元算术(Rust 语义)
1058        assert_eq!(shape("a + b as i64"), "(+ a (as b I64))");
1059        assert_eq!(shape("a as i64 + b"), "(+ (as a I64) b)");
1060        assert_eq!(shape("(a + b) as i64"), "(as (+ a b) I64)");
1061    }
1062
1063    // 轻量 fuzz:用确定性 PRNG 生成大量随机/半结构化输入喂给解析器,断言它永远
1064    // 不 panic、不崩溃(返回 Ok 或 Err 都可),也不卡死(B2 的深度守卫保证有界)。
1065    // 在大栈线程上跑,避免深嵌套合法解析在调试构建里耗尽测试线程的 2MB 栈。
1066    #[test]
1067    fn parser_never_panics_on_random_input() {
1068        run_with_big_stack(|| {
1069            const FRAGMENTS: &[&str] = &[
1070                "fn", "let", "if", "else", "for", "in", "while", "return", "struct", "impl", "pub", "(", ")", "{", "}", "[", "]", "<", ">", "+", "-", "*", "/", "%", "=", "==", "&&", "||", "..", "..=", "as", "i32",
1071                "u64", "f64", ".", ",", ";", ":", "::", "x", "0", "1", "255i8", "0xFF", "\"s\"", "true", "null", "|a|", "->",
1072            ];
1073            // xorshift64* 确定性 PRNG
1074            let mut state: u64 = 0x9E3779B97F4A7C15;
1075            let mut next = || {
1076                state ^= state >> 12;
1077                state ^= state << 25;
1078                state ^= state >> 27;
1079                state = state.wrapping_mul(0x2545F4914F6CDD1D);
1080                state
1081            };
1082
1083            for _ in 0..4000 {
1084                let mut code = String::new();
1085                let tokens = (next() % 40) as usize;
1086                for _ in 0..tokens {
1087                    code.push_str(FRAGMENTS[(next() as usize) % FRAGMENTS.len()]);
1088                    if next() % 2 == 0 {
1089                        code.push(' ');
1090                    }
1091                }
1092                // 解析全程不应 panic;parse_all 返回 Ok/Err 均可接受。
1093                let result = std::panic::catch_unwind(|| {
1094                    let mut parser = Parser::new(code.clone().into_bytes());
1095                    let mut count = 0;
1096                    loop {
1097                        match parser.stmt(false) {
1098                            Ok(_) => {
1099                                count += 1;
1100                                if parser.is_eof() || count > 1000 {
1101                                    break;
1102                                }
1103                            }
1104                            Err(_) => break,
1105                        }
1106                    }
1107                });
1108                assert!(result.is_ok(), "parser panicked on input: {:?}", code);
1109            }
1110        });
1111    }
1112
1113    #[test]
1114    fn allows_local_name_to_shadow_prior_function() {
1115        parse_all(
1116            r#"
1117            fn chunk_id(x, y) {
1118                x + y
1119            }
1120
1121            fn open() {
1122                let chunk_id = 1;
1123                chunk_id
1124            }
1125            "#,
1126        )
1127        .unwrap();
1128    }
1129
1130    #[test]
1131    fn rejects_duplicate_function_args() {
1132        let err = parse_all("fn open(value, value) { value }").unwrap_err();
1133        assert!(err.to_string().contains("符号 value 已经声明"));
1134    }
1135
1136    #[test]
1137    fn rejects_duplicate_local_let_names() {
1138        let err = parse_all(
1139            r#"
1140            fn open() {
1141                let value = 1;
1142                let value = 2;
1143                value
1144            }
1145            "#,
1146        )
1147        .unwrap_err();
1148        assert!(err.to_string().contains("符号 value 已经声明"));
1149    }
1150
1151    #[test]
1152    fn allows_same_method_name_in_different_impl_blocks() {
1153        parse_all(
1154            r#"
1155            struct A {}
1156            struct B {}
1157
1158            impl A {
1159                fn zero() { 0 }
1160            }
1161
1162            impl B {
1163                fn zero() { 0 }
1164            }
1165            "#,
1166        )
1167        .unwrap();
1168    }
1169
1170    #[test]
1171    fn rejects_nested_fn_inside_function_body() {
1172        let err = parse_all("fn outer() { fn inner() { 1 } }").unwrap_err();
1173        assert!(err.to_string().contains("函数体内不能定义"), "got: {err}");
1174    }
1175
1176    #[test]
1177    fn rejects_nested_struct_inside_function_body() {
1178        let err = parse_all("fn outer() { struct S { x: i32 } S{x: 1} }").unwrap_err();
1179        assert!(err.to_string().contains("函数体内不能定义"), "got: {err}");
1180    }
1181
1182    #[test]
1183    fn rejects_nested_const_inside_function_body() {
1184        let err = parse_all("fn outer() { const K = 1 } K").unwrap_err();
1185        assert!(err.to_string().contains("函数体内不能定义"), "got: {err}");
1186    }
1187
1188    /// 修复回归:`r#` / `r####` 后续 EOF 不再越界 panic,只返回 Err。
1189    /// 修复前会在 `text()` 收集 `#` 前缀时直接 `self.buf[self.pos]` 越界。
1190    #[test]
1191    fn raw_string_with_only_hashes_does_not_panic_at_eof() {
1192        for input in [b"r#" as &[u8], b"r##", b"r###", b"r########", b"r#\"", b"r#\"unterminated"] {
1193            let mut p = Parser::new(input.to_vec());
1194            // 不应 panic;Ok 或 Err 均可接受。
1195            let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| p.text()));
1196            assert!(result.is_ok(), "raw-string parser panicked on input {:?}", input);
1197        }
1198    }
1199
1200    #[test]
1201    fn raw_string_unterminated_returns_error_not_panic() {
1202        // `r#"abc` 缺闭合 → 应当返回 Err 而不是 panic。
1203        let mut p = Parser::new(b"r#\"abc".to_vec());
1204        let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| p.text()));
1205        assert!(result.is_ok(), "raw-string unterminated input should not panic");
1206        let err = result.unwrap().expect_err("unterminated raw string should error");
1207        assert!(err.to_string().contains("未关闭") || err.to_string().contains("unclosed"), "got: {err}");
1208    }
1209
1210    #[test]
1211    fn raw_string_simple_still_parses() {
1212        // 保证正常路径没被破坏:`r"abc"` / `r#"a"#` / `r##"b"##` 都能解析。
1213        let mut p = Parser::new(b"r\"abc\"".to_vec());
1214        assert_eq!(p.text().unwrap().as_str(), "abc");
1215        let mut p = Parser::new(b"r#\"a\"#".to_vec());
1216        assert_eq!(p.text().unwrap().as_str(), "a");
1217        let mut p = Parser::new(b"r##\"b\"##".to_vec());
1218        assert_eq!(p.text().unwrap().as_str(), "b");
1219    }
1220
1221    #[test]
1222    fn hex_escape_at_end_of_string_preserves_byte() {
1223        let mut p = Parser::new(br#""abc\x41""#.to_vec());
1224        let s = p.string().unwrap();
1225        assert_eq!(s.as_str(), "abcA");
1226    }
1227
1228    #[test]
1229    fn hex_escape_truncated_reports_clear_error() {
1230        let mut p = Parser::new(br#""abc\x""#.to_vec());
1231        let err = p.string().unwrap_err();
1232        assert!(err.to_string().contains("\\x"), "got: {err}");
1233    }
1234
1235    #[test]
1236    fn hex_escape_non_hex_char_reports_clear_error() {
1237        let mut p = Parser::new(br#""abc\xZZ""#.to_vec());
1238        let err = p.string().unwrap_err();
1239        assert!(err.to_string().contains("\\x"), "got: {err}");
1240    }
1241
1242    #[test]
1243    fn else_with_invalid_body_reports_error() {
1244        // 让 block() 在 else 后失败:解析到 '}' 紧跟一个无闭的 '{' 触发 "not code block"
1245        let err = parse_all("fn f() { if true { 1 } else }").unwrap_err();
1246        let msg = err.to_string();
1247        assert!(msg.contains("not code block") || msg.contains("未结束的"), "got: {msg}");
1248    }
1249
1250    #[test]
1251    fn float_literal_with_int_suffix_out_of_range_errors() {
1252        let mut p = Parser::new(b"1e30u8".to_vec());
1253        let err = p.number().unwrap_err();
1254        assert!(err.to_string().contains("超出"), "got: {err}");
1255    }
1256
1257    #[test]
1258    fn float_literal_with_int_suffix_fractional_errors() {
1259        let mut p = Parser::new(b"1.5i32".to_vec());
1260        let err = p.number().unwrap_err();
1261        assert!(err.to_string().contains("超出"), "got: {err}");
1262    }
1263
1264    #[test]
1265    fn float_literal_with_float_suffix_accepts_fractional() {
1266        let mut p = Parser::new(b"1e-3f32".to_vec());
1267        assert!(matches!(p.number().unwrap(), Dynamic::F32(v) if (v - 1e-3).abs() < 1e-8));
1268    }
1269
1270    #[test]
1271    fn allows_closure_inside_function_body() {
1272        parse_all("fn outer() { let f = |x: i32| { x + 1 }; f(1) }").unwrap();
1273    }
1274
1275    /// 修复 Bug 4 回归测试:Unicode 首字符的 ident 在 dict 简写里也能识别。
1276    /// 修复前 `is_shorthand_field_name` 只看首字节是否为 ASCII 字母,
1277    /// 中文 key 用 `{ 中文: 1 }` 形式能 dict 化(因为有 `:` 而非 shorthand),
1278    /// 但 `{ 中文key }` shorthand 会被错误识别。
1279    #[test]
1280    fn dict_shorthand_accepts_unicode_first_char() {
1281        // 简写形式:`{ 中文key }` 必须解析成 `{ "中文key": "中文key" }`,而不是当成块。
1282        let stmts = parse_all("fn f() { let d = { 中文key }; d }").expect("unicode shorthand should parse");
1283        assert_eq!(stmts.len(), 1);
1284    }
1285
1286    /// 修复 spans 累积回归测试:stmt 内部 `?` 提前返回时必须清理 spans 栈。
1287    /// 修复前:`spans` 是手动 push/pop,任何 `?` 冒泡都漏 pop,跨 stmt
1288    /// 反复调用会让 spans 栈深度单调增长。该 bug 在 LSP/multi-error 报告
1289    /// 或在 stmt 自己直接递归调用 `Parser::stmt` 的工具场景下尤其敏感。
1290    #[test]
1291    fn stmt_spans_cleaned_up_after_partial_failure() {
1292        let mut p = Parser::new(b"fn f() { 1".to_vec());
1293        // 第一个 stmt 失败(缺 `}`)。spans 应当被 RAII 守卫清空。
1294        let _ = p.stmt(false).expect_err("first stmt should fail (unclosed brace)");
1295        assert!(p.spans.is_empty(), "第一个 stmt 失败后 spans 应被清空。got: {:?}", p.spans);
1296
1297        // 模拟"忽略第一个错误继续解析" — 反复失败 N 次,spans 应保持空。
1298        for _ in 0..5 {
1299            let _ = p.stmt(false);
1300            assert!(p.spans.is_empty(), "spans 应保持空(没有累积)。got: {:?}", p.spans);
1301        }
1302    }
1303
1304    #[test]
1305    fn rejects_const_inside_impl_body() {
1306        let err = parse_all("struct S {}\nimpl S { const K = 1 }").unwrap_err();
1307        let msg = err.to_string();
1308        assert!(msg.contains("impl 体内不能定义") && msg.contains("const"), "got: {msg}");
1309    }
1310
1311    #[test]
1312    fn allows_fn_inside_impl_body() {
1313        parse_all("struct S {}\nimpl S { pub fn m(self: S) { 1 } }").unwrap();
1314    }
1315
1316    /// 修复 Bug 3 回归测试:`take` 在 EOF 处不应报"实际字符 `\0`",
1317    /// 而应报"已到文件末尾"。
1318    #[test]
1319    fn take_at_eof_reports_clean_eof_message() {
1320        let mut p = Parser::new(b"fn f(".to_vec());
1321        // 把 pos 推到 EOF
1322        p.whitespace().unwrap();
1323        while p.current_pos() < p.buf.len() {
1324            // consume any leftover
1325            p.whitespace().unwrap();
1326            break;
1327        }
1328        // 直接到末尾:`fn f(` 解析到 `(` 之后,`f` 后续需要 args,会调用 take 期望 `)`,但当前是 EOF。
1329        let mut p = Parser::new(b"fn f(".to_vec());
1330        // 跳到末尾直接调用 take。
1331        p.pos = p.buf.len();
1332        let err = p.take(b')').expect_err("take at EOF should error");
1333        let msg = err.downcast_ref::<crate::ParserErr>().map(|e| e.message().to_string()).unwrap_or_else(|| format!("{err:#}"));
1334        assert!(msg.contains("已到文件末尾") || msg.contains("末尾"), "expected EOF message, got: {msg}");
1335        assert!(!msg.contains(''), "should not contain NUL char, got: {msg}");
1336    }
1337
1338    #[test]
1339    fn parser_err_carries_span() {
1340        // 用 fn 重复声明触发 DuplicateSymbol,ParserErr span 应当指向重复位置。
1341        let src = "fn f() {}\nfn f() {}\n";
1342        let err = parse_all(src).unwrap_err();
1343        eprintln!("err display: {err}");
1344        let downcast = err.downcast_ref::<ParserErr>().expect("ParserErr");
1345        eprintln!("message: {}", downcast.message());
1346        eprintln!("span: {:?}", downcast.span());
1347        assert!(downcast.message().contains("f"));
1348        // span 应当在文件范围内
1349        assert!(downcast.span().start < src.len());
1350    }
1351
1352    #[test]
1353    fn block_as_let_value_is_expression() {
1354        parse_all("pub fn f() { let x = { let y = 1; y + 1 }; x }").unwrap();
1355    }
1356
1357    #[test]
1358    fn dict_still_takes_priority_over_block() {
1359        // dict 仍是 dict,不能误判为 block
1360        parse_all("pub fn f() { let d = { key: 1 }; d }").unwrap();
1361    }
1362
1363    #[test]
1364    fn list_pattern_with_rest_parses() {
1365        parse_all("pub fn f(items) { let [first, ..rest] = items; first }").unwrap();
1366    }
1367
1368    #[test]
1369    fn list_pattern_with_only_rest_parses() {
1370        parse_all("pub fn f(items) { let [..all] = items; all }").unwrap();
1371    }
1372
1373    #[test]
1374    fn take_error_carries_precise_pos() {
1375        // take 失败时,SpannedParseError.pos 应该指向缺失字符的位置,
1376        // 而不是 parse_code 默认的 parser.current_pos。
1377        use crate::SpannedParseError;
1378        let mut p = Parser::new(b"ab".to_vec());
1379        let pos_before = p.current_pos();
1380        let err = p.take(b'c').unwrap_err();
1381        let spanned = err.downcast_ref::<SpannedParseError>().expect("take should wrap in SpannedParseError");
1382        // take 在 pos_before 处失败,期望 pos == pos_before(0)
1383        assert_eq!(spanned.pos, pos_before);
1384    }
1385
1386    #[test]
1387    fn parses_scientific_float_suffixes() {
1388        let mut parser = Parser::new(b"1.7976931348623157e308f64".to_vec());
1389        assert_eq!(parser.number().unwrap(), Dynamic::F64(1.7976931348623157e308));
1390
1391        let mut parser = Parser::new(b"1e-3f32".to_vec());
1392        assert_eq!(parser.number().unwrap(), Dynamic::F32(1e-3f32));
1393    }
1394
1395    #[test]
1396    fn parses_immediate_closure_call() {
1397        let mut parser = Parser::new(b"|| { 1i32 }()".to_vec());
1398        let expr = parser.get_expr().unwrap();
1399        let ExprKind::Call { obj, params } = expr.kind else {
1400            panic!("expected closure call, got {expr:?}");
1401        };
1402        assert!(params.is_empty());
1403        let ExprKind::Closure { args, .. } = obj.kind else {
1404            panic!("expected closure callee, got {obj:?}");
1405        };
1406        assert!(args.is_empty());
1407    }
1408
1409    #[test]
1410    fn parses_empty_tuple_expression() {
1411        let mut parser = Parser::new(b"()".to_vec());
1412        let expr = parser.get_expr().unwrap();
1413        let ExprKind::Tuple(items) = expr.kind else {
1414            panic!("expected empty tuple, got {expr:?}");
1415        };
1416        assert!(items.is_empty());
1417    }
1418
1419    #[test]
1420    fn parses_explicit_generic_function_call() {
1421        let mut parser = Parser::new(b"value::<4>()".to_vec());
1422        let expr = parser.get_expr().unwrap();
1423        let ExprKind::Call { obj, params } = expr.kind else {
1424            panic!("expected function call, got {expr:?}");
1425        };
1426        assert!(params.is_empty());
1427        let ExprKind::Generic { obj, params } = obj.kind else {
1428            panic!("expected generic callee, got {obj:?}");
1429        };
1430        assert!(matches!(obj.kind, ExprKind::Ident(name) if name.as_str() == "value"));
1431        assert!(matches!(params.as_slice(), [Type::ConstInt(4)]));
1432    }
1433
1434    #[test]
1435    fn parses_import_top_level_declaration() {
1436        // 顶层 import 声明:`import "module";` 和 `import "module", "path";`。
1437        let stmts = parse_all(r#"import "foo";"#).expect("parse import decl");
1438        assert_eq!(stmts.len(), 1);
1439        let StmtKind::Import { module, path, is_pub } = &stmts[0].kind else {
1440            panic!("expected StmtKind::Import, got {:?}", stmts[0].kind);
1441        };
1442        assert_eq!(module.as_str(), "foo");
1443        assert_eq!(path.as_str(), "foo.zs", "省略路径时默认 <module>.zs");
1444        assert!(!*is_pub);
1445
1446        let stmts = parse_all(r#"import "foo", "bar.zs";"#).expect("parse import decl with path");
1447        let StmtKind::Import { module, path, .. } = &stmts[0].kind else {
1448            panic!("expected StmtKind::Import, got {:?}", stmts[0].kind);
1449        };
1450        assert_eq!(module.as_str(), "foo");
1451        assert_eq!(path.as_str(), "bar.zs");
1452
1453        let stmts = parse_all(r#"pub import "foo";"#).expect("parse pub import");
1454        let StmtKind::Import { module, is_pub, .. } = &stmts[0].kind else {
1455            panic!("expected StmtKind::Import, got {:?}", stmts[0].kind);
1456        };
1457        assert_eq!(module.as_str(), "foo");
1458        assert!(*is_pub);
1459    }
1460
1461    #[test]
1462    fn import_call_form_is_still_recognized_as_expression() {
1463        // 兼容旧 `import("name", "path");` 函数调用形式 —— 仍要能解析
1464        // 成 `Expr(Call(import, ...))`,不应当成 import 顶层声明。
1465        // 因为 `import` 后面紧跟 `(`(不是空白+字符串),peek 走 fall-through。
1466        let stmts = parse_all(r#"import("foo", "foo.zs");"#).expect("parse import call");
1467        assert_eq!(stmts.len(), 1);
1468        let StmtKind::Expr(expr, _) = &stmts[0].kind else {
1469            panic!("expected StmtKind::Expr, got {:?}", stmts[0].kind);
1470        };
1471        let ExprKind::Call { obj, params } = &expr.kind else {
1472            panic!("expected ExprKind::Call, got {expr:?}");
1473        };
1474        let ExprKind::Ident(name) = &obj.kind else {
1475            panic!("expected ident callee, got {:?}", obj.kind);
1476        };
1477        assert_eq!(name.as_str(), "import");
1478        assert_eq!(params.len(), 2);
1479    }
1480
1481    #[test]
1482    fn parses_bigfloat_cmp_context_segment() {
1483        let code = r#"
1484            struct BigFloat<N> { data: [u32; N], exp: i32, sign: bool }
1485
1486            impl BigFloat<N> {
1487                fn abs_cmp(self: BigFloat<N>, rhs: BigFloat<N>) {
1488                    let self_high = self.exp + ((N - 1) as i32);
1489                    let rhs_high = rhs.exp + ((N - 1) as i32);
1490                    let high = if self_high >= rhs_high { self_high } else { rhs_high };
1491                    let low = if self.exp <= rhs.exp { self.exp } else { rhs.exp };
1492                    let result = 0i32;
1493                    let power = high;
1494
1495                    while power >= low && result == 0i32 {
1496                        let a_idx = power - self.exp;
1497                        let b_idx = power - rhs.exp;
1498                        let a_limb = 0u32;
1499                        let b_limb = 0u32;
1500
1501                        if a_idx >= 0i32 && a_idx < (N as i32) {
1502                            a_limb = self.data[a_idx as u32];
1503                        }
1504                        if b_idx >= 0i32 && b_idx < (N as i32) {
1505                            b_limb = rhs.data[b_idx as u32];
1506                        }
1507
1508                        if a_limb > b_limb {
1509                            result = 1i32;
1510                        } else if a_limb < b_limb {
1511                            result = -1i32;
1512                        }
1513
1514                        power -= 1i32;
1515                    }
1516
1517                    result
1518                }
1519
1520                pub fn cmp(self: BigFloat<N>, rhs: BigFloat<N>) {
1521                    if self.is_zero() && rhs.is_zero() {
1522                        0i32
1523                    } else if self.sign != rhs.sign {
1524                        if self.sign { -1i32 } else { 1i32 }
1525                    } else {
1526                        let cmp = self.abs_cmp(rhs);
1527                        if self.sign { -cmp } else { cmp }
1528                    }
1529                }
1530            }
1531            "#;
1532        parse_all(code).unwrap();
1533    }
1534
1535    #[test]
1536    fn parses_bigfloat_file() {
1537        let code = include_str!("../../zusts/bigfloat.zs");
1538        parse_all(code).unwrap();
1539    }
1540}