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