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
8fn 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 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 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 _ => {}
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 Import { module: SmolStr, path: SmolStr, is_pub: bool },
90 Const { name: SmolStr, ty: Type, value: Expr, is_pub: bool },
91}
92
93impl Stmt {
94 pub fn new(kind: StmtKind, span: Span) -> Self {
95 Self { kind, span }
96 }
97
98 pub fn expr(&self) -> Option<Expr> {
99 if let StmtKind::Expr(expr, _) = &self.kind { Some(expr.clone()) } else { None }
100 }
101
102 pub fn is_return(&self) -> bool {
103 matches!(self.kind, StmtKind::Return(_))
104 }
105
106 pub fn last_return(&mut self) -> bool {
107 match &mut self.kind {
108 StmtKind::Block(stmts) => stmts.last_mut().map(|stmt| stmt.last_return()).unwrap_or(false),
109 StmtKind::If { then_body, else_body, .. } => {
110 let then_returns = then_body.last_return();
111 let else_returns = else_body.as_mut().map(|body| body.last_return()).unwrap_or(false);
112 then_returns && else_returns
113 }
114 StmtKind::Expr(e, close) => {
115 if !*close {
116 let span = e.span;
117 *self = Self::new(StmtKind::Return(Some(std::mem::take(e))), span);
118 true
119 } else {
120 false
121 }
122 }
123 StmtKind::Return(_) => true,
124 _ => false,
125 }
126 }
127
128 pub fn get_type(&self) -> Option<Type> {
129 match &self.kind {
130 StmtKind::Expr(expr, _) => Some(expr.get_type()),
131 StmtKind::Block(stmts) => stmts.last().and_then(|stmt| stmt.get_type()),
132 StmtKind::If { then_body, .. } => then_body.get_type(),
133 _ => None,
134 }
135 }
136
137 fn get_assign(idx: u32, expr: Expr) -> Self {
138 let span = expr.span;
139 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)
140 }
141
142 fn get_idx_assign(pat: Expr, idx: usize, expr: Expr) -> Self {
143 let span = pat.span.merge(expr.span);
144 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);
145 Self::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(pat), op: crate::BinaryOp::Assign, right: Box::new(right) }, span), true), span)
146 }
147
148 fn get_idx_assign_typed(pat: Expr, idx: usize, expr: Expr, ty: Type) -> Self {
153 let span = pat.span.merge(expr.span);
154 let idx_expr = 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);
155 let right = Expr::new(ExprKind::Typed { value: Box::new(idx_expr), ty }, span);
156 Self::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(pat), op: crate::BinaryOp::Assign, right: Box::new(right) }, span), true), span)
157 }
158
159 fn get_assign_expr(pat: Expr, expr: Expr) -> Self {
160 let span = pat.span.merge(expr.span);
161 Self::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(pat), op: crate::BinaryOp::Assign, right: Box::new(expr) }, span), true), span)
162 }
163
164 fn var_expr_with_ty(pat: &Pattern) -> Option<(Expr, Type)> {
165 if let PatternKind::Var { idx, ty } = &pat.kind
166 && !ty.is_any()
167 {
168 Some((Expr::new(ExprKind::Var(*idx), pat.span), ty.clone()))
169 } else {
170 None
171 }
172 }
173
174 pub fn bind_pattern(&mut self, pat: Pattern) -> Result<()> {
175 if let Some(expr) = self.expr() {
176 let stmt = match pat.kind {
177 PatternKind::Var { idx, ty } => {
178 if expr.get_type() != ty {
179 Self::get_assign(idx, Expr::new(ExprKind::Typed { value: Box::new(expr), ty }, pat.span))
180 } else {
181 Self::get_assign(idx, expr)
182 }
183 }
184 PatternKind::Tuple(list) => {
185 let mut stmts = Vec::new();
186 for (idx, p) in list.into_iter().enumerate() {
187 match Self::var_expr_with_ty(&p) {
188 Some((p, ty)) => stmts.push(Self::get_idx_assign_typed(p, idx, expr.clone(), ty)),
189 None => match p.expr() {
190 Ok(p) => stmts.push(Self::get_idx_assign(p, idx, expr.clone())),
191 Err(e) => return Err(e),
192 },
193 }
194 }
195 Self::new(StmtKind::Block(stmts), self.span)
196 }
197 PatternKind::List { elems, has_rest } => {
198 let mut stmts = Vec::new();
199 let prefix_count = if has_rest { elems.len() - 1 } else { elems.len() };
200 if has_rest {
201 for (idx, p) in elems.iter().take(prefix_count).enumerate() {
202 match Self::var_expr_with_ty(p) {
203 Some((p, ty)) => stmts.push(Self::get_idx_assign_typed(p, idx, expr.clone(), ty)),
204 None => match p.expr() {
205 Ok(p) => stmts.push(Self::get_idx_assign(p, idx, expr.clone())),
206 Err(e) => return Err(e),
207 },
208 }
209 }
210 } else {
211 for (idx, p) in elems.iter().enumerate() {
212 match Self::var_expr_with_ty(p) {
213 Some((p, ty)) => stmts.push(Self::get_idx_assign_typed(p, idx, expr.clone(), ty)),
214 None => match p.expr() {
215 Ok(p) => stmts.push(Self::get_idx_assign(p, idx, expr.clone())),
216 Err(e) => return Err(e),
217 },
218 }
219 }
220 }
221 if has_rest {
222 let rest_pat = elems.last().unwrap();
224 let rest_expr = match &rest_pat.kind {
225 PatternKind::Ident { name, .. } => Expr::new(ExprKind::Ident(name.clone()), rest_pat.span),
226 PatternKind::Var { idx, .. } => Expr::new(ExprKind::Var(*idx), rest_pat.span),
227 _ => return Err(anyhow!("..rest 后的模式必须是标识符")),
228 };
229 let from = Expr::new(ExprKind::Value((prefix_count as u32).into()), rest_pat.span);
230 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);
232 let slice_idx = Expr::new(ExprKind::Binary { left: Box::new(expr.clone()), op: crate::BinaryOp::Idx, right: Box::new(range) }, rest_pat.span);
233 stmts.push(Self::get_assign_expr(rest_expr, slice_idx));
234 }
235 Self::new(StmtKind::Block(stmts), self.span)
236 }
237 p => return Err(anyhow!("不支持的模式绑定: {:?}", p)),
238 };
239 let _ = std::mem::replace(self, stmt);
240 } else {
241 match &mut self.kind {
242 StmtKind::Block(stmts) => {
243 if let Some(stmt) = stmts.last_mut() {
244 stmt.bind_pattern(pat)?;
245 }
246 }
247 StmtKind::If { then_body, else_body, .. } => {
248 then_body.bind_pattern(pat.clone())?;
249 if let Some(e) = else_body {
250 e.bind_pattern(pat)?;
251 }
252 }
253 _ => {}
254 }
255 }
256 Ok(())
257 }
258}
259
260use std::fmt;
261impl fmt::Display for Stmt {
262 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
263 match &self.kind {
264 StmtKind::Let { pat, value } => writeln!(f, "let {:?} = {}", pat, value)?,
265 StmtKind::Block(stmts) => stmts.iter().for_each(|s| {
266 let _ = write!(f, "{}", s);
267 }),
268 StmtKind::Expr(expr, close) => writeln!(f, "{:?}[{}]", expr, close)?,
269 StmtKind::Break => writeln!(f, "break")?,
270 StmtKind::Continue => writeln!(f, "continue")?,
271 StmtKind::Return(r) => writeln!(f, "return {:?}", r)?,
272 StmtKind::While { cond, body } => write!(f, "while {:?}\n{}", cond, body)?,
273 StmtKind::Loop(body) => write!(f, "loop\n{}", body)?,
274 StmtKind::For { pat, range, body } => writeln!(f, "for {:?} in {:?} \n{}", pat, range, body)?,
275 StmtKind::If { cond, then_body, else_body } => {
276 write!(f, "if {:?}\nthen-> {}\n", cond, then_body)?;
277 if let Some(e) = else_body {
278 writeln!(f, "{}", e)?;
279 }
280 }
281 StmtKind::Fn { name, generic_params, args, body, is_pub } => {
282 let generic_suffix = if generic_params.is_empty() { String::new() } else { format!("<{:?}>", generic_params) };
283 if *is_pub {
284 write!(f, "pub fn {:?}{} {:?}\n", name, generic_suffix, args)?
285 } else {
286 write!(f, "fn {:?}{} {:?}\n", name, generic_suffix, args)?
287 }
288 write!(f, "{}", body)?;
289 }
290 StmtKind::Import { module, path, is_pub } => {
291 if *is_pub {
292 writeln!(f, "pub import {:?}, {:?};", module, path)?
293 } else {
294 writeln!(f, "import {:?}, {:?};", module, path)?
295 }
296 }
297 _ => write!(f, "(todo display: {:?})", self.kind)?,
298 }
299 fmt::Result::Ok(())
300 }
301}
302
303impl Parser {
304 pub fn ident_typed(&mut self) -> Result<(SmolStr, Type)> {
305 let name = self.ident()?;
306 self.whitespace()?;
307 if self.take(b':').is_ok() { Ok((name, self.get_type()?)) } else { Ok((name, Type::Any)) }
308 }
309
310 pub fn ident_generic(&mut self) -> Result<(SmolStr, Vec<Type>)> {
311 self.whitespace()?;
312 let name = self.ident()?;
313 self.whitespace()?;
314 let params = if self.get()? == b'<' {
315 self.pos += 1;
316 crate::parse_list!(self, Vec::new(), b'>', b',', self.get_type_param()?)
317 } else {
318 Vec::new()
319 };
320 Ok((name, params))
321 }
322
323 pub fn block(&mut self) -> Result<Stmt> {
324 self.check_fatal()?;
325 self.whitespace()?;
326 let start = self.current_pos();
327 if self.get()? == b'{' {
328 self.pos += 1;
329 self.enter_depth()?;
330 self.push_decl_scope();
331 let result = (|| -> Result<Stmt> {
332 let body = crate::parse_list!(self, Vec::new(), b'}', 0, self.stmt(false)?);
333 Ok(Stmt::new(StmtKind::Block(body), self.span_from(start)))
334 })();
335 self.pop_decl_scope();
336 self.exit_depth();
337 result
338 } else {
339 Err(anyhow!("not code block"))
340 }
341 }
342
343 pub fn if_block(&mut self) -> Result<Stmt> {
344 let start = self.spans.last().copied().unwrap_or_else(|| self.current_pos());
345 let cond = self.get_expr_without_struct_literal()?;
346 let then_body = Box::new(self.block()?);
347 self.whitespace()?;
348 let else_body = if self.keyword("else").is_ok() {
349 self.whitespace()?;
350 let body = if self.keyword("if").is_ok() { self.if_block()? } else { self.block()? };
351 Some(Box::new(body))
352 } else {
353 None
354 };
355 Ok(Stmt::new(StmtKind::If { cond, then_body, else_body }, Span::new(start, self.current_pos())))
356 }
357
358 pub fn match_block(&mut self, start: usize) -> Result<Stmt> {
362 use crate::expr::{BinaryOp, ExprKind, UnaryOp};
363 use crate::pattern::{Pattern, PatternKind};
364
365 let scrut = self.get_expr_without_struct_literal()?;
367 self.whitespace()?;
368 self.take(b'{').map_err(|_| anyhow!("match 缺少 `{{`"))?;
369
370 let mut arms: Vec<(Vec<Pattern>, Option<Expr>, Expr)> = Vec::new();
372 loop {
373 self.whitespace()?;
374 if self.take(b'}').is_ok() {
375 break;
376 }
377 self.push_decl_scope();
378 let arm_res: Result<(Vec<Pattern>, Option<Expr>, Expr)> = (|| {
379 let mut pats = vec![self.pattern()?];
381 self.whitespace()?;
382 while matches!(self.get(), Ok(b'|')) && !matches!(self.ahead(), Ok(b'|')) {
383 self.pos += 1;
384 self.whitespace()?;
385 pats.push(self.pattern()?);
386 self.whitespace()?;
387 }
388 for pat in &pats[..1] {
391 self.declare_pattern_symbols(pat)?;
392 }
393 self.whitespace()?;
399 let guard = if self.keyword("if").is_ok() {
400 self.whitespace()?;
401 Some(self.get_expr_no_assign()?)
402 } else {
403 None
404 };
405 self.whitespace()?;
407 self.just("=>").map_err(|_| anyhow!("match arm 缺少 `=>`"))?;
408 self.whitespace()?;
409 let body_start = self.current_pos();
411 let body = if self.get()? == b'{' {
412 let block_stmt = self.block()?;
413 Expr::new(ExprKind::Stmt(Box::new(block_stmt)), Span::new(body_start, self.current_pos()))
414 } else {
415 self.get_expr_no_assign()?
418 };
419 self.whitespace()?;
421 let _ = self.take(b',');
422 Ok((pats, guard, body))
423 })();
424 self.pop_decl_scope();
425 arms.push(arm_res?);
426 }
427 let span = Span::new(start, self.current_pos());
428
429 let suffix = self.match_counter;
432 self.match_counter += 1;
433 let scrut_name: SmolStr = format!("__m_scrut_{}", suffix).into();
434 let done_name: SmolStr = format!("__m_done_{}", suffix).into();
435 let out_name: SmolStr = format!("__m_out_{}", suffix).into();
436 self.declare_symbol_in_current_scope(&scrut_name)?;
437 self.declare_symbol_in_current_scope(&done_name)?;
438 self.declare_symbol_in_current_scope(&out_name)?;
439
440 let mk_ident = |name: &SmolStr, span: Span| Expr::new(ExprKind::Ident(name.clone()), span);
442 let mk_value = |v: Dynamic, span: Span| Expr::new(ExprKind::Value(v), span);
443 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);
444 let mk_let = |name: SmolStr, value: Expr, span: Span| {
445 let pat = Pattern::new(PatternKind::Ident { name, ty: Type::Any }, span);
446 let value_stmt = Stmt::new(StmtKind::Expr(value, true), span);
447 Stmt::new(StmtKind::Let { pat, value: Box::new(value_stmt) }, span)
448 };
449 let mk_assign_stmt = |name: &SmolStr, value: Expr, span: Span| {
450 let assign = mk_binary(mk_ident(name, span), BinaryOp::Assign, value, span);
451 Stmt::new(StmtKind::Expr(assign, true), span)
452 };
453 let mk_any = |value: Expr, span: Span| Expr::new(ExprKind::Typed { value: Box::new(value), ty: Type::Any }, span);
454
455 let mut stmts = Vec::new();
456 stmts.push(mk_let(scrut_name.clone(), scrut, span));
458 stmts.push(mk_let(done_name.clone(), mk_value(Dynamic::Bool(false), span), span));
460 stmts.push(mk_let(out_name.clone(), mk_value(Dynamic::Null, span), span));
462
463 for (pats, guard, body) in arms {
465 let arm_span = body.span;
466 let scrut_ident = mk_ident(&scrut_name, arm_span);
467 let mut test_chain = pats[0].match_test(&scrut_ident);
469 for p in &pats[1..] {
470 let t = p.match_test(&scrut_ident);
471 test_chain = mk_binary(test_chain, BinaryOp::Or, t, arm_span);
472 }
473 let not_done = Expr::new(ExprKind::Unary { op: UnaryOp::Not, value: Box::new(mk_ident(&done_name, arm_span)) }, arm_span);
475 let outer_cond = mk_binary(not_done, BinaryOp::And, test_chain, arm_span);
476
477 let mut body_stmts = Vec::new();
479 collect_bindings(&pats[0], &mk_ident(&scrut_name, arm_span), &mut body_stmts, arm_span);
480 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)];
482 let inner_block = Stmt::new(StmtKind::Block(inner_stmts), arm_span);
483 if let Some(g) = guard {
485 body_stmts.push(Stmt::new(StmtKind::If { cond: g, then_body: Box::new(inner_block), else_body: None }, arm_span));
486 } else {
487 body_stmts.push(inner_block);
488 }
489 let then_body = Stmt::new(StmtKind::Block(body_stmts), arm_span);
490 stmts.push(Stmt::new(StmtKind::If { cond: outer_cond, then_body: Box::new(then_body), else_body: None }, arm_span));
491 }
492 stmts.push(Stmt::new(StmtKind::Expr(mk_any(mk_ident(&out_name, span), span), false), span));
494
495 Ok(Stmt::new(StmtKind::Block(stmts), span))
496 }
497
498 fn peek_import_top_level(&self) -> bool {
505 let rest = &self.buf[self.pos..];
506 let Some(after_kw) = rest.strip_prefix(b"import") else {
507 return false;
508 };
509 let Some(&first) = after_kw.first() else {
511 return false;
512 };
513 if !first.is_ascii_whitespace() {
514 return false;
515 }
516 let mut after_ws = after_kw.iter().skip_while(|b| b.is_ascii_whitespace());
518 matches!(after_ws.next(), Some(b'"'))
519 }
520
521 pub fn stmt(&mut self, is_pub: bool) -> Result<Stmt> {
522 self.check_fatal()?;
523 self.whitespace()?;
524 let _span_guard = self.with_stmt_span();
528 let start = self.current_pos();
529 if self.scope_depths.fn_body_depth > 0 {
532 for kw in &["fn", "struct", "impl", "const", "static"] {
533 if self.keyword(kw).is_ok() {
534 return Err(anyhow!("函数体内不能定义 {};请移到顶层或改用闭包", kw));
535 }
536 }
537 }
538 if self.scope_depths.impl_body_depth > 0 {
540 for kw in &["struct", "impl", "const", "static"] {
541 if self.keyword(kw).is_ok() {
542 return Err(anyhow!("impl 体内不能定义 {};请移到顶层", kw));
543 }
544 }
545 }
546 let stmt = if self.peek_import_top_level() {
547 if self.scope_depths.fn_body_depth > 0 || self.scope_depths.impl_body_depth > 0 {
554 return Err(anyhow!("import 只能作为顶层声明;请写在模块顶层"));
555 }
556 self.just("import").map_err(|_| anyhow!("expected import"))?;
557 self.whitespace()?;
558 let module = match self.get_expr()?.kind {
559 ExprKind::Value(Dynamic::String(value)) => value,
560 ExprKind::Ident(value) => value,
561 other => return Err(anyhow!("import 模块名必须是字符串或标识符,实际是 {:?}", other)),
562 };
563 self.whitespace()?;
564 let path = if self.take(b',').is_ok() {
565 self.whitespace()?;
566 match self.get_expr()?.kind {
567 ExprKind::Value(Dynamic::String(value)) => value,
568 ExprKind::Ident(value) => value,
569 other => return Err(anyhow!("import 路径必须是字符串或标识符,实际是 {:?}", other)),
570 }
571 } else {
572 format!("{module}.zs").into()
573 };
574 self.until(b';')?;
575 Stmt::new(StmtKind::Import { module, path, is_pub }, Span::new(start, self.current_pos()))
576 } else if self.keyword("let").is_ok() {
577 let pat = self.pattern()?;
578 self.declare_pattern_symbols(&pat)?;
579 self.until(b'=')?;
580 self.whitespace()?;
581 let value = if self.get()? == b'{' {
582 if self.looks_like_dict() {
583 self.get_expr()?
584 } else {
585 let span = self.current_pos();
587 let block_stmt = self.block()?;
588 Expr::new(ExprKind::Stmt(Box::new(block_stmt)), Span::new(span, self.current_pos()))
589 }
590 } else {
591 self.get_expr()?
592 };
593 self.whitespace()?;
594 let close = self.take(b';').is_ok();
595 let stmt = Stmt::new(StmtKind::Expr(value, close), Span::new(start, self.current_pos()));
596 Stmt::new(StmtKind::Let { pat, value: Box::new(stmt) }, Span::new(start, self.current_pos()))
597 } else if self.keyword("break").is_ok() {
598 self.until(b';')?;
599 Stmt::new(StmtKind::Break, Span::new(start, self.current_pos()))
600 } else if self.keyword("continue").is_ok() {
601 self.until(b';')?;
602 Stmt::new(StmtKind::Continue, Span::new(start, self.current_pos()))
603 } else if self.keyword("return").is_ok() {
604 self.whitespace()?;
605 let expr = if matches!(self.get(), Ok(b';' | b'}')) { None } else { Some(self.get_expr()?) };
606 self.whitespace()?;
607 if self.take(b';').is_err() && !matches!(self.get(), Ok(b'}')) {
608 return Err(anyhow!("return 后期望 ; 或 }}"));
612 }
613 Stmt::new(StmtKind::Return(expr), Span::new(start, self.current_pos()))
614 } else if self.keyword("if").is_ok() {
615 self.if_block()?
616 } else if self.keyword("loop").is_ok() {
617 Stmt::new(StmtKind::Loop(Box::new(self.block()?)), Span::new(start, self.current_pos()))
618 } else if self.keyword("while").is_ok() {
619 self.whitespace()?;
620 let cond = self.get_expr()?;
621 let body = Box::new(self.block()?);
622 Stmt::new(StmtKind::While { cond, body }, Span::new(start, self.current_pos()))
623 } else if self.keyword("for").is_ok() {
624 self.whitespace()?;
625 let pat = self.pattern()?;
626 self.whitespace()?;
627 self.keyword("in")?;
628 self.whitespace()?;
629 let range = self.get_expr()?;
630 self.push_decl_scope();
631 let result: Result<Stmt> = (|| {
632 self.declare_pattern_symbols(&pat)?;
633 let body = Box::new(self.block()?);
634 Ok(Stmt::new(StmtKind::For { pat, range, body }, Span::new(start, self.current_pos())))
635 })();
636 self.pop_decl_scope();
637 result?
638 } else if self.keyword("fn").is_ok() {
639 self.whitespace()?;
640 let (name, generic_params) = self.ident_generic()?;
641 self.declare_function_name(&name)?;
642 self.until(b'(')?;
643 let args = crate::parse_list!(self, Vec::new(), b')', b',', self.ident_typed()?);
644 let body = Box::new(self.function_body(&args)?);
645 Stmt::new(StmtKind::Fn { name, generic_params, args, body, is_pub }, Span::new(start, self.current_pos()))
646 } else if self.keyword("struct").is_ok() {
647 let (name, params) = self.ident_generic()?;
648 self.declare_symbol(&name)?;
649 if self.until(b'{').is_ok() {
650 let fields = crate::parse_list!(self, Vec::new(), b'}', b',', self.ident_typed()?);
651 if let Some(f) = fields.iter().find(|f| f.1.is_any()) {
652 return Err(anyhow!("字段 {} 的类型未知", f.0));
653 }
654 Stmt::new(StmtKind::Struct { name, def: Type::Struct { params, fields }, is_pub }, Span::new(start, self.current_pos()))
655 } else {
656 self.until(b';')?;
657 Stmt::new(StmtKind::Struct { name, def: Type::Struct { params, fields: Vec::new() }, is_pub }, Span::new(start, self.current_pos()))
658 }
659 } else if self.keyword("const").is_ok() {
660 self.whitespace()?;
661 let (name, ty) = self.ident_typed()?;
662 self.declare_symbol(&name)?;
663 self.until(b'=')?;
664 let value = self.get_expr()?;
665 self.until(b';')?;
666 Stmt::new(StmtKind::Const { name, ty, value, is_pub }, Span::new(start, self.current_pos()))
667 } else if self.keyword("static").is_ok() {
668 self.whitespace()?;
669 let (name, ty) = self.ident_typed()?;
670 self.declare_symbol(&name)?;
671 self.whitespace()?;
672 if self.take(b'=').is_ok() {
673 let expr = self.get_expr()?;
674 self.until(b';')?;
675 Stmt::new(StmtKind::Static { name, ty, value: Some(expr), is_pub }, Span::new(start, self.current_pos()))
676 } else {
677 self.until(b';')?;
678 Stmt::new(StmtKind::Static { name, ty, value: None, is_pub }, Span::new(start, self.current_pos()))
679 }
680 } else if self.keyword("impl").is_ok() {
681 self.whitespace()?;
682 let target = self.get_type()?;
683 Stmt::new(StmtKind::Impl { target, body: Box::new(self.impl_body()?) }, Span::new(start, self.current_pos()))
684 } else if self.keyword("pub").is_ok() {
685 if is_pub {
688 return Err(anyhow!("重复的 pub 修饰符"));
689 }
690 self.stmt(true)?
691 } else {
692 let expr = if self.get()? == b'{' {
693 if self.looks_like_empty_dict() {
694 self.dict()?
695 } else if let Ok(block) = try_parse!(self, self.block()) {
696 return Ok(block);
698 } else if let Ok(dict) = try_parse!(self, self.dict()) {
699 dict
700 } else {
701 let block = self.block()?;
702 return Ok(block);
703 }
704 } else {
705 self.get_expr()?
706 };
707 self.whitespace()?;
708 if self.is_eof() {
709 Stmt::new(StmtKind::Expr(expr, false), Span::new(start, self.current_pos()))
710 } else if self.get()? == b';' {
711 self.pos += 1;
712 Stmt::new(StmtKind::Expr(expr, true), Span::new(start, self.current_pos()))
713 } else if self.get()? == b'}' {
714 Stmt::new(StmtKind::Expr(expr, false), Span::new(start, self.current_pos()))
715 } else {
716 return Err(anyhow!("未结束的表达式"));
717 }
718 };
719 Ok(stmt)
721 }
722}