devalang_core/core/parser/handler/
loop_.rs1use crate::core::{
2 lexer::{ token::TokenKind },
3 parser::{ statement::{ Statement, StatementKind }, driver::Parser },
4 shared::value::Value,
5 store::global::GlobalStore,
6};
7
8pub fn parse_loop_token(parser: &mut Parser, global_store: &mut GlobalStore) -> Statement {
9 parser.advance(); let Some(loop_token) = parser.previous_clone() else {
11 return Statement::unknown();
12 };
13
14 let Some(next_token) = parser.peek_clone() else {
20 return Statement::error(loop_token, "Expected iterator after loop/for".to_string());
21 };
22
23 let mut foreach_ident: Option<String> = None;
25 if let TokenKind::Identifier = next_token.kind {
26 let name = next_token.lexeme.clone();
29 if let Some(t2) = parser.peek_nth(1) {
31 if t2.kind == TokenKind::Identifier && t2.lexeme == "in" {
32 foreach_ident = Some(name);
34 parser.advance();
36 parser.advance();
37 }
38 }
39 }
40
41 if let Some(var_name) = foreach_ident {
42 let array_val = if let Some(v) = parser.parse_array_value() { v } else {
44 return Statement::error(loop_token, "Expected array literal after 'in'".to_string());
45 };
46
47 if !parser.match_token(TokenKind::Colon) {
49 return Statement::error(loop_token, "Expected ':' after foreach header".to_string());
50 }
51
52 let tokens = parser.collect_until(|t| t.kind == TokenKind::Dedent || t.kind == TokenKind::EOF);
53 let loop_body = parser.parse_block(tokens.clone(), global_store);
54 if let Some(token) = parser.peek() { if token.kind == TokenKind::Dedent { parser.advance(); } }
55
56 let mut value_map = std::collections::HashMap::new();
57 value_map.insert("foreach".to_string(), Value::Identifier(var_name));
58 value_map.insert("array".to_string(), array_val);
59 value_map.insert("body".to_string(), Value::Block(loop_body.clone()));
60
61 return Statement { kind: StatementKind::Loop, value: Value::Map(value_map), indent: loop_token.indent, line: loop_token.line, column: loop_token.column };
62 }
63
64 let Some(iterator_token) = parser.peek_clone() else {
66 return Statement::error(loop_token, "Expected number or identifier after 'loop'".to_string());
67 };
68
69 let iterator_value = match iterator_token.kind {
70 TokenKind::Number => { let val = iterator_token.lexeme.parse::<f32>().unwrap_or(1.0); parser.advance(); Value::Number(val) }
71 TokenKind::Identifier => { let val = iterator_token.lexeme.clone(); parser.advance(); Value::Identifier(val) }
72 _ => { return Statement::error(iterator_token.clone(), "Expected a number or identifier as loop count".to_string()); }
73 };
74
75 if !parser.match_token(TokenKind::Colon) {
76 let message = format!("Expected ':' after loop count, got {:?}", parser.peek_kind());
77 return Statement::error(loop_token.clone(), message);
78 }
79
80 let tokens = parser.collect_until(|t| t.kind == TokenKind::Dedent || t.kind == TokenKind::EOF);
81 let loop_body = parser.parse_block(tokens.clone(), global_store);
82 if let Some(token) = parser.peek() { if token.kind == TokenKind::Dedent { parser.advance(); } }
83
84 let mut value_map = std::collections::HashMap::new();
85 value_map.insert("iterator".to_string(), iterator_value);
86 value_map.insert("body".to_string(), Value::Block(loop_body.clone()));
87
88 Statement { kind: StatementKind::Loop, value: Value::Map(value_map), indent: loop_token.indent, line: loop_token.line, column: loop_token.column }
89}