pipeline_script/parser/
expr.rs

1use crate::ast::expr::{Argument, Expr, ExprNode, FunctionCall, Op, StructExpr};
2use crate::context::Context;
3use crate::core::error::Error;
4use crate::lexer::position::Position;
5use crate::lexer::token::Token;
6use crate::parser::helper::{get_struct_from_context, is_enum};
7use crate::parser::Parser;
8use std::collections::HashMap;
9
10impl Parser {
11    pub fn parse_primary_expr(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
12        let (token, mut pos) = self.token_stream.next_token();
13        match token {
14            Token::Not => {
15                let expr = self.parse_primary_expr(ctx)?;
16                Ok(ExprNode::from(Expr::Unary(Op::Not, Box::new(expr))).with_position(pos))
17            }
18            Token::Minus => {
19                let expr = self.parse_primary_expr(ctx)?;
20                Ok(ExprNode::from(Expr::Unary(Op::Negate, Box::new(expr))).with_position(pos))
21            }
22            Token::Vertical => {
23                let peek = self.token_stream.peek().0;
24                let mut l = vec![];
25                if peek != Token::Vertical {
26                    l = self.parse_param_list(ctx)?;
27                }
28                let p1 = self.parse_special_token(Token::Vertical)?;
29                if let Token::Arrow = self.token_stream.peek().0 {
30                    let _ = self.parse_special_token(Token::Arrow)?;
31                    let return_type = self.parse_type()?;
32                    let block = self.parse_block(ctx)?;
33                    Ok(ExprNode::from(Expr::Closure {
34                        args: l,
35                        body: block,
36                        captures: vec![],
37                        return_type: Some(return_type),
38                    })
39                    .with_position(p1 + pos))
40                } else {
41                    let block = self.parse_block(ctx)?;
42                    Ok(ExprNode::from(Expr::Closure {
43                        args: l,
44                        body: block,
45                        captures: vec![],
46                        return_type: None,
47                    })
48                    .with_position(p1 + pos))
49                }
50            }
51            Token::Identifier(id) => {
52                // 检查是否是枚举变体访问
53                if is_enum(ctx, &id) && self.try_parse_token(Token::Dot) {
54                    return self.parse_enum_variant(ctx, &id, pos);
55                }
56                let mut generics = vec![];
57                loop {
58                    let (peek, _) = self.token_stream.peek();
59                    match peek {
60                        Token::ScopeSymbol => {
61                            let _ = self.parse_special_token(Token::ScopeSymbol)?;
62                            let list = self.parse_generic_list()?;
63                            let (args, _) = self.parse_fn_args(ctx)?;
64                            return Ok(ExprNode::from(Expr::FnCall(FunctionCall {
65                                name: id,
66                                args,
67                                is_method: false,
68                                generics: list,
69                                type_generics: vec![],
70                            }))
71                            .with_position(pos));
72                        }
73                        Token::BraceLeft => {
74                            let (args, p0) = self.parse_fn_args(ctx)?;
75                            pos += p0;
76                            return Ok(ExprNode::from(Expr::FnCall(FunctionCall {
77                                name: id,
78                                args,
79                                is_method: false,
80                                generics,
81                                type_generics: vec![],
82                            }))
83                            .with_position(pos));
84                        }
85                        Token::Less => {
86                            let mut flag = false;
87                            ctx.apply_module(self.module, |m| {
88                                let r = m.get_struct(&id);
89                                if r.is_some() {
90                                    flag = true;
91                                }
92                            });
93                            if flag {
94                                generics = self.parse_generic_list()?;
95                            } else {
96                                return Ok(ExprNode::from(Expr::Variable(id)).with_position(pos));
97                            }
98                        }
99                        Token::ParenLeft => {
100                            let f = ctx.get_function(&id);
101                            if f.is_some() {
102                                let mut args = vec![];
103                                let body = self.parse_block(ctx)?;
104                                let expr = Expr::Closure {
105                                    args: vec![],
106                                    body,
107                                    captures: vec![],
108                                    return_type: None,
109                                };
110                                let expr_node = ExprNode::from(expr).with_position(pos.clone());
111                                args.push(Argument::new(expr_node));
112                                return Ok(ExprNode::from(Expr::FnCall(FunctionCall {
113                                    name: id,
114                                    args,
115                                    is_method: false,
116                                    generics,
117                                    type_generics: vec![],
118                                }))
119                                .with_position(pos));
120                            }
121                            // 解析结构体构造
122                            let p0 = self.parse_special_token(Token::ParenLeft)?;
123
124                            let mut fields = HashMap::new();
125                            loop {
126                                let (peek, p1) = self.token_stream.peek();
127                                pos += p1;
128                                match peek {
129                                    Token::ParenRight => {
130                                        let p2 = self.parse_special_token(Token::ParenRight)?;
131                                        pos += p2;
132                                        break;
133                                    }
134                                    Token::Comma => {
135                                        let p2 = self.parse_special_token(Token::Comma)?;
136                                        pos += p2;
137                                        continue;
138                                    }
139                                    Token::Identifier(ident) => {
140                                        let (_, _) = self.parse_identifier()?;
141                                        let _ = self.parse_special_token(Token::Colon)?;
142                                        let expr = self.parse_expr(ctx)?;
143                                        let _ = expr.position();
144                                        fields.insert(ident, expr);
145                                    }
146                                    _ => todo!("parse primary expr"),
147                                }
148                            }
149
150                            pos += p0;
151                            return Ok(ExprNode::from(Expr::Struct(
152                                StructExpr::new(id, fields).with_generics(generics),
153                            ))
154                            .with_position(pos));
155                        }
156                        Token::Dot if !generics.is_empty() => {
157                            let _ = self.parse_special_token(Token::Dot)?;
158                            let (static_method, p1) = self.parse_identifier()?;
159                            pos += p1;
160                            let (args, p2) = self.parse_fn_args(ctx).unwrap();
161                            pos += p2;
162                            return Ok(ExprNode::from(Expr::FnCall(FunctionCall {
163                                name: format!("{}.{}", id, static_method),
164                                args,
165                                is_method: false,
166                                generics: vec![],
167                                type_generics: generics,
168                            })));
169                        }
170                        _ => return Ok(ExprNode::from(Expr::Variable(id)).with_position(pos)),
171                    }
172                }
173            }
174            Token::Int(n) => Ok(ExprNode::from(Expr::Int(n)).with_position(pos)),
175            Token::String(s) => Ok(ExprNode::from(Expr::String(s)).with_position(pos)),
176            Token::Boolean(b) => Ok(ExprNode::from(Expr::Boolean(b)).with_position(pos)),
177            Token::Float(n) => Ok(ExprNode::from(Expr::Float(n)).with_position(pos)),
178            Token::BraceLeft => {
179                let expr = self.parse_expr(ctx)?;
180                self.parse_special_token(Token::BraceRight)?;
181                Ok(ExprNode::from(Expr::Brace(Box::new(expr))).with_position(pos))
182            }
183            Token::BitAnd => {
184                let expr = self.parse_primary_expr(ctx)?;
185                let _ = expr.position();
186                Ok(ExprNode::from(Expr::Address(Box::new(expr))).with_position(pos))
187            }
188            Token::BracketLeft => {
189                let mut v = vec![];
190                loop {
191                    let expr = self.parse_expr(ctx)?;
192                    pos += expr.position();
193                    v.push(expr);
194                    let (token, p1) = self.token_stream.peek();
195                    pos += p1;
196                    match token {
197                        Token::BracketRight => {
198                            let p2 = self.parse_special_token(Token::BracketRight)?;
199                            return Ok(ExprNode::from(Expr::Array(v)).with_position(pos + p2));
200                        }
201                        Token::Comma => {
202                            let p2 = self.parse_special_token(Token::Comma)?;
203                            pos += p2;
204                            continue;
205                        }
206                        _ => {}
207                    }
208                }
209            }
210            _ => Err(Error::UnexpectedToken(
211                token.to_string(),
212                "Expect Primary Expr".into(),
213                pos,
214            )),
215        }
216    }
217    fn parse_enum_variant(
218        &mut self,
219        ctx: &Context,
220        enum_name: &str,
221        pos: Position,
222    ) -> crate::core::result::Result<ExprNode> {
223        let (variant_name, variant_pos) = self.parse_identifier()?;
224
225        // 检查是否有关联值
226        if self.try_parse_token(Token::BraceLeft) {
227            // 解析关联值表达式
228            let value_expr = self.parse_expr(ctx)?;
229            self.parse_special_token(Token::BraceRight)?;
230
231            // 创建枚举变体表达式
232            let enum_variant =
233                Expr::EnumVariant(enum_name.into(), variant_name, Some(Box::new(value_expr)));
234
235            Ok(ExprNode::new(enum_variant).with_position(pos + variant_pos))
236        } else {
237            // 没有关联值的枚举变体
238            let enum_variant = Expr::EnumVariant(enum_name.into(), variant_name, None);
239
240            Ok(ExprNode::new(enum_variant).with_position(pos + variant_pos))
241        }
242    }
243    pub fn parse_fact_expr(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
244        let expr = self.parse_chain_expr(ctx)?;
245        let p0 = expr.position();
246        let (token, _) = self.token_stream.peek();
247        match token {
248            Token::BraceLeft => {
249                let (mut args, p1) = self.parse_fn_args(ctx)?;
250                let p1 = p1 + p0;
251                let mut name = expr.get_member_name();
252                let mut is_method = false;
253
254                // 检查是否是结构体方法调用
255                if expr.is_member() {
256                    let root = expr.get_member_root();
257                    if let Expr::Variable(root_name) = &root.expr {
258                        // 检查是否是已知的结构体
259                        if let Some(_) = get_struct_from_context(ctx, root_name) {
260                            name = format!("{}.{}", root_name, name);
261                            args.insert(0, Argument::new(root));
262                            is_method = true;
263                        } else {
264                            // 普通成员访问,保持原始函数名,添加self参数
265                            args.insert(0, Argument::new(root));
266                            is_method = true;
267                        }
268                    }
269                }
270
271                Ok(ExprNode::from(Expr::FnCall(FunctionCall {
272                    name,
273                    generics: vec![],
274                    is_method,
275                    args,
276                    type_generics: vec![],
277                }))
278                .with_position(p1))
279            }
280            Token::BracketLeft => {
281                let p0 = self.parse_special_token(Token::BracketLeft)?;
282                let index = self.parse_expr(ctx)?;
283                let p1 = index.position();
284                let p2 = self.parse_special_token(Token::BracketRight)?;
285                Ok(ExprNode::from(Expr::Index(Box::new(expr), Box::new(index)))
286                    .with_position(p0 + p1 + p2))
287            }
288
289            _ => Ok(expr),
290        }
291    }
292    pub fn parse_term(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
293        let expr0 = self.parse_fact_expr(ctx)?;
294        let p0 = expr0.position();
295        let (token, _) = self.token_stream.peek();
296        match token {
297            Token::Star => {
298                let p1 = self.parse_special_token(Token::Star)?;
299                let expr1 = self.parse_term(ctx)?;
300                let p2 = expr1.position();
301                Ok(
302                    ExprNode::from(Expr::Binary(Op::Mul, Box::new(expr0), Box::new(expr1)))
303                        .with_position(p0 + p1 + p2),
304                )
305            }
306            Token::Slash => {
307                let p0 = self.parse_special_token(Token::Slash)?;
308                let expr1 = self.parse_term(ctx)?;
309                Ok(
310                    ExprNode::from(Expr::Binary(Op::Div, Box::new(expr0), Box::new(expr1)))
311                        .with_position(p0),
312                )
313            }
314            _ => Ok(expr0),
315        }
316    }
317
318    pub fn parse_expr0(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
319        let expr0 = self.parse_term(ctx)?;
320        let (token, _) = self.token_stream.peek();
321        match token {
322            Token::Plus => {
323                let p0 = self.parse_special_token(Token::Plus)?;
324                let expr1 = self.parse_expr(ctx)?;
325                Ok(
326                    ExprNode::new(Expr::Binary(Op::Plus, Box::new(expr0), Box::new(expr1)))
327                        .with_position(p0),
328                )
329            }
330            Token::Minus => {
331                let p0 = self.parse_special_token(Token::Minus)?;
332                let expr1 = self.parse_expr(ctx)?;
333                Ok(
334                    ExprNode::new(Expr::Binary(Op::Minus, Box::new(expr0), Box::new(expr1)))
335                        .with_position(p0),
336                )
337            }
338            _ => Ok(expr0),
339        }
340    }
341    pub fn parse_expr(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
342        let expr0 = self.parse_expr0(ctx)?;
343        let (token, _) = self.token_stream.peek();
344        match token {
345            Token::Equal => {
346                let p0 = self.parse_special_token(Token::Equal)?;
347                let expr1 = self.parse_expr(ctx)?;
348                Ok(
349                    ExprNode::new(Expr::Binary(Op::Equal, Box::new(expr0), Box::new(expr1)))
350                        .with_position(p0),
351                )
352            }
353            Token::NotEqual => {
354                let p0 = self.parse_special_token(Token::NotEqual)?;
355                let expr1 = self.parse_expr(ctx)?;
356                Ok(
357                    ExprNode::new(Expr::Binary(Op::NotEqual, Box::new(expr0), Box::new(expr1)))
358                        .with_position(p0),
359                )
360            }
361            Token::Less => {
362                let p0 = self.parse_special_token(Token::Less)?;
363                let expr1 = self.parse_expr(ctx)?;
364                Ok(
365                    ExprNode::new(Expr::Binary(Op::Less, Box::new(expr0), Box::new(expr1)))
366                        .with_position(p0),
367                )
368            }
369            Token::LessEqual => {
370                let p0 = self.parse_special_token(Token::LessEqual)?;
371                let expr1 = self.parse_expr(ctx)?;
372                Ok(ExprNode::new(Expr::Binary(
373                    Op::LessEqual,
374                    Box::new(expr0),
375                    Box::new(expr1),
376                ))
377                .with_position(p0))
378            }
379            Token::GreaterEqual => {
380                let p0 = self.parse_special_token(Token::GreaterEqual)?;
381                let expr1 = self.parse_expr(ctx)?;
382                Ok(ExprNode::new(Expr::Binary(
383                    Op::GreaterEqual,
384                    Box::new(expr0),
385                    Box::new(expr1),
386                ))
387                .with_position(p0))
388            }
389            Token::Greater => {
390                let p0 = self.parse_special_token(Token::Greater)?;
391                let expr1 = self.parse_expr(ctx)?;
392                Ok(
393                    ExprNode::new(Expr::Binary(Op::Greater, Box::new(expr0), Box::new(expr1)))
394                        .with_position(p0),
395                )
396            }
397            _ => Ok(expr0),
398        }
399    }
400    pub fn parse_chain_expr(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
401        let mut expr = self.parse_primary_expr(ctx).unwrap();
402
403        loop {
404            let (peek, _) = self.token_stream.peek();
405            expr = match peek {
406                Token::Dot => {
407                    self.parse_special_token(Token::Dot)?;
408                    let (name, pos) = self.parse_identifier()?;
409                    ExprNode::from(Expr::Member(Box::new(expr), name)).with_position(pos)
410                }
411                Token::BracketLeft => {
412                    self.parse_special_token(Token::BracketLeft)?;
413                    let index = self.parse_expr(ctx)?;
414                    let pos = index.position();
415                    self.parse_special_token(Token::BracketRight)?;
416                    ExprNode::from(Expr::Index(Box::new(expr), Box::new(index))).with_position(pos)
417                }
418                _ => break,
419            };
420        }
421
422        Ok(expr)
423    }
424}