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