1use crate::try_parse;
2use dynamic::Type;
3
4use super::{Expr, Parser, Pattern, Span, expr::ExprKind, pattern::PatternKind};
5use anyhow::{Result, anyhow};
6use smol_str::SmolStr;
7
8#[derive(Debug, Clone)]
9pub struct Stmt {
10 pub kind: StmtKind,
11 pub span: Span,
12}
13
14#[derive(Debug, Clone)]
15pub enum StmtKind {
16 Let { pat: Pattern, value: Box<Stmt> },
17 Expr(Expr, bool),
18 Block(Vec<Stmt>),
19 Break,
20 Continue,
21 Return(Option<Expr>),
22 While { cond: Expr, body: Box<Stmt> },
23 Loop(Box<Stmt>),
24 For { pat: Pattern, range: Expr, body: Box<Stmt> },
25 Fn { name: SmolStr, generic_params: Vec<Type>, args: Vec<(SmolStr, Type)>, body: Box<Stmt>, is_pub: bool },
26 Struct { name: SmolStr, def: Type, is_pub: bool },
27 Impl { target: Type, body: Box<Stmt> },
28 If { cond: Expr, then_body: Box<Stmt>, else_body: Option<Box<Stmt>> },
29 Static { name: SmolStr, ty: Type, value: Option<Expr>, is_pub: bool },
30 Const { name: SmolStr, ty: Type, value: Expr, is_pub: bool },
31}
32
33impl Stmt {
34 pub fn new(kind: StmtKind, span: Span) -> Self {
35 Self { kind, span }
36 }
37
38 pub fn expr(&self) -> Option<Expr> {
39 if let StmtKind::Expr(expr, _) = &self.kind { Some(expr.clone()) } else { None }
40 }
41
42 pub fn is_return(&self) -> bool {
43 matches!(self.kind, StmtKind::Return(_))
44 }
45
46 pub fn last_return(&mut self) -> bool {
47 match &mut self.kind {
48 StmtKind::Block(stmts) => stmts.last_mut().map(|stmt| stmt.last_return()).unwrap_or(false),
49 StmtKind::If { then_body, else_body, .. } => {
50 let then_returns = then_body.last_return();
51 let else_returns = else_body.as_mut().map(|body| body.last_return()).unwrap_or(false);
52 then_returns && else_returns
53 }
54 StmtKind::Expr(e, close) => {
55 if !*close {
56 let span = e.span;
57 *self = Self::new(StmtKind::Return(Some(std::mem::take(e))), span);
58 true
59 } else {
60 false
61 }
62 }
63 StmtKind::Return(_) => true,
64 _ => false,
65 }
66 }
67
68 pub fn get_type(&self) -> Option<Type> {
69 match &self.kind {
70 StmtKind::Expr(expr, _) => Some(expr.get_type()),
71 StmtKind::Block(stmts) => stmts.last().and_then(|stmt| stmt.get_type()),
72 StmtKind::If { then_body, .. } => then_body.get_type(),
73 _ => None,
74 }
75 }
76
77 fn get_assign(idx: u32, expr: Expr) -> Self {
78 let span = expr.span;
79 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)
80 }
81
82 fn get_idx_assign(pat: Expr, idx: usize, expr: Expr) -> Self {
83 let span = pat.span.merge(expr.span);
84 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);
85 Self::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(pat), op: crate::BinaryOp::Assign, right: Box::new(right) }, span), true), span)
86 }
87
88 pub fn bind_pattern(&mut self, pat: Pattern) -> Result<()> {
89 if let Some(expr) = self.expr() {
90 let stmt = match pat.kind {
91 PatternKind::Var { idx, ty } => {
92 if expr.get_type() != ty {
93 Self::get_assign(idx, Expr::new(ExprKind::Typed { value: Box::new(expr), ty }, pat.span))
94 } else {
95 Self::get_assign(idx, expr)
96 }
97 }
98 PatternKind::Tuple(list) | PatternKind::List { elems: list, has_rest: _ } => {
99 let mut stmts = Vec::new();
100 for (idx, p) in list.into_iter().enumerate() {
101 match p.expr() {
102 Ok(p) => stmts.push(Self::get_idx_assign(p, idx, expr.clone())),
103 Err(e) => {
104 println!("{:?}", e);
105 }
106 }
107 }
108 Self::new(StmtKind::Block(stmts), self.span)
109 }
110 p => panic!("{:?}", p),
111 };
112 let _ = std::mem::replace(self, stmt);
113 } else {
114 match &mut self.kind {
115 StmtKind::Block(stmts) => {
116 stmts.last_mut().map(|stmt| stmt.bind_pattern(pat));
117 }
118 StmtKind::If { then_body, else_body, .. } => {
119 let _ = then_body.bind_pattern(pat.clone());
120 else_body.as_mut().map(|e| e.bind_pattern(pat));
121 }
122 _ => {}
123 }
124 }
125 Ok(())
126 }
127}
128
129use std::fmt;
130impl fmt::Display for Stmt {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 match &self.kind {
133 StmtKind::Let { pat, value } => writeln!(f, "let {:?} = {}", pat, value)?,
134 StmtKind::Block(stmts) => stmts.iter().for_each(|s| {
135 let _ = write!(f, "{}", s);
136 }),
137 StmtKind::Expr(expr, close) => writeln!(f, "{:?}[{}]", expr, close)?,
138 StmtKind::Break => writeln!(f, "break")?,
139 StmtKind::Continue => writeln!(f, "continue")?,
140 StmtKind::Return(r) => writeln!(f, "return {:?}", r)?,
141 StmtKind::While { cond, body } => write!(f, "while {:?}\n{}", cond, body)?,
142 StmtKind::Loop(body) => write!(f, "loop\n{}", body)?,
143 StmtKind::For { pat, range, body } => writeln!(f, "for {:?} in {:?} \n{}", pat, range, body)?,
144 StmtKind::If { cond, then_body, else_body } => {
145 write!(f, "if {:?}\nthen-> {}\n", cond, then_body)?;
146 if let Some(e) = else_body {
147 writeln!(f, "{}", e)?;
148 }
149 }
150 StmtKind::Fn { name, generic_params, args, body, is_pub } => {
151 let generic_suffix = if generic_params.is_empty() { String::new() } else { format!("<{:?}>", generic_params) };
152 if *is_pub {
153 write!(f, "pub fn {:?}{} {:?}\n", name, generic_suffix, args)?
154 } else {
155 write!(f, "fn {:?}{} {:?}\n", name, generic_suffix, args)?
156 }
157 write!(f, "{}", body)?;
158 }
159 _ => {
160 panic!("无效语句 {:?}", self)
161 }
162 }
163 fmt::Result::Ok(())
164 }
165}
166
167impl Parser {
168 pub fn ident_typed(&mut self) -> Result<(SmolStr, Type)> {
169 let name = self.ident()?;
170 self.whitespace()?;
171 if self.take(b':').is_ok() { Ok((name, self.get_type()?)) } else { Ok((name, Type::Any)) }
172 }
173
174 pub fn ident_generic(&mut self) -> Result<(SmolStr, Vec<Type>)> {
175 self.whitespace()?;
176 let name = self.ident()?;
177 self.whitespace()?;
178 let params = if self.get()? == b'<' {
179 self.pos += 1;
180 crate::parse_list!(self, Vec::new(), b'>', b',', self.get_type_param()?)
181 } else {
182 Vec::new()
183 };
184 Ok((name, params))
185 }
186
187 pub fn block(&mut self) -> Result<Stmt> {
188 self.whitespace()?;
189 let start = self.current_pos();
190 if self.get()? == b'{' {
191 self.pos += 1;
192 Ok(Stmt::new(StmtKind::Block(crate::parse_list!(self, Vec::new(), b'}', 0, self.stmt(false)?)), self.span_from(start)))
193 } else {
194 Err(anyhow!("not code block"))
195 }
196 }
197
198 pub fn if_block(&mut self) -> Result<Stmt> {
199 let start = self.spans.last().copied().unwrap_or_else(|| self.current_pos());
200 let cond = self.get_expr_without_struct_literal()?;
201 let then_body = Box::new(self.block()?);
202 self.whitespace()?;
203 let else_body = if self.keyword("else").is_ok() {
204 self.whitespace()?;
205 if self.keyword("if").is_ok() { self.if_block().map(Box::new).ok() } else { self.block().map(Box::new).ok() }
206 } else {
207 None
208 };
209 Ok(Stmt::new(StmtKind::If { cond, then_body, else_body }, Span::new(start, self.current_pos())))
210 }
211
212 pub fn stmt(&mut self, is_pub: bool) -> Result<Stmt> {
213 self.whitespace()?;
214 self.spans.push(self.pos);
215 let start = self.current_pos();
216 let stmt = if self.keyword("let").is_ok() {
217 let pat = self.pattern()?;
218 self.until(b'=')?;
219 self.whitespace()?;
220 let stmt = if self.get()? == b'{' {
221 if self.looks_like_dict() {
222 let expr = self.get_expr()?;
223 self.whitespace()?;
224 if self.get()? == b';' {
225 self.pos += 1;
226 }
227 Stmt::new(StmtKind::Expr(expr, true), Span::new(start, self.current_pos()))
228 } else {
229 return Err(anyhow!("代码块不能直接作为表达式,请使用 || {{ ... }} 包装为匿名函数"));
230 }
231 } else {
232 let stmt = self.stmt(false)?;
233 if stmt.expr().is_none() {
234 self.until(b';')?;
235 }
236 stmt
237 };
238 Stmt::new(StmtKind::Let { pat, value: Box::new(stmt) }, Span::new(start, self.current_pos()))
239 } else if self.keyword("break").is_ok() {
240 self.until(b';')?;
241 Stmt::new(StmtKind::Break, Span::new(start, self.current_pos()))
242 } else if self.keyword("continue").is_ok() {
243 self.until(b';')?;
244 Stmt::new(StmtKind::Continue, Span::new(start, self.current_pos()))
245 } else if self.keyword("return").is_ok() {
246 self.whitespace()?;
247 let expr = self.get_expr().ok();
248 self.until(b';')?;
249 Stmt::new(StmtKind::Return(expr), Span::new(start, self.current_pos()))
250 } else if self.keyword("if").is_ok() {
251 self.if_block()?
252 } else if self.keyword("loop").is_ok() {
253 Stmt::new(StmtKind::Loop(Box::new(self.block()?)), Span::new(start, self.current_pos()))
254 } else if self.keyword("while").is_ok() {
255 self.whitespace()?;
256 let cond = self.get_expr()?;
257 let body = Box::new(self.block()?);
258 Stmt::new(StmtKind::While { cond, body }, Span::new(start, self.current_pos()))
259 } else if self.keyword("for").is_ok() {
260 self.whitespace()?;
261 let pat = self.pattern()?;
262 self.whitespace()?;
263 self.keyword("in")?;
264 self.whitespace()?;
265 let range = self.get_expr()?;
266 let body = Box::new(self.block()?);
267 Stmt::new(StmtKind::For { pat, range, body }, Span::new(start, self.current_pos()))
268 } else if self.keyword("fn").is_ok() {
269 self.whitespace()?;
270 let (name, generic_params) = self.ident_generic()?;
271 self.until(b'(')?;
272 let args = crate::parse_list!(self, Vec::new(), b')', b',', self.ident_typed()?);
273 let body = Box::new(self.block()?);
274 Stmt::new(StmtKind::Fn { name, generic_params, args, body, is_pub }, Span::new(start, self.current_pos()))
275 } else if self.keyword("struct").is_ok() {
276 let (name, params) = self.ident_generic()?;
277 if self.until(b'{').is_ok() {
278 let fields = crate::parse_list!(self, Vec::new(), b'}', b',', self.ident_typed()?);
279 if let Some(f) = fields.iter().find(|f| f.1.is_any()) {
280 return Err(anyhow!("字段 {} 的类型未知", f.0));
281 }
282 Stmt::new(StmtKind::Struct { name, def: Type::Struct { params, fields }, is_pub }, Span::new(start, self.current_pos()))
283 } else {
284 self.until(b';')?;
285 Stmt::new(StmtKind::Struct { name, def: Type::Struct { params, fields: Vec::new() }, is_pub }, Span::new(start, self.current_pos()))
286 }
287 } else if self.keyword("const").is_ok() {
288 self.whitespace()?;
289 let (name, ty) = self.ident_typed()?;
290 self.until(b'=')?;
291 let value = self.get_expr()?;
292 self.until(b';')?;
293 Stmt::new(StmtKind::Const { name, ty, value, is_pub }, Span::new(start, self.current_pos()))
294 } else if self.keyword("static").is_ok() {
295 self.whitespace()?;
296 let (name, ty) = self.ident_typed()?;
297 self.whitespace()?;
298 if self.take(b'=').is_ok() {
299 let expr = self.get_expr()?;
300 self.until(b';')?;
301 Stmt::new(StmtKind::Static { name, ty, value: Some(expr), is_pub }, Span::new(start, self.current_pos()))
302 } else {
303 self.until(b';')?;
304 Stmt::new(StmtKind::Static { name, ty, value: None, is_pub }, Span::new(start, self.current_pos()))
305 }
306 } else if self.keyword("impl").is_ok() {
307 self.whitespace()?;
308 let target = self.get_type()?;
309 Stmt::new(StmtKind::Impl { target, body: Box::new(self.block()?) }, Span::new(start, self.current_pos()))
310 } else if self.keyword("pub").is_ok() {
311 self.stmt(true)?
312 } else {
313 let expr = if self.get()? == b'{' {
314 if let Ok(block) = try_parse!(self, self.block()) {
315 let _ = self.spans.pop();
316 return Ok(block);
317 } else if let Ok(dict) = try_parse!(self, self.dict()) {
318 dict
319 } else {
320 let block = self.block()?;
321 let _ = self.spans.pop();
322 return Ok(block);
323 }
324 } else {
325 self.get_expr()?
326 };
327 self.whitespace()?;
328 if self.is_eof() {
329 Stmt::new(StmtKind::Expr(expr, false), Span::new(start, self.current_pos()))
330 } else if self.get()? == b';' {
331 self.pos += 1;
332 Stmt::new(StmtKind::Expr(expr, true), Span::new(start, self.current_pos()))
333 } else if self.get()? == b'}' {
334 Stmt::new(StmtKind::Expr(expr, false), Span::new(start, self.current_pos()))
335 } else {
336 return Err(anyhow!("未结束的表达式"));
337 }
338 };
339 let _ = self.spans.pop();
340 Ok(stmt)
341 }
342}