pipeline_script/parser/
stmt.rs1use crate::ast::declaration::VariableDeclaration;
2use crate::ast::expr::{Expr, ExprNode};
3use crate::ast::stmt::{IfBranchStmt, IfStmt, MatchBranch, Stmt, StmtNode};
4use crate::context::Context;
5use crate::lexer::position::Position;
6use crate::lexer::token::Token;
7use crate::parser::Parser;
8
9impl Parser {
10 pub fn parse_match_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
11 let pos = self.parse_keyword("match")?;
13
14 self.parse_special_token(Token::BraceLeft)?;
16 let expr = self.parse_expr(ctx)?;
17 self.parse_special_token(Token::BraceRight)?;
18
19 self.parse_special_token(Token::ParenLeft)?;
21
22 let mut branches = vec![];
24 loop {
25 let (token, _) = self.token_stream.peek();
26 match token {
27 Token::ParenRight => {
28 self.parse_special_token(Token::ParenRight)?;
29 break;
30 }
31 _ => {
32 let pattern = self.parse_expr(ctx)?;
34
35 self.parse_special_token(Token::Arrow)?;
37
38 let mut body = vec![];
40
41 let (token, _) = self.token_stream.peek();
43 if token == Token::ParenLeft {
44 body = self.parse_block(ctx)?;
45 } else {
46 let stmt = self.parse_stmt(ctx)?;
48 body.push(stmt);
49 }
50
51 branches.push(MatchBranch::new(pattern, body));
53
54 if self.try_parse_token(Token::Comma) {
56 continue;
57 }
58 }
59 }
60 }
61
62 let match_stmt = Stmt::Match(Box::new(expr), branches);
64 Ok(StmtNode::new(match_stmt, pos))
65 }
66
67 pub fn parse_if_let_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
69 let pos = self.parse_keyword("if")?;
71
72 self.parse_keyword("let")?;
74
75 self.parse_special_token(Token::BraceLeft)?;
77
78 let pattern = self.parse_expr(ctx)?;
80
81 self.parse_special_token(Token::Assign)?;
83
84 let expr = self.parse_expr(ctx)?;
86
87 self.parse_special_token(Token::BraceRight)?;
89
90 let body = self.parse_block(ctx)?;
92
93 let mut else_body = None;
95 if self.try_parse_token(Token::Keyword("else".to_string())) {
96 else_body = Some(self.parse_block(ctx)?);
97 }
98
99 let if_let_stmt = Stmt::IfLet(Box::new(pattern), Box::new(expr), body, else_body);
101 Ok(StmtNode::new(if_let_stmt, pos))
102 }
103 pub fn parse_if_const_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
104 let pos = self.parse_keyword("if")?;
106 let s = self.val_keyword.clone();
107 self.parse_keyword(s.as_str())?;
109
110 self.parse_special_token(Token::BraceLeft)?;
112
113 let pattern = self.parse_expr(ctx)?;
115
116 self.parse_special_token(Token::Assign)?;
118
119 let expr = self.parse_expr(ctx)?;
121
122 self.parse_special_token(Token::BraceRight)?;
124
125 let body = self.parse_block(ctx)?;
127
128 let mut else_body = None;
130 if self.try_parse_token(Token::Keyword("else".to_string())) {
131 else_body = Some(self.parse_block(ctx)?);
132 }
133
134 let if_let_stmt = Stmt::IfConst(Box::new(pattern), Box::new(expr), body, else_body);
136 Ok(StmtNode::new(if_let_stmt, pos))
137 }
138 pub fn parse_var_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
139 let keyword = self.var_keyword.clone();
140 self.parse_decl_stmt(ctx, &keyword, |vd, _| Stmt::VarDecl(vd))
141 }
142
143 pub fn parse_val_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
144 let keyword = self.val_keyword.clone();
145 self.parse_decl_stmt(ctx, &keyword, |vd, _| Stmt::ValDecl(vd))
146 }
147 pub(crate) fn parse_if_branch(
148 &mut self,
149 ctx: &Context,
150 ) -> crate::core::result::Result<(IfBranchStmt, Position)> {
151 let mut p0 = self.parse_keyword("if")?;
152 let p1 = self.parse_special_token(Token::BraceLeft)?;
153 let e = self.parse_expr(ctx).unwrap();
154 let p2 = e.position();
155 let p3 = self.parse_special_token(Token::BraceRight)?;
156 let block = self.parse_block(ctx)?;
157 for b in block.iter() {
158 p0 += b.position();
159 }
160 let branch = IfBranchStmt::new(e, block);
161 Ok((branch, p0 + p1 + p2 + p3))
162 }
163 fn parse_decl_stmt(
164 &mut self,
165 ctx: &Context,
166 keyword: &str,
167 builder: fn(VariableDeclaration, ExprNode) -> Stmt,
168 ) -> crate::core::result::Result<StmtNode> {
169 let p0 = self.parse_keyword(keyword)?;
170 let (name, mut p1) = self.parse_identifier()?;
171 let mut vd = VariableDeclaration::new(name);
172
173 if let Token::Colon = self.token_stream.peek().0 {
175 p1 += self.parse_special_token(Token::Colon)?;
176 let ty = self.parse_type()?;
177 vd = vd.with_type(ty);
178 }
179
180 let p4 = self.parse_special_token(Token::Assign)?;
182 let expr = self.parse_expr(ctx)?;
183 let p5 = expr.position();
184
185 Ok(StmtNode::new(
186 builder(vd.with_default(expr.clone()), expr),
187 p0 + p1 + p4 + p5,
188 ))
189 }
190 pub(crate) fn parse_return_stmt(
191 &mut self,
192 ctx: &Context,
193 ) -> crate::core::result::Result<StmtNode> {
194 let p0 = self.parse_keyword("return")?;
195 if self.token_stream.peek().0 == Token::ParenRight {
196 return Ok(StmtNode::new(Stmt::Return(Box::new(Expr::None.into())), p0));
197 }
198 let expr = self.parse_expr(ctx).expect("parse return stmt error");
199 Ok(StmtNode::new(Stmt::Return(Box::new(expr)), p0))
200 }
201 pub fn parse_while_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
202 let mut p0 = self.parse_keyword("while")?;
203 let p1 = self.parse_special_token(Token::BraceLeft)?;
204 let expr = self.parse_expr(ctx)?;
205 let p2 = expr.position();
206 let p3 = self.parse_special_token(Token::BraceRight)?;
207 let block = self.parse_block(ctx)?;
208 for s in block.iter() {
209 p0 += s.position();
210 }
211 Ok(StmtNode::new(
212 Stmt::While(Box::new(expr), block),
213 p0 + p1 + p2 + p3,
214 ))
215 }
216 pub fn parse_if_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
217 let mut branches = vec![];
218 let mut else_body = None;
219 let (b, pos) = self.parse_if_branch(ctx).unwrap();
220 branches.push(b);
221
222 loop {
223 let (peek, _) = self.token_stream.peek();
224 match peek.clone() {
225 Token::Keyword(k) if k == "else" => {
226 self.token_stream.next_token();
227 let (peek0, _) = self.token_stream.peek();
228 if let Token::ParenLeft = peek0 {
229 let blocks = self.parse_block(ctx)?;
230 else_body = Some(blocks);
231 break;
232 }
233 let (b0, _) = self.parse_if_branch(ctx)?;
234 branches.push(b0);
235 }
236 _ => break,
237 }
238 }
239 Ok(StmtNode::new(
240 Stmt::If(Box::new(IfStmt::new(branches, else_body))),
241 pos,
242 ))
243 }
244 pub fn parse_for_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
245 self.parse_keyword("for")?;
246 self.parse_special_token(Token::BraceLeft)?;
247 let (var_name, _) = self.parse_identifier()?;
248 let _ = self.parse_keyword("in");
249 let e0 = self.parse_expr(ctx)?;
250 self.parse_special_token(Token::BraceRight)?;
251 let body = self.parse_block(ctx)?;
252 Ok(StmtNode::new(
253 Stmt::ForIn(var_name, Box::new(e0), body),
254 Position::none(),
255 ))
256 }
257 pub(crate) fn parse_continue_stmt(&mut self) -> crate::core::result::Result<StmtNode> {
258 todo!()
259 }
260 pub(crate) fn parse_break_stmt(&mut self) -> crate::core::result::Result<StmtNode> {
261 self.parse_keyword("break")?;
262 Ok(StmtNode::new(Stmt::Break, Position::none()))
263 }
264 pub fn parse_stmt(&mut self, ctx: &Context) -> crate::core::result::Result<StmtNode> {
265 loop {
266 let (token, _) = self.token_stream.peek();
267 return Ok(match token {
268 Token::Keyword(k) => match k.as_str() {
269 t if t == self.var_keyword => self.parse_var_stmt(ctx).unwrap(),
270 t if t == self.val_keyword => self.parse_val_stmt(ctx).unwrap(),
271 "while" => self.parse_while_stmt(ctx).unwrap(),
272 "for" => self.parse_for_stmt(ctx).unwrap(),
273 "return" => self.parse_return_stmt(ctx).unwrap(),
274 "break" => self.parse_break_stmt()?,
275 "continue" => self.parse_continue_stmt()?,
276 "struct" => {
277 self.parse_struct(ctx)?;
278 continue;
279 }
280 "enum" => {
281 self.parse_enum(ctx)?;
282 continue;
283 }
284 "trait" => {
285 self.parse_trait();
286 continue;
287 }
288 "extern" => {
289 self.parse_extern_function_declaration(ctx).unwrap();
290 continue;
291 }
292 "module" => {
293 self.parse_module(ctx)?;
294 continue;
295 }
296 "match" => {
297 return self.parse_match_stmt(ctx);
298 }
299 "if" => {
300 let (next_token, _) = self.token_stream.peek_nth(1);
302 if next_token.is_keyword("let") {
303 return self.parse_if_let_stmt(ctx);
304 } else if next_token.is_keyword("const") {
305 return self.parse_if_const_stmt(ctx);
306 } else {
307 return self.parse_if_stmt(ctx);
308 }
309 }
310 t => {
311 if t == self.function_keyword {
312 self.parse_function(ctx).unwrap();
313 continue;
314 }
315 dbg!(t);
316 todo!()
317 }
318 },
319 Token::Eof | Token::ParenRight => StmtNode::new(Stmt::Noop, Position::none()),
320 _ => {
321 let e0 = self.parse_expr(ctx)?;
322 let p0 = e0.position();
323 let (peek, p1) = self.token_stream.peek();
324 if let Token::Assign = peek {
325 let p0 = self.parse_special_token(Token::Assign)?;
326 let e1 = self.parse_expr(ctx)?;
327 let p2 = e1.position();
328 return Ok(StmtNode::new(
329 Stmt::Assign(Box::new(e0), Box::new(e1)),
330 p0 + p1 + p2,
331 ));
332 }
333 return Ok(StmtNode::new(Stmt::EvalExpr(Box::new(e0)), p0));
334 }
335 });
336 }
337 }
338}