pipeline_script/ast/
stmt.rs

1use crate::ast::data::Data;
2use crate::ast::declaration::VariableDeclaration;
3use crate::ast::expr::{Expr, ExprNode};
4use crate::ast::NodeTrait;
5use crate::lexer::position::Position;
6use std::any::Any;
7use std::collections::HashMap;
8
9#[derive(Debug, Clone)]
10pub struct StmtNode {
11    stmt: Stmt,
12    pos: Position,
13}
14#[derive(Debug, Clone)]
15pub enum Stmt {
16    EvalExpr(Box<ExprNode>),
17    ValDecl(VariableDeclaration),
18    VarDecl(VariableDeclaration),
19    Assign(Box<ExprNode>, Box<ExprNode>),
20    Return(Box<ExprNode>),
21    If(Box<IfStmt>),
22    While(Box<ExprNode>, Vec<StmtNode>),
23    ForIn(String, Box<ExprNode>, Vec<StmtNode>),
24    /// 第一个Expr表示的是获取Array或者Map的表达式
25    /// 第二个Expr表示的是获取索引的表达式
26    /// 第三个Expr表示的是对索引处的赋值
27    IndexAssign(Box<ExprNode>, Box<ExprNode>, Box<ExprNode>),
28    Break,
29    Continue,
30    Import(String),
31    // Match语句,包含匹配的表达式和匹配分支
32    Match(Box<ExprNode>, Vec<MatchBranch>),
33    // If let语句,用于模式匹配
34    IfLet(
35        Box<ExprNode>,
36        Box<ExprNode>,
37        Vec<StmtNode>,
38        Option<Vec<StmtNode>>,
39    ),
40    IfConst(
41        Box<ExprNode>,
42        Box<ExprNode>,
43        Vec<StmtNode>,
44        Option<Vec<StmtNode>>,
45    ),
46    Noop,
47}
48#[derive(Debug, Clone)]
49pub struct IfStmt {
50    branches: Vec<IfBranchStmt>,
51    else_body: Option<Vec<StmtNode>>,
52}
53
54impl IfStmt {
55    pub fn new(branches: Vec<IfBranchStmt>, else_body: Option<Vec<StmtNode>>) -> Self {
56        Self {
57            branches,
58            else_body,
59        }
60    }
61    pub fn set_else_body(&mut self, else_body: Option<Vec<StmtNode>>) {
62        self.else_body = else_body;
63    }
64    pub fn set_branches(&mut self, branches: Vec<IfBranchStmt>) {
65        self.branches = branches;
66    }
67    pub fn get_branches(&self) -> &Vec<IfBranchStmt> {
68        &self.branches
69    }
70    pub fn get_else_body(&self) -> Option<Vec<StmtNode>> {
71        self.else_body.clone()
72    }
73}
74#[derive(Debug, Clone)]
75pub struct IfBranchStmt {
76    condition: ExprNode,
77    body: Vec<StmtNode>,
78}
79
80impl IfBranchStmt {
81    pub fn new(condition: ExprNode, body: Vec<StmtNode>) -> Self {
82        Self { condition, body }
83    }
84
85    pub fn get_condition(&self) -> &ExprNode {
86        &self.condition
87    }
88    pub fn get_body(&self) -> &Vec<StmtNode> {
89        &self.body
90    }
91}
92
93// 匹配分支,包含模式和对应的语句
94#[derive(Debug, Clone)]
95pub struct MatchBranch {
96    pattern: ExprNode,
97    body: Vec<StmtNode>,
98}
99
100impl MatchBranch {
101    pub fn new(pattern: ExprNode, body: Vec<StmtNode>) -> Self {
102        Self { pattern, body }
103    }
104
105    pub fn get_pattern(&self) -> &ExprNode {
106        &self.pattern
107    }
108
109    pub fn get_body(&self) -> &Vec<StmtNode> {
110        &self.body
111    }
112}
113
114impl Stmt {
115    pub fn is_noop(&self) -> bool {
116        matches!(self, Stmt::Noop)
117    }
118    pub fn is_fn_call(&self) -> bool {
119        match self {
120            Stmt::EvalExpr(expr) => expr.is_fn_call(),
121            _ => false,
122        }
123    }
124    pub fn is_break(&self) -> bool {
125        matches!(self, Stmt::Break)
126    }
127    pub fn is_closure_decl(&self) -> bool {
128        match &self {
129            Stmt::ValDecl(v) => v.is_closure,
130            _ => false,
131        }
132    }
133}
134impl NodeTrait for StmtNode {
135    fn get_id(&self) -> &str {
136        match &self.stmt {
137            Stmt::EvalExpr(e) => e.get_id(),
138            Stmt::ValDecl(_) => "ValDecl",
139            Stmt::VarDecl(_) => "VarDecl",
140            Stmt::Assign(_, _) => "Assign",
141            Stmt::Return(_) => "Return",
142            Stmt::If(_) => "If",
143            Stmt::While(_, _) => "While",
144            Stmt::ForIn(_, _, _) => "ForIn",
145            Stmt::IndexAssign(_, _, _) => "IndexAssign",
146            Stmt::Break => "Break",
147            Stmt::Continue => "Continue",
148            Stmt::Import(_) => "Import",
149            Stmt::Noop => "Noop",
150            Stmt::Match(_, _) => "Match",
151            Stmt::IfLet(_, _, _, _) => "IfLet",
152            Stmt::IfConst(_, _, _, _) => "IfConst",
153        }
154    }
155
156    fn get_data(&self, key: &str) -> Option<Data> {
157        match &self.stmt {
158            Stmt::ValDecl(v) => v.get_data(key),
159            Stmt::EvalExpr(e) => e.get_data(key),
160            Stmt::VarDecl(v) => v.get_data(key),
161            _ => {
162                todo!()
163            }
164        }
165    }
166
167    fn set_data(&mut self, key: &str, value: Data) {
168        match &mut self.stmt {
169            Stmt::ValDecl(v) => {
170                if key == "name" {
171                    v.set_name(value.as_str().unwrap());
172                }
173            }
174            Stmt::EvalExpr(e) => e.set_data(key, value),
175            Stmt::VarDecl(v) => {
176                if key == "name" {
177                    v.set_name(value.as_str().unwrap());
178                }
179            }
180            _ => {
181                todo!()
182            }
183        }
184    }
185
186    fn get_children(&self) -> Vec<&dyn NodeTrait> {
187        todo!()
188    }
189
190    fn get_mut_children(&mut self) -> Vec<&mut dyn NodeTrait> {
191        match &mut self.stmt {
192            Stmt::ValDecl(v) => {
193                let mut children = vec![];
194                let default = v.get_mut_default();
195                match default {
196                    Some(default) => {
197                        children.push(default as &mut dyn NodeTrait);
198                        children
199                    }
200                    None => vec![],
201                }
202            }
203            Stmt::EvalExpr(e) => e.get_mut_children(),
204            Stmt::ForIn(_, target, block) => {
205                let mut children = vec![];
206                children.push(&mut **target as &mut dyn NodeTrait);
207                for stmt in block.iter_mut() {
208                    children.push(stmt as &mut dyn NodeTrait)
209                }
210                children
211            }
212            Stmt::Assign(target, value) => {
213                vec![&mut **target, &mut **value]
214            }
215            Stmt::VarDecl(v) => {
216                let mut children = vec![];
217                let default = v.get_mut_default();
218                match default {
219                    Some(default) => {
220                        children.push(default as &mut dyn NodeTrait);
221                        children
222                    }
223                    None => vec![],
224                }
225            }
226            t => {
227                dbg!(t);
228                todo!()
229            }
230        }
231    }
232
233    fn get_extra(&self) -> &HashMap<String, Box<dyn Any>> {
234        todo!()
235    }
236}
237impl StmtNode {
238    pub fn new(stmt: Stmt, pos: Position) -> Self {
239        Self { stmt, pos }
240    }
241
242    pub fn get_stmt(&self) -> &Stmt {
243        &self.stmt
244    }
245
246    pub fn position(&self) -> Position {
247        self.pos.clone()
248    }
249
250    pub fn is_noop(&self) -> bool {
251        self.stmt.is_noop()
252    }
253    pub fn is_fn_call(&self) -> bool {
254        self.stmt.is_fn_call()
255    }
256    pub fn get_fn_call_name(&self) -> Option<String> {
257        match &self.stmt {
258            Stmt::EvalExpr(expr) => match expr.get_expr() {
259                Expr::FnCall(fn_call) => Some(fn_call.name.clone()),
260                _ => None,
261            },
262            _ => None,
263        }
264    }
265    pub fn get_mut_stmt(&mut self) -> &mut Stmt {
266        &mut self.stmt
267    }
268    pub fn set_fn_call_name(&mut self, name: String) {
269        if let Stmt::EvalExpr(expr) = &mut self.stmt {
270            if let Expr::FnCall(ref mut fn_call) = expr.get_expr_mut() {
271                fn_call.name = name;
272            }
273        }
274    }
275    pub fn is_val_decl(&self) -> bool {
276        matches!(&self.stmt, Stmt::ValDecl(_))
277    }
278}