pipeline_script/parser/
stmt.rs

1use crate::ast::declaration::VariableDeclaration;
2use crate::ast::expr::{Expr, ExprNode};
3use crate::ast::stmt::{IfBranchStmt, IfStmt, MatchBranch, Stmt, StmtNode};
4use crate::context::Context;
5use crate::lexer::position::Position;
6use crate::lexer::token::Token;
7use crate::parser::Parser;
8
9impl Parser {
10    pub fn parse_match_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
11        // 解析match关键字
12        let pos = self.parse_keyword("match")?;
13
14        // 解析匹配的表达式
15        self.parse_special_token(Token::BraceLeft)?;
16        let expr = self.parse_expr(ctx)?;
17        self.parse_special_token(Token::BraceRight)?;
18
19        // 解析匹配体
20        self.parse_special_token(Token::ParenLeft)?;
21
22        // 解析匹配分支
23        let mut branches = vec![];
24        loop {
25            let (token, _) = self.token_stream.peek();
26            match token {
27                Token::ParenRight => {
28                    self.parse_special_token(Token::ParenRight)?;
29                    break;
30                }
31                _ => {
32                    // 解析模式
33                    let pattern = self.parse_expr(ctx)?;
34
35                    // 解析箭头 (->)
36                    self.parse_special_token(Token::Arrow)?;
37
38                    // 解析分支体
39                    let mut body = vec![];
40
41                    // 检查是否是代码块
42                    let (token, _) = self.token_stream.peek();
43                    if token == Token::ParenLeft {
44                        body = self.parse_block(ctx)?;
45                    } else {
46                        // 单个语句
47                        let stmt = self.parse_stmt(ctx)?;
48                        body.push(stmt);
49                    }
50
51                    // 添加分支
52                    branches.push(MatchBranch::new(pattern, body));
53
54                    // 检查是否有逗号
55                    if self.try_parse_token(Token::Comma) {
56                        continue;
57                    }
58                }
59            }
60        }
61
62        // 创建match语句
63        let match_stmt = Stmt::Match(Box::new(expr), branches);
64        Ok(StmtNode::new(match_stmt, pos))
65    }
66
67    // 解析if let语句
68    pub fn parse_if_let_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
69        // 解析if关键字
70        let pos = self.parse_keyword("if")?;
71
72        // 解析let关键字
73        self.parse_keyword("let")?;
74
75        // 解析左括号
76        self.parse_special_token(Token::BraceLeft)?;
77
78        // 解析模式
79        let pattern = self.parse_expr(ctx)?;
80
81        // 解析等号
82        self.parse_special_token(Token::Assign)?;
83
84        // 解析匹配的表达式
85        let expr = self.parse_expr(ctx)?;
86
87        // 解析右括号
88        self.parse_special_token(Token::BraceRight)?;
89
90        // 解析if分支体
91        let body = self.parse_block(ctx)?;
92
93        // 解析else分支(如果有)
94        let mut else_body = None;
95        if self.try_parse_token(Token::Keyword("else".to_string())) {
96            else_body = Some(self.parse_block(ctx)?);
97        }
98
99        // 创建if let语句
100        let if_let_stmt = Stmt::IfLet(Box::new(pattern), Box::new(expr), body, else_body);
101        Ok(StmtNode::new(if_let_stmt, pos))
102    }
103    pub fn parse_if_const_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
104        // 解析if关键字
105        let pos = self.parse_keyword("if")?;
106        let s = self.val_keyword.clone();
107        // 解析const关键字
108        self.parse_keyword(s.as_str())?;
109
110        // 解析左括号
111        self.parse_special_token(Token::BraceLeft)?;
112
113        // 解析模式
114        let pattern = self.parse_expr(ctx)?;
115
116        // 解析等号
117        self.parse_special_token(Token::Assign)?;
118
119        // 解析匹配的表达式
120        let expr = self.parse_expr(ctx)?;
121
122        // 解析右括号
123        self.parse_special_token(Token::BraceRight)?;
124
125        // 解析if分支体
126        let body = self.parse_block(ctx)?;
127
128        // 解析else分支(如果有)
129        let mut else_body = None;
130        if self.try_parse_token(Token::Keyword("else".to_string())) {
131            else_body = Some(self.parse_block(ctx)?);
132        }
133
134        // 创建if let语句
135        let if_let_stmt = Stmt::IfConst(Box::new(pattern), Box::new(expr), body, else_body);
136        Ok(StmtNode::new(if_let_stmt, pos))
137    }
138    pub fn parse_var_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
139        let keyword = self.var_keyword.clone();
140        self.parse_decl_stmt(ctx, &keyword, |vd, _| Stmt::VarDecl(vd))
141    }
142
143    pub fn parse_val_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
144        let keyword = self.val_keyword.clone();
145        self.parse_decl_stmt(ctx, &keyword, |vd, _| Stmt::ValDecl(vd))
146    }
147    pub(crate) fn parse_if_branch(
148        &mut self,
149        ctx: &Context,
150    ) -> crate::core::result::Result<(IfBranchStmt, Position)> {
151        let mut p0 = self.parse_keyword("if")?;
152        let p1 = self.parse_special_token(Token::BraceLeft)?;
153        let e = self.parse_expr(ctx).unwrap();
154        let p2 = e.position();
155        let p3 = self.parse_special_token(Token::BraceRight)?;
156        let block = self.parse_block(ctx)?;
157        for b in block.iter() {
158            p0 += b.position();
159        }
160        let branch = IfBranchStmt::new(e, block);
161        Ok((branch, p0 + p1 + p2 + p3))
162    }
163    fn parse_decl_stmt(
164        &mut self,
165        ctx: &Context,
166        keyword: &str,
167        builder: fn(VariableDeclaration, ExprNode) -> Stmt,
168    ) -> crate::core::result::Result<StmtNode> {
169        let p0 = self.parse_keyword(keyword)?;
170        let (name, mut p1) = self.parse_identifier()?;
171        let mut vd = VariableDeclaration::new(name);
172
173        // 处理类型注解
174        if let Token::Colon = self.token_stream.peek().0 {
175            p1 += self.parse_special_token(Token::Colon)?;
176            let ty = self.parse_type()?;
177            vd = vd.with_type(ty);
178        }
179
180        // 处理赋值表达式
181        let p4 = self.parse_special_token(Token::Assign)?;
182        let expr = self.parse_expr(ctx)?;
183        let p5 = expr.position();
184
185        Ok(StmtNode::new(
186            builder(vd.with_default(expr.clone()), expr),
187            p0 + p1 + p4 + p5,
188        ))
189    }
190    pub(crate) fn parse_return_stmt(
191        &mut self,
192        ctx: &Context,
193    ) -> crate::core::result::Result<StmtNode> {
194        let p0 = self.parse_keyword("return")?;
195        if self.token_stream.peek().0 == Token::ParenRight {
196            return Ok(StmtNode::new(Stmt::Return(Box::new(Expr::None.into())), p0));
197        }
198        let expr = self.parse_expr(ctx).expect("parse return stmt error");
199        Ok(StmtNode::new(Stmt::Return(Box::new(expr)), p0))
200    }
201    pub fn parse_while_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
202        let mut p0 = self.parse_keyword("while")?;
203        let p1 = self.parse_special_token(Token::BraceLeft)?;
204        let expr = self.parse_expr(ctx)?;
205        let p2 = expr.position();
206        let p3 = self.parse_special_token(Token::BraceRight)?;
207        let block = self.parse_block(ctx)?;
208        for s in block.iter() {
209            p0 += s.position();
210        }
211        Ok(StmtNode::new(
212            Stmt::While(Box::new(expr), block),
213            p0 + p1 + p2 + p3,
214        ))
215    }
216    pub fn parse_if_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
217        let mut branches = vec![];
218        let mut else_body = None;
219        let (b, pos) = self.parse_if_branch(ctx).unwrap();
220        branches.push(b);
221
222        loop {
223            let (peek, _) = self.token_stream.peek();
224            match peek.clone() {
225                Token::Keyword(k) if k == "else" => {
226                    self.token_stream.next_token();
227                    let (peek0, _) = self.token_stream.peek();
228                    if let Token::ParenLeft = peek0 {
229                        let blocks = self.parse_block(ctx)?;
230                        else_body = Some(blocks);
231                        break;
232                    }
233                    let (b0, _) = self.parse_if_branch(ctx)?;
234                    branches.push(b0);
235                }
236                _ => break,
237            }
238        }
239        Ok(StmtNode::new(
240            Stmt::If(Box::new(IfStmt::new(branches, else_body))),
241            pos,
242        ))
243    }
244    pub fn parse_for_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
245        self.parse_keyword("for")?;
246        self.parse_special_token(Token::BraceLeft)?;
247        let (var_name, _) = self.parse_identifier()?;
248        let _ = self.parse_keyword("in");
249        let e0 = self.parse_expr(ctx)?;
250        self.parse_special_token(Token::BraceRight)?;
251        let body = self.parse_block(ctx)?;
252        Ok(StmtNode::new(
253            Stmt::ForIn(var_name, Box::new(e0), body),
254            Position::none(),
255        ))
256    }
257    pub(crate) fn parse_continue_stmt(&mut self) -> crate::core::result::Result<StmtNode> {
258        todo!()
259    }
260    pub(crate) fn parse_break_stmt(&mut self) -> crate::core::result::Result<StmtNode> {
261        self.parse_keyword("break")?;
262        Ok(StmtNode::new(Stmt::Break, Position::none()))
263    }
264    pub fn parse_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
265        loop {
266            let (token, _) = self.token_stream.peek();
267            return Ok(match token {
268                Token::Keyword(k) => match k.as_str() {
269                    t if t == self.var_keyword => self.parse_var_stmt(ctx)?,
270                    t if t == self.val_keyword => self.parse_val_stmt(ctx).unwrap(),
271                    "while" => self.parse_while_stmt(ctx).unwrap(),
272                    "for" => self.parse_for_stmt(ctx).unwrap(),
273                    "return" => self.parse_return_stmt(ctx).unwrap(),
274                    "break" => self.parse_break_stmt()?,
275                    "continue" => self.parse_continue_stmt()?,
276                    "struct" => {
277                        self.parse_struct(ctx)?;
278                        continue;
279                    }
280                    "enum" => {
281                        self.parse_enum(ctx)?;
282                        continue;
283                    }
284                    "trait" => {
285                        self.parse_trait();
286                        continue;
287                    }
288                    "extern" => {
289                        self.parse_extern_function_declaration(ctx).unwrap();
290                        continue;
291                    }
292                    "module" => {
293                        self.parse_module(ctx)?;
294                        continue;
295                    }
296                    "match" => {
297                        return self.parse_match_stmt(ctx);
298                    }
299                    "if" => {
300                        // 检查是否是if let语句
301                        let (next_token, _) = self.token_stream.peek_nth(1);
302                        if next_token.is_keyword("let") {
303                            return self.parse_if_let_stmt(ctx);
304                        } else if next_token.is_keyword("const") {
305                            return self.parse_if_const_stmt(ctx);
306                        } else {
307                            return self.parse_if_stmt(ctx);
308                        }
309                    }
310                    t => {
311                        if t == self.function_keyword {
312                            self.parse_function(ctx).unwrap();
313                            continue;
314                        }
315                        dbg!(t);
316                        todo!()
317                    }
318                },
319                Token::Eof | Token::ParenRight => StmtNode::new(Stmt::Noop, Position::none()),
320                _ => {
321                    let e0 = self.parse_expr(ctx)?;
322                    let p0 = e0.position();
323                    let (peek, p1) = self.token_stream.peek();
324                    if let Token::Assign = peek {
325                        let p0 = self.parse_special_token(Token::Assign)?;
326                        let e1 = self.parse_expr(ctx)?;
327                        let p2 = e1.position();
328                        return Ok(StmtNode::new(
329                            Stmt::Assign(Box::new(e0), Box::new(e1)),
330                            p0 + p1 + p2,
331                        ));
332                    }
333                    return Ok(StmtNode::new(Stmt::EvalExpr(Box::new(e0)), p0));
334                }
335            });
336        }
337    }
338}