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
148    pub fn parse_static_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
149        // 检查是否在全局作用域
150        if !self.is_in_global_scope() {
151            use crate::core::error::Error;
152            use crate::lexer::position::Position;
153            return Err(Error::Message(
154                "static declarations can only be used in global scope".to_string(),
155                Position::none(),
156            ));
157        }
158        self.parse_decl_stmt(ctx, "static", |vd, _| Stmt::StaticDecl(vd))
159    }
160
161    pub(crate) fn parse_if_branch(
162        &mut self,
163        ctx: &Context,
164    ) -> crate::core::result::Result<(IfBranchStmt, Position)> {
165        let mut p0 = self.parse_keyword("if")?;
166        let p1 = self.parse_special_token(Token::BraceLeft)?;
167        let e = self.parse_expr(ctx).unwrap();
168        let p2 = e.position();
169        let p3 = self.parse_special_token(Token::BraceRight)?;
170        let block = self.parse_block(ctx)?;
171        for b in block.iter() {
172            p0 += b.position();
173        }
174        let branch = IfBranchStmt::new(e, block);
175        Ok((branch, p0 + p1 + p2 + p3))
176    }
177    fn parse_decl_stmt(
178        &mut self,
179        ctx: &Context,
180        keyword: &str,
181        builder: fn(VariableDeclaration, ExprNode) -> Stmt,
182    ) -> crate::core::result::Result<StmtNode> {
183        let p0 = self.parse_keyword(keyword)?;
184        let (name, mut p1) = self.parse_identifier()?;
185        let mut vd = VariableDeclaration::new(name);
186
187        // 处理类型注解
188        if let Token::Colon = self.token_stream.peek().0 {
189            p1 += self.parse_special_token(Token::Colon)?;
190            let ty = self.parse_type()?;
191            vd = vd.with_type(ty);
192        }
193
194        // 处理赋值表达式
195        let p4 = self.parse_special_token(Token::Assign)?;
196        let expr = self.parse_expr(ctx)?;
197        let p5 = expr.position();
198
199        Ok(StmtNode::new(
200            builder(vd.with_default(expr.clone()), expr),
201            p0 + p1 + p4 + p5,
202        ))
203    }
204    pub(crate) fn parse_return_stmt(
205        &mut self,
206        ctx: &Context,
207    ) -> crate::core::result::Result<StmtNode> {
208        let p0 = self.parse_keyword("return")?;
209        if self.token_stream.peek().0 == Token::ParenRight {
210            return Ok(StmtNode::new(Stmt::Return(Box::new(Expr::None.into())), p0));
211        }
212        let expr = self.parse_expr(ctx).expect("parse return stmt error");
213        Ok(StmtNode::new(Stmt::Return(Box::new(expr)), p0))
214    }
215    pub fn parse_while_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
216        let mut p0 = self.parse_keyword("while")?;
217        let p1 = self.parse_special_token(Token::BraceLeft)?;
218        let expr = self.parse_expr(ctx)?;
219        let p2 = expr.position();
220        let p3 = self.parse_special_token(Token::BraceRight)?;
221        let block = self.parse_block(ctx)?;
222        for s in block.iter() {
223            p0 += s.position();
224        }
225        Ok(StmtNode::new(
226            Stmt::While(Box::new(expr), block),
227            p0 + p1 + p2 + p3,
228        ))
229    }
230    pub fn parse_if_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
231        let mut branches = vec![];
232        let mut else_body = None;
233        let (b, pos) = self.parse_if_branch(ctx).unwrap();
234        branches.push(b);
235
236        loop {
237            let (peek, _) = self.token_stream.peek();
238            match peek.clone() {
239                Token::Keyword(k) if k == "else" => {
240                    self.token_stream.next_token();
241                    let (peek0, _) = self.token_stream.peek();
242                    if let Token::ParenLeft = peek0 {
243                        let blocks = self.parse_block(ctx)?;
244                        else_body = Some(blocks);
245                        break;
246                    }
247                    let (b0, _) = self.parse_if_branch(ctx)?;
248                    branches.push(b0);
249                }
250                _ => break,
251            }
252        }
253        Ok(StmtNode::new(
254            Stmt::If(Box::new(IfStmt::new(branches, else_body))),
255            pos,
256        ))
257    }
258    pub fn parse_for_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
259        self.parse_keyword("for")?;
260        self.parse_special_token(Token::BraceLeft)?;
261        let (var_name, _) = self.parse_identifier()?;
262        let _ = self.parse_keyword("in");
263        let e0 = self.parse_expr(ctx)?;
264        self.parse_special_token(Token::BraceRight)?;
265        let body = self.parse_block(ctx)?;
266        Ok(StmtNode::new(
267            Stmt::ForIn(var_name, Box::new(e0), body),
268            Position::none(),
269        ))
270    }
271    pub(crate) fn parse_continue_stmt(&mut self) -> crate::core::result::Result<StmtNode> {
272        todo!()
273    }
274    pub(crate) fn parse_break_stmt(&mut self) -> crate::core::result::Result<StmtNode> {
275        self.parse_keyword("break")?;
276        Ok(StmtNode::new(Stmt::Break, Position::none()))
277    }
278    pub fn parse_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
279        loop {
280            let (token, _) = self.token_stream.peek();
281            return Ok(match token {
282                Token::Keyword(k) => match k.as_str() {
283                    t if t == self.var_keyword => self.parse_var_stmt(ctx)?,
284                    t if t == self.val_keyword => self.parse_val_stmt(ctx).unwrap(),
285                    "static" => self.parse_static_stmt(ctx)?,
286                    "while" => self.parse_while_stmt(ctx).unwrap(),
287                    "for" => self.parse_for_stmt(ctx).unwrap(),
288                    "return" => self.parse_return_stmt(ctx).unwrap(),
289                    "break" => self.parse_break_stmt()?,
290                    "continue" => self.parse_continue_stmt()?,
291                    "struct" => {
292                        self.parse_struct(ctx)?;
293                        continue;
294                    }
295                    "enum" => {
296                        self.parse_enum(ctx)?;
297                        continue;
298                    }
299                    "trait" => {
300                        self.parse_trait();
301                        continue;
302                    }
303                    "extern" => {
304                        self.parse_extern_function_declaration(ctx).unwrap();
305                        continue;
306                    }
307                    "module" => {
308                        self.parse_module(ctx)?;
309                        continue;
310                    }
311                    "match" => {
312                        return self.parse_match_stmt(ctx);
313                    }
314                    "if" => {
315                        // 检查是否是if let语句
316                        let (next_token, _) = self.token_stream.peek_nth(1);
317                        if next_token.is_keyword("let") {
318                            return self.parse_if_let_stmt(ctx);
319                        } else if next_token.is_keyword("const") {
320                            return self.parse_if_const_stmt(ctx);
321                        } else {
322                            return self.parse_if_stmt(ctx);
323                        }
324                    }
325                    t => {
326                        if t == self.function_keyword {
327                            self.parse_function(ctx).unwrap();
328                            continue;
329                        }
330                        dbg!(t);
331                        todo!()
332                    }
333                },
334                Token::Eof | Token::ParenRight => StmtNode::new(Stmt::Noop, Position::none()),
335                _ => {
336                    let e0 = self.parse_expr(ctx)?;
337                    let p0 = e0.position();
338                    let (peek, p1) = self.token_stream.peek();
339                    if let Token::Assign = peek {
340                        let p0 = self.parse_special_token(Token::Assign)?;
341                        let e1 = self.parse_expr(ctx)?;
342                        let p2 = e1.position();
343                        return Ok(StmtNode::new(
344                            Stmt::Assign(Box::new(e0), Box::new(e1)),
345                            p0 + p1 + p2,
346                        ));
347                    }
348                    return Ok(StmtNode::new(Stmt::EvalExpr(Box::new(e0)), p0));
349                }
350            });
351        }
352    }
353}