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 IndexAssign(Box<ExprNode>, Box<ExprNode>, Box<ExprNode>),
29 Break,
30 Continue,
31 Import(String),
32 Match(Box<ExprNode>, Vec<MatchBranch>),
34 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#[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}