Parses a builtin call (things of the form `INPUT a`).
(
&mut self,
vref: VarRef,
vref_pos: LineCol,
mut first: Option<Expr>,
)
| 350 | |
| 351 | /// Parses a builtin call (things of the form `INPUT a`). |
| 352 | fn parse_builtin_call( |
| 353 | &mut self, |
| 354 | vref: VarRef, |
| 355 | vref_pos: LineCol, |
| 356 | mut first: Option<Expr>, |
| 357 | ) -> Result<Statement> { |
| 358 | let mut name = vref_to_unannotated_string(vref, vref_pos)?; |
| 359 | name.make_ascii_uppercase(); |
| 360 | |
| 361 | let mut args = vec![]; |
| 362 | loop { |
| 363 | let expr = self.parse_expr(first.take())?; |
| 364 | |
| 365 | let peeked = self.lexer.peek()?; |
| 366 | match peeked.token { |
| 367 | Token::Eof | Token::Eol | Token::Else => { |
| 368 | if expr.is_some() || !args.is_empty() { |
| 369 | args.push(ArgSpan { expr, sep: ArgSep::End, sep_pos: peeked.pos }); |
| 370 | } |
| 371 | break; |
| 372 | } |
| 373 | Token::Semicolon => { |
| 374 | let peeked = self.lexer.consume_peeked(); |
| 375 | args.push(ArgSpan { expr, sep: ArgSep::Short, sep_pos: peeked.pos }); |
| 376 | } |
| 377 | Token::Comma => { |
| 378 | let peeked = self.lexer.consume_peeked(); |
| 379 | args.push(ArgSpan { expr, sep: ArgSep::Long, sep_pos: peeked.pos }); |
| 380 | } |
| 381 | Token::As => { |
| 382 | let peeked = self.lexer.consume_peeked(); |
| 383 | args.push(ArgSpan { expr, sep: ArgSep::As, sep_pos: peeked.pos }); |
| 384 | } |
| 385 | _ => { |
| 386 | return Err(Error::Bad( |
| 387 | peeked.pos, |
| 388 | "Expected comma, semicolon, or end of statement".to_owned(), |
| 389 | )); |
| 390 | } |
| 391 | } |
| 392 | } |
| 393 | Ok(Statement::Call(CallSpan { vref: VarRef::new(name, None), vref_pos, args })) |
| 394 | } |
| 395 | |
| 396 | /// Starts processing either an array reference or a builtin call and disambiguates between the |
| 397 | /// two. |
no test coverage detected