1use super::*;
18
19use leo_errors::{ParserError, Result};
20
21const ASSIGN_TOKENS: &[Token] = &[
22 Token::Assign,
23 Token::AddAssign,
24 Token::SubAssign,
25 Token::MulAssign,
26 Token::DivAssign,
27 Token::RemAssign,
28 Token::PowAssign,
29 Token::OrAssign,
30 Token::AndAssign,
31 Token::BitAndAssign,
32 Token::BitOrAssign,
33 Token::BitXorAssign,
34 Token::ShrAssign,
35 Token::ShlAssign,
36];
37
38impl ParserContext<'_> {
39 pub(crate) fn parse_statement(&mut self) -> Result<Statement> {
41 match &self.token.token {
42 Token::Return => Ok(self.parse_return_statement()?.into()),
43 Token::If => Ok(self.parse_conditional_statement()?.into()),
44 Token::For => Ok(self.parse_loop_statement()?.into()),
45 Token::Assert | Token::AssertEq | Token::AssertNeq => Ok(self.parse_assert_statement()?),
46 Token::Let => Ok(self.parse_definition_statement()?.into()),
47 Token::Const => Ok(self.parse_const_declaration_statement()?.into()),
48 Token::LeftCurly => Ok(self.parse_block()?.into()),
49 _ => Ok(self.parse_assign_statement()?),
50 }
51 }
52
53 fn parse_assert_statement(&mut self) -> Result<Statement> {
55 let is_assert = self.check(&Token::Assert);
58 let is_assert_eq = self.check(&Token::AssertEq);
59 let is_assert_neq = self.check(&Token::AssertNeq);
60 let span = self.expect_any(&[Token::Assert, Token::AssertEq, Token::AssertNeq])?;
62 self.expect(&Token::LeftParen)?;
64 let variant = match (is_assert, is_assert_eq, is_assert_neq) {
66 (true, false, false) => AssertVariant::Assert(self.parse_expression()?),
67 (false, true, false) => AssertVariant::AssertEq(self.parse_expression()?, {
68 self.expect(&Token::Comma)?;
69 self.parse_expression()?
70 }),
71 (false, false, true) => AssertVariant::AssertNeq(self.parse_expression()?, {
72 self.expect(&Token::Comma)?;
73 self.parse_expression()?
74 }),
75 _ => unreachable!("The call the `expect_any` ensures that only one of the three tokens is true."),
76 };
77 self.expect(&Token::RightParen)?;
79 self.expect(&Token::Semicolon)?;
81
82 Ok(AssertStatement { variant, span, id: self.node_builder.next_id() }.into())
84 }
85
86 fn parse_assign_statement(&mut self) -> Result<Statement> {
88 let expression = self.parse_expression()?;
89 if self.eat_any(ASSIGN_TOKENS) {
90 let operation = match &self.prev_token.token {
92 Token::Assign => None,
93 Token::AddAssign => Some(BinaryOperation::Add),
94 Token::SubAssign => Some(BinaryOperation::Sub),
95 Token::MulAssign => Some(BinaryOperation::Mul),
96 Token::DivAssign => Some(BinaryOperation::Div),
97 Token::RemAssign => Some(BinaryOperation::Rem),
98 Token::PowAssign => Some(BinaryOperation::Pow),
99 Token::OrAssign => Some(BinaryOperation::Or),
100 Token::AndAssign => Some(BinaryOperation::And),
101 Token::BitAndAssign => Some(BinaryOperation::BitwiseAnd),
102 Token::BitOrAssign => Some(BinaryOperation::BitwiseOr),
103 Token::BitXorAssign => Some(BinaryOperation::Xor),
104 Token::ShrAssign => Some(BinaryOperation::Shr),
105 Token::ShlAssign => Some(BinaryOperation::Shl),
106 _ => panic!("`parse_assign_statement` shouldn't produce this"),
107 };
108
109 let value = self.parse_expression()?;
110 self.expect(&Token::Semicolon)?;
111
112 let span = expression.span() + value.span();
114
115 let mut left = expression.clone();
117 left.set_id(self.node_builder.next_id());
118
119 let value = match operation {
122 None => value,
123 Some(op) => BinaryExpression { left, right: value, op, span, id: self.node_builder.next_id() }.into(),
124 };
125
126 return Ok(AssignStatement { span, place: expression, value, id: self.node_builder.next_id() }.into());
127 }
128
129 let end = self.expect(&Token::Semicolon)?;
130
131 Ok(ExpressionStatement { span: expression.span() + end, expression, id: self.node_builder.next_id() }.into())
132 }
133
134 pub(super) fn parse_block(&mut self) -> Result<Block> {
136 self.parse_list(Delimiter::Brace, None, |p| p.parse_statement().map(Some)).map(|(statements, _, span)| Block {
137 statements,
138 span,
139 id: self.node_builder.next_id(),
140 })
141 }
142
143 fn parse_return_statement(&mut self) -> Result<ReturnStatement> {
145 let start = self.expect(&Token::Return)?;
146
147 let expression = match self.token.token {
148 Token::Semicolon => {
150 Expression::Unit(UnitExpression { span: self.token.span, id: self.node_builder.next_id() })
151 }
152 _ => self.parse_expression()?,
154 };
155 let end = self.expect(&Token::Semicolon)?;
156 let span = start + end;
157 Ok(ReturnStatement { span, expression, id: self.node_builder.next_id() })
158 }
159
160 fn parse_conditional_statement(&mut self) -> Result<ConditionalStatement> {
162 let start = self.expect(&Token::If)?;
163 self.disallow_struct_construction = true;
164 let expr = self.parse_conditional_expression()?;
165 self.disallow_struct_construction = false;
166 let body = self.parse_block()?;
167 let next = if self.eat(&Token::Else) {
168 let s = self.parse_statement()?;
169 if !matches!(s, Statement::Block(_) | Statement::Conditional(_)) {
170 self.emit_err(ParserError::unexpected_statement(&s, "Block or Conditional", s.span()));
171 }
172 Some(Box::new(s))
173 } else {
174 None
175 };
176
177 Ok(ConditionalStatement {
178 span: start + next.as_ref().map(|x| x.span()).unwrap_or(body.span),
179 condition: expr,
180 then: body,
181 otherwise: next,
182 id: self.node_builder.next_id(),
183 })
184 }
185
186 fn parse_loop_statement(&mut self) -> Result<IterationStatement> {
188 let start_span = self.expect(&Token::For)?;
189
190 let ident = self.expect_identifier()?;
192
193 let type_ = if self.eat(&Token::Colon) { Some(self.parse_type()?.0) } else { None };
195 self.expect(&Token::In)?;
196
197 let start = self.parse_expression()?;
199 self.expect(&Token::DotDot)?;
200 self.disallow_struct_construction = true;
201 let stop = self.parse_conditional_expression()?;
202 self.disallow_struct_construction = false;
203
204 let block = self.parse_block()?;
205
206 Ok(IterationStatement {
207 span: start_span + block.span,
208 variable: ident,
209 type_,
210 start,
211 stop,
212 inclusive: false,
213 block,
214 id: self.node_builder.next_id(),
215 })
216 }
217
218 pub(super) fn parse_const_declaration_statement(&mut self) -> Result<ConstDeclaration> {
220 self.expect(&Token::Const)?;
221 let decl_span = self.prev_token.span;
222
223 let (place, type_, _) = self.parse_typed_ident()?;
225
226 self.expect(&Token::Assign)?;
227 let value = self.parse_expression()?;
228 self.expect(&Token::Semicolon)?;
229
230 Ok(ConstDeclaration { span: decl_span + value.span(), place, type_, value, id: self.node_builder.next_id() })
231 }
232
233 fn parse_definition_place(&mut self) -> Result<DefinitionPlace> {
234 if let Some(identifier) = self.eat_identifier() {
235 return Ok(DefinitionPlace::Single(identifier));
236 }
237
238 let (identifiers, _, _) = self.parse_paren_comma_list(|p| {
239 let span = p.token.span;
240
241 let eaten = p.eat_identifier();
242
243 if eaten.is_some() { Ok(eaten) } else { Err(ParserError::expected_identifier(span).into()) }
244 })?;
245
246 Ok(DefinitionPlace::Multiple(identifiers))
247 }
248
249 pub(super) fn parse_definition_statement(&mut self) -> Result<DefinitionStatement> {
251 self.expect(&Token::Let)?;
252 let decl_span = self.prev_token.span;
253
254 let place = self.parse_definition_place()?;
256
257 let type_ = if self.eat(&Token::Colon) { Some(self.parse_type()?.0) } else { None };
259
260 self.expect(&Token::Assign)?;
261 let value = self.parse_expression()?;
262 self.expect(&Token::Semicolon)?;
263
264 Ok(DefinitionStatement { span: decl_span + value.span(), place, type_, value, id: self.node_builder.next_id() })
265 }
266}