Parse block expression. The different between block_expr() and block() are: - block_expr() will treat the last line as an expression if it not ends with semicolon. - block_expr() nornamlly wrapped in Expr::Block while block() wraped in Stmt::Block
(&mut self)
| 1240 | // - block_expr() will treat the last line as an expression if it not ends with semicolon. |
| 1241 | // - block_expr() nornamlly wrapped in Expr::Block while block() wraped in Stmt::Block |
| 1242 | fn block_expr(&mut self) -> Vec<Stmt<'gc>> { |
| 1243 | let mut statements = Vec::new(); |
| 1244 | |
| 1245 | while !self.check(TokenType::CloseBrace) && !self.is_at_end() { |
| 1246 | // Check if we're looking at a potential expression |
| 1247 | if self.current.is_expr_start() { |
| 1248 | // Parse as expression |
| 1249 | if let Some(expr) = self.expression() { |
| 1250 | if self.check(TokenType::CloseBrace) { |
| 1251 | // It's a tail expression - create special BlockReturn statement |
| 1252 | // This is different from Return in that it only returns from the block |
| 1253 | statements.push(Stmt::BlockReturn { |
| 1254 | value: expr, |
| 1255 | line: self.previous.line, |
| 1256 | }); |
| 1257 | break; |
| 1258 | } else { |
| 1259 | // Not a tail expression, must have semicolon |
| 1260 | if self.check(TokenType::Semicolon) { |
| 1261 | self.advance(); |
| 1262 | } else { |
| 1263 | self.error("Expect ';' after expression."); |
| 1264 | } |
| 1265 | |
| 1266 | statements.push(Stmt::Expression { |
| 1267 | expression: expr, |
| 1268 | line: self.previous.line, |
| 1269 | }); |
| 1270 | } |
| 1271 | } |
| 1272 | } else if let Some(declaration) = self.declaration() { |
| 1273 | statements.push(declaration); |
| 1274 | } |
| 1275 | } |
| 1276 | |
| 1277 | self.consume(TokenType::CloseBrace, "Expect '}' after block."); |
| 1278 | statements |
| 1279 | } |
| 1280 | |
| 1281 | fn expression(&mut self) -> Option<Expr<'gc>> { |
| 1282 | self.parse_precedence(Precedence::Assignment) |
no test coverage detected