MCPcopy Index your code
hub / github.com/endbasic/endbasic / parse_for

Method parse_for

core/src/parser.rs:1251–1318  ·  view source on GitHub ↗

Parses a `FOR` statement.

(&mut self, for_pos: LineCol)

Source from the content-addressed store, hash-verified

1249
1250 /// Parses a `FOR` statement.
1251 fn parse_for(&mut self, for_pos: LineCol) -> Result<Statement> {
1252 let token_span = self.lexer.read()?;
1253 let iterator = match token_span.token {
1254 Token::Symbol(iterator) => match iterator.ref_type {
1255 None | Some(ExprType::Double) | Some(ExprType::Integer) => iterator,
1256 _ => {
1257 return Err(Error::Bad(
1258 token_span.pos,
1259 "Iterator name in FOR statement must be a numeric reference".to_owned(),
1260 ));
1261 }
1262 },
1263 _ => {
1264 return Err(Error::Bad(
1265 token_span.pos,
1266 "No iterator name in FOR statement".to_owned(),
1267 ));
1268 }
1269 };
1270 let iterator_pos = token_span.pos;
1271
1272 self.expect_and_consume(Token::Equal, "No equal sign in FOR statement")?;
1273 let start = self.parse_required_expr("No start expression in FOR statement")?;
1274
1275 let to_span = self.expect_and_consume(Token::To, "No TO in FOR statement")?;
1276 let end = self.parse_required_expr("No end expression in FOR statement")?;
1277
1278 let (step, step_sign, iter_double) = self.parse_step(for_pos)?;
1279 let end_condition = match step_sign {
1280 Ordering::Greater => Expr::LessEqual(Box::from(BinaryOpSpan {
1281 lhs: Expr::Symbol(SymbolSpan { vref: iterator.clone(), pos: iterator_pos }),
1282 rhs: end,
1283 pos: to_span.pos,
1284 })),
1285 Ordering::Less => Expr::GreaterEqual(Box::from(BinaryOpSpan {
1286 lhs: Expr::Symbol(SymbolSpan { vref: iterator.clone(), pos: iterator_pos }),
1287 rhs: end,
1288 pos: to_span.pos,
1289 })),
1290 Ordering::Equal => {
1291 return Err(Error::Bad(
1292 step.start_pos(),
1293 "Infinite FOR loop; STEP cannot be 0".to_owned(),
1294 ));
1295 }
1296 };
1297
1298 let next_value = Expr::Add(Box::from(BinaryOpSpan {
1299 lhs: Expr::Symbol(SymbolSpan { vref: iterator.clone(), pos: iterator_pos }),
1300 rhs: step,
1301 pos: to_span.pos,
1302 }));
1303
1304 self.expect_and_consume(Token::Eol, "Expecting newline after FOR")?;
1305
1306 let stmts = self.parse_until(Token::Next)?;
1307 self.expect_and_consume_with_pos(Token::Next, for_pos, "FOR without NEXT")?;
1308

Callers 1

parse_oneMethod · 0.80

Calls 7

expect_and_consumeMethod · 0.80
parse_required_exprMethod · 0.80
parse_stepMethod · 0.80
start_posMethod · 0.80
parse_untilMethod · 0.80
readMethod · 0.45

Tested by

no test coverage detected