use crate::data::primitive::int::PrimitiveInt;
use crate::data::{ast::*, Data, Literal, MessageData, MSG};
use crate::error_format::*;
use crate::interpreter::interpret_scope;
use crate::interpreter::variable_handler::expr_to_literal::expr_to_literal;
use crate::parser::ExitCondition;
use std::sync::mpsc;
pub fn for_loop(
ident: &Identifier,
i: &Option<Identifier>,
expr: &Expr,
block: &Block,
range: &RangeInterval,
mut root: MessageData,
data: &mut Data,
instruction_index: Option<usize>,
sender: &Option<mpsc::Sender<MSG>>,
) -> Result<MessageData, ErrorInfo> {
let literal = expr_to_literal(expr, None, data, &mut root, sender)?;
let array = Literal::get_value::<Vec<Literal>>(
&literal.primitive,
range.start.to_owned(),
ERROR_FOREACH.to_owned(),
)?;
for (value, elem) in array.iter().enumerate() {
data.step_vars
.insert(ident.ident.to_owned(), elem.to_owned());
if let Some(index) = i {
data.step_vars.insert(
index.ident.to_owned(),
PrimitiveInt::get_literal(value as i64, elem.interval.to_owned()),
);
};
root = root + interpret_scope(block, data, instruction_index, sender)?;
if let Some(ExitCondition::Break) = root.exit_condition {
root.exit_condition = None;
break;
} else if root.exit_condition.is_some() {
break;
}
}
data.step_vars.remove(&ident.ident);
if let Some(index) = i {
data.step_vars.remove(&index.ident);
};
Ok(root)
}