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).unwrap();
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).unwrap();
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).unwrap();
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).unwrap();
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().unwrap();
63                            let (args, _) = self.parse_fn_args(ctx).unwrap();
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().unwrap();
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).unwrap();
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).unwrap();
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::Int8(n) => Ok(ExprNode::from(Expr::Int8(n)).with_position(pos)),
176            Token::Int16(n) => Ok(ExprNode::from(Expr::Int16(n)).with_position(pos)),
177            Token::Int32(n) => Ok(ExprNode::from(Expr::Int32(n)).with_position(pos)),
178            Token::Int64(n) => Ok(ExprNode::from(Expr::Int64(n)).with_position(pos)),
179            Token::String(s) => Ok(ExprNode::from(Expr::String(s)).with_position(pos)),
180            Token::Boolean(b) => Ok(ExprNode::from(Expr::Boolean(b)).with_position(pos)),
181            Token::Float(n) => Ok(ExprNode::from(Expr::Double(n)).with_position(pos)),
182            Token::Float32(n) => Ok(ExprNode::from(Expr::Float(n)).with_position(pos)),
183            Token::Float64(n) => Ok(ExprNode::from(Expr::Double(n)).with_position(pos)),
184            Token::BraceLeft => {
185                let expr = self.parse_expr(ctx)?;
186                self.parse_special_token(Token::BraceRight)?;
187                Ok(ExprNode::from(Expr::Brace(Box::new(expr))).with_position(pos))
188            }
189            Token::BitAnd => {
190                let expr = self.parse_primary_expr(ctx).unwrap();
191                let _ = expr.position();
192                Ok(ExprNode::from(Expr::Address(Box::new(expr))).with_position(pos))
193            }
194            Token::BracketLeft => {
195                let mut v = vec![];
196                loop {
197                    let expr = self.parse_expr(ctx).unwrap();
198                    pos += expr.position();
199                    v.push(expr);
200                    let (token, p1) = self.token_stream.peek();
201                    pos += p1;
202                    match token {
203                        Token::BracketRight => {
204                            let p2 = self.parse_special_token(Token::BracketRight)?;
205                            return Ok(ExprNode::from(Expr::Array(v)).with_position(pos + p2));
206                        }
207                        Token::Comma => {
208                            let p2 = self.parse_special_token(Token::Comma)?;
209                            pos += p2;
210                            continue;
211                        }
212                        _ => {}
213                    }
214                }
215            }
216            _ => Err(Error::UnexpectedToken(
217                token.to_string(),
218                "Expect Primary Expr".into(),
219                pos,
220            )),
221        }
222    }
223    fn parse_enum_variant(
224        &mut self,
225        ctx: &Context,
226        enum_name: &str,
227        pos: Position,
228    ) -> crate::core::result::Result<ExprNode> {
229        let (variant_name, variant_pos) = self.parse_identifier()?;
230
231        // 检查是否有关联值
232        if self.try_parse_token(Token::BraceLeft) {
233            // 解析关联值表达式
234            let value_expr = self.parse_expr(ctx)?;
235            self.parse_special_token(Token::BraceRight)?;
236
237            // 创建枚举变体表达式
238            let enum_variant =
239                Expr::EnumVariant(enum_name.into(), variant_name, Some(Box::new(value_expr)));
240
241            Ok(ExprNode::new(enum_variant).with_position(pos + variant_pos))
242        } else {
243            // 没有关联值的枚举变体
244            let enum_variant = Expr::EnumVariant(enum_name.into(), variant_name, None);
245
246            Ok(ExprNode::new(enum_variant).with_position(pos + variant_pos))
247        }
248    }
249    pub fn parse_fact_expr(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
250        let expr = self.parse_chain_expr(ctx)?;
251        let p0 = expr.position();
252        let (token, _) = self.token_stream.peek();
253        match token {
254            Token::BraceLeft => {
255                let (mut args, p1) = self.parse_fn_args(ctx)?;
256                let p1 = p1 + p0;
257                let mut name = expr.get_member_name();
258                let mut is_method = false;
259
260                // 检查是否是结构体方法调用
261                if expr.is_member() {
262                    let root = expr.get_member_root();
263                    if let Expr::Variable(root_name) = &root.expr {
264                        // 检查是否是已知的结构体
265                        if get_struct_from_context(ctx, root_name).is_some() {
266                            name = format!("{}.{}", root_name, name);
267                            let function = ctx.get_function(&name).unwrap();
268                            if !function.self_type().is_none() {
269                                args.insert(0, Argument::new(root));
270                                is_method = true;
271                            }
272                        } else {
273                            // 普通成员访问,保持原始函数名,添加self参数
274                            args.insert(0, Argument::new(root));
275                            is_method = true;
276                        }
277                    }
278                }
279
280                Ok(ExprNode::from(Expr::FnCall(FunctionCall {
281                    name,
282                    generics: vec![],
283                    is_method,
284                    args,
285                    type_generics: vec![],
286                }))
287                .with_position(p1))
288            }
289            Token::BracketLeft => {
290                let p0 = self.parse_special_token(Token::BracketLeft)?;
291                let index = self.parse_expr(ctx)?;
292                let p1 = index.position();
293                let p2 = self.parse_special_token(Token::BracketRight)?;
294                Ok(ExprNode::from(Expr::Index(Box::new(expr), Box::new(index)))
295                    .with_position(p0 + p1 + p2))
296            }
297
298            _ => Ok(expr),
299        }
300    }
301    pub fn parse_term(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
302        let expr0 = self.parse_fact_expr(ctx)?;
303        let p0 = expr0.position();
304        let (token, _) = self.token_stream.peek();
305        match token {
306            Token::Star => {
307                let p1 = self.parse_special_token(Token::Star)?;
308                let expr1 = self.parse_term(ctx)?;
309                let p2 = expr1.position();
310                Ok(
311                    ExprNode::from(Expr::Binary(Op::Mul, Box::new(expr0), Box::new(expr1)))
312                        .with_position(p0 + p1 + p2),
313                )
314            }
315            Token::Slash => {
316                let p0 = self.parse_special_token(Token::Slash)?;
317                let expr1 = self.parse_term(ctx)?;
318                Ok(
319                    ExprNode::from(Expr::Binary(Op::Div, Box::new(expr0), Box::new(expr1)))
320                        .with_position(p0),
321                )
322            }
323            _ => Ok(expr0),
324        }
325    }
326
327    pub fn parse_expr0(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
328        let expr0 = self.parse_term(ctx)?;
329        let (token, _) = self.token_stream.peek();
330        match token {
331            Token::Plus => {
332                let p0 = self.parse_special_token(Token::Plus)?;
333                let expr1 = self.parse_expr(ctx)?;
334                Ok(
335                    ExprNode::new(Expr::Binary(Op::Plus, Box::new(expr0), Box::new(expr1)))
336                        .with_position(p0),
337                )
338            }
339            Token::Minus => {
340                let p0 = self.parse_special_token(Token::Minus)?;
341                let expr1 = self.parse_expr(ctx)?;
342                Ok(
343                    ExprNode::new(Expr::Binary(Op::Minus, Box::new(expr0), Box::new(expr1)))
344                        .with_position(p0),
345                )
346            }
347            _ => Ok(expr0),
348        }
349    }
350    pub fn parse_expr(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
351        let lhs = self.parse_expr1(ctx)?;
352        let (token, _) = self.token_stream.peek();
353        match token {
354            Token::Or => {
355                let p0 = self.parse_special_token(Token::Or)?;
356                let expr1 = self.parse_expr1(ctx)?;
357                Ok(
358                    ExprNode::new(Expr::Binary(Op::Or, Box::new(lhs), Box::new(expr1)))
359                        .with_position(p0),
360                )
361            }
362            Token::And => {
363                let p0 = self.parse_special_token(Token::And)?;
364                let expr1 = self.parse_expr1(ctx)?;
365                Ok(
366                    ExprNode::new(Expr::Binary(Op::And, Box::new(lhs), Box::new(expr1)))
367                        .with_position(p0),
368                )
369            }
370            _ => Ok(lhs),
371        }
372    }
373    pub fn parse_expr1(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
374        let expr0 = self.parse_expr0(ctx)?;
375        let (token, _) = self.token_stream.peek();
376        match token {
377            Token::Equal => {
378                let p0 = self.parse_special_token(Token::Equal)?;
379                let expr1 = self.parse_expr1(ctx)?;
380                Ok(
381                    ExprNode::new(Expr::Binary(Op::Equal, Box::new(expr0), Box::new(expr1)))
382                        .with_position(p0),
383                )
384            }
385            Token::NotEqual => {
386                let p0 = self.parse_special_token(Token::NotEqual)?;
387                let expr1 = self.parse_expr1(ctx)?;
388                Ok(
389                    ExprNode::new(Expr::Binary(Op::NotEqual, Box::new(expr0), Box::new(expr1)))
390                        .with_position(p0),
391                )
392            }
393            Token::Less => {
394                let p0 = self.parse_special_token(Token::Less)?;
395                let expr1 = self.parse_expr1(ctx)?;
396                Ok(
397                    ExprNode::new(Expr::Binary(Op::Less, Box::new(expr0), Box::new(expr1)))
398                        .with_position(p0),
399                )
400            }
401            Token::LessEqual => {
402                let p0 = self.parse_special_token(Token::LessEqual)?;
403                let expr1 = self.parse_expr1(ctx)?;
404                Ok(ExprNode::new(Expr::Binary(
405                    Op::LessEqual,
406                    Box::new(expr0),
407                    Box::new(expr1),
408                ))
409                .with_position(p0))
410            }
411            Token::GreaterEqual => {
412                let p0 = self.parse_special_token(Token::GreaterEqual)?;
413                let expr1 = self.parse_expr1(ctx)?;
414                Ok(ExprNode::new(Expr::Binary(
415                    Op::GreaterEqual,
416                    Box::new(expr0),
417                    Box::new(expr1),
418                ))
419                .with_position(p0))
420            }
421            Token::Greater => {
422                let p0 = self.parse_special_token(Token::Greater)?;
423                let expr1 = self.parse_expr1(ctx)?;
424                Ok(
425                    ExprNode::new(Expr::Binary(Op::Greater, Box::new(expr0), Box::new(expr1)))
426                        .with_position(p0),
427                )
428            }
429            _ => Ok(expr0),
430        }
431    }
432    pub fn parse_chain_expr(&mut self, ctx: &Context) -> crate::core::result::Result<ExprNode> {
433        let mut expr = self.parse_primary_expr(ctx)?;
434
435        loop {
436            let (peek, _) = self.token_stream.peek();
437            expr = match peek {
438                Token::Dot => {
439                    self.parse_special_token(Token::Dot)?;
440                    let (name, pos) = self.parse_identifier()?;
441                    ExprNode::from(Expr::Member(Box::new(expr), name)).with_position(pos)
442                }
443                Token::BracketLeft => {
444                    self.parse_special_token(Token::BracketLeft)?;
445                    let index = self.parse_expr(ctx)?;
446                    let pos = index.position();
447                    self.parse_special_token(Token::BracketRight)?;
448                    ExprNode::from(Expr::Index(Box::new(expr), Box::new(index))).with_position(pos)
449                }
450                _ => break,
451            };
452        }
453
454        Ok(expr)
455    }
456}