i_slint_compiler/parser/
statements.rs1use crate::parser::r#type::parse_type;
5
6use super::element::parse_code_block;
7use super::expressions::parse_expression;
8use super::prelude::*;
9
10#[cfg_attr(test, parser_test)]
11pub fn parse_statement(p: &mut impl Parser) -> bool {
24 if p.nth(0).kind() == SyntaxKind::RBrace {
25 return false;
26 }
27 if p.test(SyntaxKind::Semicolon) {
28 return true;
29 }
30 let checkpoint = p.checkpoint();
31
32 if p.peek().as_str() == "if"
33 && !matches!(
34 p.nth(1).kind(),
35 SyntaxKind::Dot
36 | SyntaxKind::Comma
37 | SyntaxKind::Semicolon
38 | SyntaxKind::RBrace
39 | SyntaxKind::RBracket
40 | SyntaxKind::RParent
41 )
42 {
43 let mut p = p.start_node(SyntaxKind::Expression);
44 parse_if_statement(&mut *p);
45 return true;
46 }
47
48 if p.peek().as_str() == "return" {
49 let mut p = p.start_node_at(checkpoint, SyntaxKind::ReturnStatement);
50 p.expect(SyntaxKind::Identifier); if !p.test(SyntaxKind::Semicolon) {
52 parse_expression(&mut *p);
53 p.expect(SyntaxKind::Semicolon);
54 }
55 return true;
56 }
57
58 if p.peek().as_str() == "let" && p.nth(1).kind() == SyntaxKind::Identifier {
59 parse_let_statement(p);
60 return true;
61 }
62
63 parse_expression(p);
64 if matches!(
65 p.nth(0).kind(),
66 SyntaxKind::MinusEqual
67 | SyntaxKind::PlusEqual
68 | SyntaxKind::StarEqual
69 | SyntaxKind::DivEqual
70 | SyntaxKind::Equal
71 ) {
72 let mut p = p.start_node_at(checkpoint.clone(), SyntaxKind::Expression);
73 let mut p = p.start_node_at(checkpoint, SyntaxKind::SelfAssignment);
74 p.consume();
75 parse_expression(&mut *p);
76 }
77 p.test(SyntaxKind::Semicolon)
78}
79
80#[cfg_attr(test, parser_test)]
81fn parse_let_statement(p: &mut impl Parser) {
87 let mut p = p.start_node(SyntaxKind::LetStatement);
88 debug_assert_eq!(p.peek().as_str(), "let");
89 p.expect(SyntaxKind::Identifier); {
91 let mut p = p.start_node(SyntaxKind::DeclaredIdentifier);
92 p.expect(SyntaxKind::Identifier);
93 }
94
95 if p.test(SyntaxKind::Colon) {
96 parse_type(&mut *p);
97 }
98
99 p.expect(SyntaxKind::Equal);
100 parse_expression(&mut *p);
101 p.expect(SyntaxKind::Semicolon);
102}
103
104#[cfg_attr(test, parser_test)]
105fn parse_if_statement(p: &mut impl Parser) {
112 let mut p = p.start_node(SyntaxKind::ConditionalExpression);
113 debug_assert_eq!(p.peek().as_str(), "if");
114 p.expect(SyntaxKind::Identifier);
115 parse_expression(&mut *p);
116 {
117 let mut p = p.start_node(SyntaxKind::Expression);
118 parse_code_block(&mut *p);
119 }
120 if p.peek().as_str() == "else" {
121 p.expect(SyntaxKind::Identifier);
122 let mut p = p.start_node(SyntaxKind::Expression);
123 if p.peek().as_str() == "if" {
124 parse_if_statement(&mut *p)
125 } else {
126 parse_code_block(&mut *p);
127 }
128 } else {
129 let mut p = p.start_node(SyntaxKind::Expression);
132 let _ = p.start_node(SyntaxKind::CodeBlock);
133 }
134}