Skip to main content

parser/
stmt.rs

1use crate::try_parse;
2use dynamic::{Dynamic, Type};
3
4use super::{Expr, Parser, Pattern, Span, expr::ExprKind, pattern::PatternKind};
5use anyhow::{Result, anyhow};
6use smol_str::SmolStr;
7
8/// 把 pattern 引入的所有变量绑定生成出来,追加到 `out`。
9/// `access` 是该 pattern 整体对应的访问表达式(如 `__m_scrut` 或 `__m_scrut.field`)。
10fn collect_bindings(pat: &Pattern, access: &Expr, out: &mut Vec<Stmt>, span: Span) {
11    use crate::expr::BinaryOp;
12    let mk_let_ident = |name: SmolStr, value: Expr, span: Span| {
13        let p = Pattern::new(PatternKind::Ident { name, ty: Type::Any }, span);
14        let value_stmt = Stmt::new(StmtKind::Expr(value, true), span);
15        Stmt::new(StmtKind::Let { pat: p, value: Box::new(value_stmt) }, span)
16    };
17    let mk_bin = |left: Expr, op: BinaryOp, right: Expr, span: Span| Expr::new(ExprKind::Binary { left: Box::new(left), op, right: Box::new(right) }, span);
18    let mk_idx_int = |obj: Expr, i: i32, span: Span| mk_bin(obj, BinaryOp::Idx, Expr::new(ExprKind::Value(Dynamic::I32(i)), span), span);
19    let mk_field = |obj: Expr, name: SmolStr, span: Span| mk_bin(obj, BinaryOp::Idx, Expr::new(ExprKind::Value(Dynamic::String(name)), span), span);
20
21    match &pat.kind {
22        PatternKind::Ident { name, .. } => {
23            out.push(mk_let_ident(name.clone(), access.clone(), span));
24        }
25        PatternKind::Tuple(items) => {
26            for (i, p) in items.iter().enumerate() {
27                let elem = mk_idx_int(access.clone(), i as i32, span);
28                collect_bindings(p, &elem, out, span);
29            }
30        }
31        PatternKind::List { elems, has_rest } => {
32            let prefix = if *has_rest { elems.len() - 1 } else { elems.len() };
33            for (i, p) in elems.iter().take(prefix).enumerate() {
34                let elem = mk_idx_int(access.clone(), i as i32, span);
35                collect_bindings(p, &elem, out, span);
36            }
37            if *has_rest {
38                if let PatternKind::Ident { name, .. } = &elems.last().unwrap().kind {
39                    // 切片: access[prefix..];用 `ExprKind::Range` 而不是 `Binary{RangeOpen}`,
40                    // 与 parser 产物一致,这样下游 type infer / 优化都走同一条路径。
41                    let from = Expr::new(ExprKind::Value((prefix as u32).into()), span);
42                    let range = Expr::new(ExprKind::Range { start: Box::new(from), stop: Box::new(Expr::new(ExprKind::Value(Dynamic::Null), span)), inclusive: false }, span);
43                    let slice = Expr::new(ExprKind::Binary { left: Box::new(access.clone()), op: BinaryOp::Idx, right: Box::new(range) }, span);
44                    out.push(mk_let_ident(name.clone(), slice, span));
45                }
46            }
47        }
48        PatternKind::Struct { fields, .. } => {
49            for (fname, sub) in fields {
50                let field_access = mk_field(access.clone(), fname.clone(), span);
51                match sub {
52                    None => {
53                        // 简写 `field` —— 绑定同名变量
54                        out.push(mk_let_ident(fname.clone(), field_access, span));
55                    }
56                    Some(sub_pat) => {
57                        collect_bindings(sub_pat, &field_access, out, span);
58                    }
59                }
60            }
61        }
62        // 其它(Wildcard / Literal / Var / Member / Idx)在 match 上下文中不产生绑定
63        _ => {}
64    }
65}
66
67#[derive(Debug, Clone)]
68pub struct Stmt {
69    pub kind: StmtKind,
70    pub span: Span,
71}
72
73#[derive(Debug, Clone)]
74pub enum StmtKind {
75    Let { pat: Pattern, value: Box<Stmt> },
76    Expr(Expr, bool),
77    Block(Vec<Stmt>),
78    Break,
79    Continue,
80    Return(Option<Expr>),
81    While { cond: Expr, body: Box<Stmt> },
82    Loop(Box<Stmt>),
83    For { pat: Pattern, range: Expr, body: Box<Stmt> },
84    Fn { name: SmolStr, generic_params: Vec<Type>, args: Vec<(SmolStr, Type)>, body: Box<Stmt>, is_pub: bool },
85    Struct { name: SmolStr, def: Type, is_pub: bool },
86    Impl { target: Type, body: Box<Stmt> },
87    If { cond: Expr, then_body: Box<Stmt>, else_body: Option<Box<Stmt>> },
88    Static { name: SmolStr, ty: Type, value: Option<Expr>, is_pub: bool },
89    Const { name: SmolStr, ty: Type, value: Expr, is_pub: bool },
90}
91
92impl Stmt {
93    pub fn new(kind: StmtKind, span: Span) -> Self {
94        Self { kind, span }
95    }
96
97    pub fn expr(&self) -> Option<Expr> {
98        if let StmtKind::Expr(expr, _) = &self.kind { Some(expr.clone()) } else { None }
99    }
100
101    pub fn is_return(&self) -> bool {
102        matches!(self.kind, StmtKind::Return(_))
103    }
104
105    pub fn last_return(&mut self) -> bool {
106        match &mut self.kind {
107            StmtKind::Block(stmts) => stmts.last_mut().map(|stmt| stmt.last_return()).unwrap_or(false),
108            StmtKind::If { then_body, else_body, .. } => {
109                let then_returns = then_body.last_return();
110                let else_returns = else_body.as_mut().map(|body| body.last_return()).unwrap_or(false);
111                then_returns && else_returns
112            }
113            StmtKind::Expr(e, close) => {
114                if !*close {
115                    let span = e.span;
116                    *self = Self::new(StmtKind::Return(Some(std::mem::take(e))), span);
117                    true
118                } else {
119                    false
120                }
121            }
122            StmtKind::Return(_) => true,
123            _ => false,
124        }
125    }
126
127    pub fn get_type(&self) -> Option<Type> {
128        match &self.kind {
129            StmtKind::Expr(expr, _) => Some(expr.get_type()),
130            StmtKind::Block(stmts) => stmts.last().and_then(|stmt| stmt.get_type()),
131            StmtKind::If { then_body, .. } => then_body.get_type(),
132            _ => None,
133        }
134    }
135
136    fn get_assign(idx: u32, expr: Expr) -> Self {
137        let span = expr.span;
138        Self::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(Expr::new(ExprKind::Var(idx), span)), op: crate::BinaryOp::Assign, right: Box::new(expr) }, span), true), span)
139    }
140
141    fn get_idx_assign(pat: Expr, idx: usize, expr: Expr) -> Self {
142        let span = pat.span.merge(expr.span);
143        let right = Expr::new(ExprKind::Binary { left: Box::new(expr), op: crate::BinaryOp::Idx, right: Box::new(Expr::new(ExprKind::Value((idx as u32).into()), span)) }, span);
144        Self::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(pat), op: crate::BinaryOp::Assign, right: Box::new(right) }, span), true), span)
145    }
146
147    fn get_assign_expr(pat: Expr, expr: Expr) -> Self {
148        let span = pat.span.merge(expr.span);
149        Self::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(pat), op: crate::BinaryOp::Assign, right: Box::new(expr) }, span), true), span)
150    }
151
152    fn get_pop_assign(pat: Expr, expr: Expr) -> Self {
153        let span = pat.span.merge(expr.span);
154        let pop_name = Expr::new(ExprKind::Value(Dynamic::from("pop")), span);
155        let pop_method = Expr::new(ExprKind::Binary { left: Box::new(expr), op: crate::BinaryOp::Idx, right: Box::new(pop_name) }, span);
156        let pop_call = Expr::new(ExprKind::Call { obj: Box::new(pop_method), params: Vec::new() }, span);
157        Self::get_assign_expr(pat, pop_call)
158    }
159
160    pub fn bind_pattern(&mut self, pat: Pattern) -> Result<()> {
161        if let Some(expr) = self.expr() {
162            let stmt = match pat.kind {
163                PatternKind::Var { idx, ty } => {
164                    if expr.get_type() != ty {
165                        Self::get_assign(idx, Expr::new(ExprKind::Typed { value: Box::new(expr), ty }, pat.span))
166                    } else {
167                        Self::get_assign(idx, expr)
168                    }
169                }
170                PatternKind::Tuple(list) => {
171                    let mut stmts = Vec::new();
172                    for p in list.into_iter().rev() {
173                        match p.expr() {
174                            Ok(p) => stmts.push(Self::get_pop_assign(p, expr.clone())),
175                            Err(e) => return Err(e),
176                        }
177                    }
178                    Self::new(StmtKind::Block(stmts), self.span)
179                }
180                PatternKind::List { elems, has_rest } => {
181                    let mut stmts = Vec::new();
182                    let prefix_count = if has_rest { elems.len() - 1 } else { elems.len() };
183                    if has_rest {
184                        for (idx, p) in elems.iter().take(prefix_count).enumerate() {
185                            match p.expr() {
186                                Ok(p) => stmts.push(Self::get_idx_assign(p, idx, expr.clone())),
187                                Err(e) => return Err(e),
188                            }
189                        }
190                    } else {
191                        for p in elems.iter().rev() {
192                            match p.expr() {
193                                Ok(p) => stmts.push(Self::get_pop_assign(p, expr.clone())),
194                                Err(e) => return Err(e),
195                            }
196                        }
197                    }
198                    if has_rest {
199                        // 最后一个元素是 `..rest`,把它绑定为 expr[prefix_count..] 的切片。
200                        let rest_pat = elems.last().unwrap();
201                        let rest_expr = match &rest_pat.kind {
202                            PatternKind::Ident { name, .. } => Expr::new(ExprKind::Ident(name.clone()), rest_pat.span),
203                            PatternKind::Var { idx, .. } => Expr::new(ExprKind::Var(*idx), rest_pat.span),
204                            _ => return Err(anyhow!("..rest 后的模式必须是标识符")),
205                        };
206                        let from = Expr::new(ExprKind::Value((prefix_count as u32).into()), rest_pat.span);
207                        // 用 `ExprKind::Range` 与 parser 产物对齐,确保下游 type infer 走切片分支。
208                        let range = Expr::new(ExprKind::Range { start: Box::new(from), stop: Box::new(Expr::new(ExprKind::Value(Dynamic::Null), rest_pat.span)), inclusive: false }, rest_pat.span);
209                        let slice_idx = Expr::new(ExprKind::Binary { left: Box::new(expr.clone()), op: crate::BinaryOp::Idx, right: Box::new(range) }, rest_pat.span);
210                        stmts.push(Self::get_assign_expr(rest_expr, slice_idx));
211                    }
212                    Self::new(StmtKind::Block(stmts), self.span)
213                }
214                p => return Err(anyhow!("不支持的模式绑定: {:?}", p)),
215            };
216            let _ = std::mem::replace(self, stmt);
217        } else {
218            match &mut self.kind {
219                StmtKind::Block(stmts) => {
220                    if let Some(stmt) = stmts.last_mut() {
221                        stmt.bind_pattern(pat)?;
222                    }
223                }
224                StmtKind::If { then_body, else_body, .. } => {
225                    then_body.bind_pattern(pat.clone())?;
226                    if let Some(e) = else_body {
227                        e.bind_pattern(pat)?;
228                    }
229                }
230                _ => {}
231            }
232        }
233        Ok(())
234    }
235}
236
237use std::fmt;
238impl fmt::Display for Stmt {
239    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240        match &self.kind {
241            StmtKind::Let { pat, value } => writeln!(f, "let {:?} = {}", pat, value)?,
242            StmtKind::Block(stmts) => stmts.iter().for_each(|s| {
243                let _ = write!(f, "{}", s);
244            }),
245            StmtKind::Expr(expr, close) => writeln!(f, "{:?}[{}]", expr, close)?,
246            StmtKind::Break => writeln!(f, "break")?,
247            StmtKind::Continue => writeln!(f, "continue")?,
248            StmtKind::Return(r) => writeln!(f, "return {:?}", r)?,
249            StmtKind::While { cond, body } => write!(f, "while {:?}\n{}", cond, body)?,
250            StmtKind::Loop(body) => write!(f, "loop\n{}", body)?,
251            StmtKind::For { pat, range, body } => writeln!(f, "for {:?} in {:?} \n{}", pat, range, body)?,
252            StmtKind::If { cond, then_body, else_body } => {
253                write!(f, "if {:?}\nthen-> {}\n", cond, then_body)?;
254                if let Some(e) = else_body {
255                    writeln!(f, "{}", e)?;
256                }
257            }
258            StmtKind::Fn { name, generic_params, args, body, is_pub } => {
259                let generic_suffix = if generic_params.is_empty() { String::new() } else { format!("<{:?}>", generic_params) };
260                if *is_pub {
261                    write!(f, "pub fn {:?}{} {:?}\n", name, generic_suffix, args)?
262                } else {
263                    write!(f, "fn {:?}{} {:?}\n", name, generic_suffix, args)?
264                }
265                write!(f, "{}", body)?;
266            }
267            _ => write!(f, "(todo display: {:?})", self.kind)?,
268        }
269        fmt::Result::Ok(())
270    }
271}
272
273impl Parser {
274    pub fn ident_typed(&mut self) -> Result<(SmolStr, Type)> {
275        let name = self.ident()?;
276        self.whitespace()?;
277        if self.take(b':').is_ok() { Ok((name, self.get_type()?)) } else { Ok((name, Type::Any)) }
278    }
279
280    pub fn ident_generic(&mut self) -> Result<(SmolStr, Vec<Type>)> {
281        self.whitespace()?;
282        let name = self.ident()?;
283        self.whitespace()?;
284        let params = if self.get()? == b'<' {
285            self.pos += 1;
286            crate::parse_list!(self, Vec::new(), b'>', b',', self.get_type_param()?)
287        } else {
288            Vec::new()
289        };
290        Ok((name, params))
291    }
292
293    pub fn block(&mut self) -> Result<Stmt> {
294        self.check_fatal()?;
295        self.whitespace()?;
296        let start = self.current_pos();
297        if self.get()? == b'{' {
298            self.pos += 1;
299            self.enter_depth()?;
300            self.push_decl_scope();
301            let result = (|| -> Result<Stmt> {
302                let body = crate::parse_list!(self, Vec::new(), b'}', 0, self.stmt(false)?);
303                Ok(Stmt::new(StmtKind::Block(body), self.span_from(start)))
304            })();
305            self.pop_decl_scope();
306            self.exit_depth();
307            result
308        } else {
309            Err(anyhow!("not code block"))
310        }
311    }
312
313    pub fn if_block(&mut self) -> Result<Stmt> {
314        let start = self.spans.last().copied().unwrap_or_else(|| self.current_pos());
315        let cond = self.get_expr_without_struct_literal()?;
316        let then_body = Box::new(self.block()?);
317        self.whitespace()?;
318        let else_body = if self.keyword("else").is_ok() {
319            self.whitespace()?;
320            let body = if self.keyword("if").is_ok() { self.if_block()? } else { self.block()? };
321            Some(Box::new(body))
322        } else {
323            None
324        };
325        Ok(Stmt::new(StmtKind::If { cond, then_body, else_body }, Span::new(start, self.current_pos())))
326    }
327
328    /// 解析 `match scrut { pat ("|" pat)* ("if" guard)? => body ","? ... }`,
329    /// desugar 成 `Block + Let + If 链 + 临时变量`,返回顶层 `Block`(再由
330    /// 调用方用 `ExprKind::Stmt` 包成表达式)。
331    pub fn match_block(&mut self, start: usize) -> Result<Stmt> {
332        use crate::expr::{BinaryOp, ExprKind, UnaryOp};
333        use crate::pattern::{Pattern, PatternKind};
334
335        // ---- 一、解析阶段 ----
336        let scrut = self.get_expr_without_struct_literal()?;
337        self.whitespace()?;
338        self.take(b'{').map_err(|_| anyhow!("match 缺少 `{{`"))?;
339
340        // 每个 arm 是 (pats: Vec<Pattern>, guard: Option<Expr>, body: Expr)
341        let mut arms: Vec<(Vec<Pattern>, Option<Expr>, Expr)> = Vec::new();
342        loop {
343            self.whitespace()?;
344            if self.take(b'}').is_ok() {
345                break;
346            }
347            self.push_decl_scope();
348            let arm_res: Result<(Vec<Pattern>, Option<Expr>, Expr)> = (|| {
349                // 一组 pattern(用 `|` 分隔,or-pattern)
350                let mut pats = vec![self.pattern()?];
351                self.whitespace()?;
352                while matches!(self.get(), Ok(b'|')) && !matches!(self.ahead(), Ok(b'|')) {
353                    self.pos += 1;
354                    self.whitespace()?;
355                    pats.push(self.pattern()?);
356                    self.whitespace()?;
357                }
358                // 声明 pattern 引入的变量(对每个 alt 都声明,允许重名 → 由
359                // declare_symbol_in_current_scope 容错;这里我们只用第一个 alt 的 binding)
360                for pat in &pats[..1] {
361                    self.declare_pattern_symbols(pat)?;
362                }
363                // 校验 or-pattern:第二及之后必须是 Literal(MVP 限制)
364                if pats.len() > 1 {
365                    for p in &pats[1..] {
366                        if !matches!(p.kind, PatternKind::Literal(_) | PatternKind::Wildcard) {
367                            return Err(anyhow!("or-pattern 中除第一个外只支持字面量 / 通配模式 (MVP 限制)"));
368                        }
369                    }
370                }
371                // 可选 guard
372                self.whitespace()?;
373                let guard = if self.keyword("if").is_ok() {
374                    self.whitespace()?;
375                    Some(self.get_expr_no_assign()?)
376                } else {
377                    None
378                };
379                // `=>`
380                self.whitespace()?;
381                self.just("=>").map_err(|_| anyhow!("match arm 缺少 `=>`"))?;
382                self.whitespace()?;
383                // 体
384                let body_start = self.current_pos();
385                let body = if self.get()? == b'{' {
386                    let block_stmt = self.block()?;
387                    Expr::new(ExprKind::Stmt(Box::new(block_stmt)), Span::new(body_start, self.current_pos()))
388                } else {
389                    // body 也用 no_assign 防止 `=> body, ...` 中 `,` 后或下一 arm
390                    // 的 `=>` 被错误吞入(同时仍允许 +-*/ 等正常二元)。
391                    self.get_expr_no_assign()?
392                };
393                // 容忍尾随逗号
394                self.whitespace()?;
395                let _ = self.take(b',');
396                Ok((pats, guard, body))
397            })();
398            self.pop_decl_scope();
399            arms.push(arm_res?);
400        }
401        let span = Span::new(start, self.current_pos());
402
403        // ---- 二、声明 match 顶层临时变量 ----
404        // 为避免嵌套 match 重名,加 counter 后缀(简单递增,parser 本地状态)
405        let suffix = self.match_counter;
406        self.match_counter += 1;
407        let scrut_name: SmolStr = format!("__m_scrut_{}", suffix).into();
408        let done_name: SmolStr = format!("__m_done_{}", suffix).into();
409        let out_name: SmolStr = format!("__m_out_{}", suffix).into();
410        self.declare_symbol_in_current_scope(&scrut_name)?;
411        self.declare_symbol_in_current_scope(&done_name)?;
412        self.declare_symbol_in_current_scope(&out_name)?;
413
414        // ---- 三、构建顶层 Block ----
415        let mk_ident = |name: &SmolStr, span: Span| Expr::new(ExprKind::Ident(name.clone()), span);
416        let mk_value = |v: Dynamic, span: Span| Expr::new(ExprKind::Value(v), span);
417        let mk_binary = |left: Expr, op: BinaryOp, right: Expr, span: Span| Expr::new(ExprKind::Binary { left: Box::new(left), op, right: Box::new(right) }, span);
418        let mk_let = |name: SmolStr, value: Expr, span: Span| {
419            let pat = Pattern::new(PatternKind::Ident { name, ty: Type::Any }, span);
420            let value_stmt = Stmt::new(StmtKind::Expr(value, true), span);
421            Stmt::new(StmtKind::Let { pat, value: Box::new(value_stmt) }, span)
422        };
423        let mk_assign_stmt = |name: &SmolStr, value: Expr, span: Span| {
424            let assign = mk_binary(mk_ident(name, span), BinaryOp::Assign, value, span);
425            Stmt::new(StmtKind::Expr(assign, true), span)
426        };
427        let mk_any = |value: Expr, span: Span| Expr::new(ExprKind::Typed { value: Box::new(value), ty: Type::Any }, span);
428
429        let mut stmts = Vec::new();
430        // let __m_scrut = SCRUT;
431        stmts.push(mk_let(scrut_name.clone(), scrut, span));
432        // let __m_done = false;
433        stmts.push(mk_let(done_name.clone(), mk_value(Dynamic::Bool(false), span), span));
434        // let __m_out = null;
435        stmts.push(mk_let(out_name.clone(), mk_value(Dynamic::Null, span), span));
436
437        // 每个 arm 一个 if(顺序构造)
438        for (pats, guard, body) in arms {
439            let arm_span = body.span;
440            let scrut_ident = mk_ident(&scrut_name, arm_span);
441            // test = pat[0].test || pat[1].test || ...
442            let mut test_chain = pats[0].match_test(&scrut_ident);
443            for p in &pats[1..] {
444                let t = p.match_test(&scrut_ident);
445                test_chain = mk_binary(test_chain, BinaryOp::Or, t, arm_span);
446            }
447            // !__m_done && (test_chain)
448            let not_done = Expr::new(ExprKind::Unary { op: UnaryOp::Not, value: Box::new(mk_ident(&done_name, arm_span)) }, arm_span);
449            let outer_cond = mk_binary(not_done, BinaryOp::And, test_chain, arm_span);
450
451            // arm body block:bind + guard + assign + done
452            let mut body_stmts = Vec::new();
453            collect_bindings(&pats[0], &mk_ident(&scrut_name, arm_span), &mut body_stmts, arm_span);
454            // 内层 body:__m_out = BODY; __m_done = true;
455            let inner_stmts = vec![mk_assign_stmt(&out_name, mk_any(body, arm_span), arm_span), mk_assign_stmt(&done_name, mk_value(Dynamic::Bool(true), arm_span), arm_span)];
456            let inner_block = Stmt::new(StmtKind::Block(inner_stmts), arm_span);
457            // 如果有 guard,再裹一层 if;否则直接展开
458            if let Some(g) = guard {
459                body_stmts.push(Stmt::new(StmtKind::If { cond: g, then_body: Box::new(inner_block), else_body: None }, arm_span));
460            } else {
461                body_stmts.push(inner_block);
462            }
463            let then_body = Stmt::new(StmtKind::Block(body_stmts), arm_span);
464            stmts.push(Stmt::new(StmtKind::If { cond: outer_cond, then_body: Box::new(then_body), else_body: None }, arm_span));
465        }
466        // 末尾求值:__m_out
467        stmts.push(Stmt::new(StmtKind::Expr(mk_any(mk_ident(&out_name, span), span), false), span));
468
469        Ok(Stmt::new(StmtKind::Block(stmts), span))
470    }
471
472    pub fn stmt(&mut self, is_pub: bool) -> Result<Stmt> {
473        self.check_fatal()?;
474        self.whitespace()?;
475        self.spans.push(self.pos);
476        let start = self.current_pos();
477        // 函数体内不允许 fn / struct / impl / const / static 顶层声明。
478        // 编译器对这些位置直接 panic,这里前置到 parser,让错误落到用户可见的地方。
479        if self.fn_body_depth > 0 {
480            for kw in &["fn", "struct", "impl", "const", "static"] {
481                if self.keyword(kw).is_ok() {
482                    return Err(anyhow!("函数体内不能定义 {};请移到顶层或改用闭包", kw));
483                }
484            }
485        }
486        // impl body 允许 fn(方法)和 pub fn,但拒绝嵌套 struct / impl / const / static。
487        if self.impl_body_depth > 0 {
488            for kw in &["struct", "impl", "const", "static"] {
489                if self.keyword(kw).is_ok() {
490                    return Err(anyhow!("impl 体内不能定义 {};请移到顶层", kw));
491                }
492            }
493        }
494        let stmt = if self.keyword("let").is_ok() {
495            let pat = self.pattern()?;
496            self.declare_pattern_symbols(&pat)?;
497            self.until(b'=')?;
498            self.whitespace()?;
499            let value = if self.get()? == b'{' {
500                if self.looks_like_dict() {
501                    self.get_expr()?
502                } else {
503                    // 块作为表达式:{ stmts; expr } 的值是最后一条语句的值。
504                    let span = self.current_pos();
505                    let block_stmt = self.block()?;
506                    Expr::new(ExprKind::Stmt(Box::new(block_stmt)), Span::new(span, self.current_pos()))
507                }
508            } else {
509                self.get_expr()?
510            };
511            self.whitespace()?;
512            let close = self.take(b';').is_ok();
513            let stmt = Stmt::new(StmtKind::Expr(value, close), Span::new(start, self.current_pos()));
514            Stmt::new(StmtKind::Let { pat, value: Box::new(stmt) }, Span::new(start, self.current_pos()))
515        } else if self.keyword("break").is_ok() {
516            self.until(b';')?;
517            Stmt::new(StmtKind::Break, Span::new(start, self.current_pos()))
518        } else if self.keyword("continue").is_ok() {
519            self.until(b';')?;
520            Stmt::new(StmtKind::Continue, Span::new(start, self.current_pos()))
521        } else if self.keyword("return").is_ok() {
522            self.whitespace()?;
523            let expr = if matches!(self.get(), Ok(b';' | b'}')) { None } else { Some(self.get_expr()?) };
524            self.whitespace()?;
525            if self.take(b';').is_err() && !matches!(self.get(), Ok(b'}')) {
526                self.until(b';')?;
527            }
528            Stmt::new(StmtKind::Return(expr), Span::new(start, self.current_pos()))
529        } else if self.keyword("if").is_ok() {
530            self.if_block()?
531        } else if self.keyword("loop").is_ok() {
532            Stmt::new(StmtKind::Loop(Box::new(self.block()?)), Span::new(start, self.current_pos()))
533        } else if self.keyword("while").is_ok() {
534            self.whitespace()?;
535            let cond = self.get_expr()?;
536            let body = Box::new(self.block()?);
537            Stmt::new(StmtKind::While { cond, body }, Span::new(start, self.current_pos()))
538        } else if self.keyword("for").is_ok() {
539            self.whitespace()?;
540            let pat = self.pattern()?;
541            self.whitespace()?;
542            self.keyword("in")?;
543            self.whitespace()?;
544            let range = self.get_expr()?;
545            self.push_decl_scope();
546            let result: Result<Stmt> = (|| {
547                self.declare_pattern_symbols(&pat)?;
548                let body = Box::new(self.block()?);
549                Ok(Stmt::new(StmtKind::For { pat, range, body }, Span::new(start, self.current_pos())))
550            })();
551            self.pop_decl_scope();
552            result?
553        } else if self.keyword("fn").is_ok() {
554            self.whitespace()?;
555            let (name, generic_params) = self.ident_generic()?;
556            self.declare_function_name(&name)?;
557            self.until(b'(')?;
558            let args = crate::parse_list!(self, Vec::new(), b')', b',', self.ident_typed()?);
559            let body = Box::new(self.function_body(&args)?);
560            Stmt::new(StmtKind::Fn { name, generic_params, args, body, is_pub }, Span::new(start, self.current_pos()))
561        } else if self.keyword("struct").is_ok() {
562            let (name, params) = self.ident_generic()?;
563            self.declare_symbol(&name)?;
564            if self.until(b'{').is_ok() {
565                let fields = crate::parse_list!(self, Vec::new(), b'}', b',', self.ident_typed()?);
566                if let Some(f) = fields.iter().find(|f| f.1.is_any()) {
567                    return Err(anyhow!("字段 {} 的类型未知", f.0));
568                }
569                Stmt::new(StmtKind::Struct { name, def: Type::Struct { params, fields }, is_pub }, Span::new(start, self.current_pos()))
570            } else {
571                self.until(b';')?;
572                Stmt::new(StmtKind::Struct { name, def: Type::Struct { params, fields: Vec::new() }, is_pub }, Span::new(start, self.current_pos()))
573            }
574        } else if self.keyword("const").is_ok() {
575            self.whitespace()?;
576            let (name, ty) = self.ident_typed()?;
577            self.declare_symbol(&name)?;
578            self.until(b'=')?;
579            let value = self.get_expr()?;
580            self.until(b';')?;
581            Stmt::new(StmtKind::Const { name, ty, value, is_pub }, Span::new(start, self.current_pos()))
582        } else if self.keyword("static").is_ok() {
583            self.whitespace()?;
584            let (name, ty) = self.ident_typed()?;
585            self.declare_symbol(&name)?;
586            self.whitespace()?;
587            if self.take(b'=').is_ok() {
588                let expr = self.get_expr()?;
589                self.until(b';')?;
590                Stmt::new(StmtKind::Static { name, ty, value: Some(expr), is_pub }, Span::new(start, self.current_pos()))
591            } else {
592                self.until(b';')?;
593                Stmt::new(StmtKind::Static { name, ty, value: None, is_pub }, Span::new(start, self.current_pos()))
594            }
595        } else if self.keyword("impl").is_ok() {
596            self.whitespace()?;
597            let target = self.get_type()?;
598            Stmt::new(StmtKind::Impl { target, body: Box::new(self.impl_body()?) }, Span::new(start, self.current_pos()))
599        } else if self.keyword("pub").is_ok() {
600            self.stmt(true)?
601        } else {
602            let expr = if self.get()? == b'{' {
603                if self.looks_like_empty_dict() {
604                    self.dict()?
605                } else if let Ok(block) = try_parse!(self, self.block()) {
606                    let _ = self.spans.pop();
607                    return Ok(block);
608                } else if let Ok(dict) = try_parse!(self, self.dict()) {
609                    dict
610                } else {
611                    let block = self.block()?;
612                    let _ = self.spans.pop();
613                    return Ok(block);
614                }
615            } else {
616                self.get_expr()?
617            };
618            self.whitespace()?;
619            if self.is_eof() {
620                Stmt::new(StmtKind::Expr(expr, false), Span::new(start, self.current_pos()))
621            } else if self.get()? == b';' {
622                self.pos += 1;
623                Stmt::new(StmtKind::Expr(expr, true), Span::new(start, self.current_pos()))
624            } else if self.get()? == b'}' {
625                Stmt::new(StmtKind::Expr(expr, false), Span::new(start, self.current_pos()))
626            } else {
627                return Err(anyhow!("未结束的表达式"));
628            }
629        };
630        let _ = self.spans.pop();
631        Ok(stmt)
632    }
633}