neutralts/bif/
parse_bif_for.rs1#![doc = include_str!("../../doc/bif-for.md")]
2
3use crate::{bif::constants::*, bif::Bif, bif::BifError, utils::extract_blocks};
4
5impl<'a> Bif<'a> {
6 pub(crate) fn parse_bif_for(&mut self) -> Result<(), BifError> {
12 if self.mod_filter || self.mod_negate {
13 return Err(self.bif_error(BIF_ERROR_MODIFIER_NOT_ALLOWED));
14 }
15
16 self.extract_params_code(true);
17
18 if !self.flags.is_empty() {
19 return Err(self.bif_error(BIF_ERROR_FLAGS_NOT_ALLOWED));
20 }
21
22 self.params = self.params.replace("..", " ");
23 let mut parts = self.params.split_whitespace();
24
25 let var_name = match parts.next() {
26 Some(value) => value.to_string(),
27 None => {
28 return Err(self.bif_error(BIF_ERROR_ARGUMENTS_NOT_FOUND));
29 }
30 };
31
32 let from = match parts.next() {
33 Some(value) => match value.parse::<i32>() {
34 Ok(num) => num,
35 Err(_) => {
36 return Err(self.bif_error(BIF_ERROR_ARGUMENT_NOT_NUMBER));
37 }
38 },
39 None => {
40 return Err(self.bif_error(BIF_ERROR_ARGS_FROM_TO_NOT_FOUND));
41 }
42 };
43
44 let to = match parts.next() {
45 Some(value) => match value.parse::<i32>() {
46 Ok(num) => num,
47 Err(_) => {
48 return Err(self.bif_error(BIF_ERROR_ARGUMENT_NOT_NUMBER));
49 }
50 },
51 None => {
52 return Err(self.bif_error(BIF_ERROR_ARGS_TO_NOT_FOUND));
53 }
54 };
55
56 let blocks = match extract_blocks(&self.code) {
57 Ok(b) => b,
58 Err(p) => return Err(self.bif_error(&format!("Unmatched block at position {}", p))),
59 };
60
61 let restore_var = self.get_data(&var_name);
62 if from > to {
63 for i in (to..=from).rev() {
64 self.parse_bif_for_iter(&var_name, &i.to_string(), &blocks);
65 }
66 } else {
67 for i in from..=to {
68 self.parse_bif_for_iter(&var_name, &i.to_string(), &blocks);
69 }
70 };
71 self.set_data(&var_name, &restore_var);
72
73 Ok(())
74 }
75
76 fn parse_bif_for_iter(&mut self, var_name: &str, val: &str, blocks: &Vec<(usize, usize)>) {
77 self.set_data(var_name, val);
78
79 let mut child_inherit = self.inherit.clone();
80 child_inherit.alias = self.alias.clone();
81 if !self.file_path.is_empty() {
82 child_inherit.current_file = self.file_path.clone();
83 }
84 if !self.dir.is_empty() {
85 child_inherit.current_dir = self.dir.clone();
86 }
87
88 if self.mod_scope {
89 self.inherit.create_block_schema(self.shared);
90 }
91
92 let mut block_parser = crate::block_parser::BlockParser::new(self.shared, child_inherit);
93 let code = block_parser.parse_with_blocks(&self.code, blocks, self.only);
94
95 if self.mod_scope {
96 block_parser.update_indir(&self.inherit.indir);
97 }
98
99 self.out += &code;
100 }
101}
102
103#[cfg(test)]
104#[path = "parse_bif_for_tests.rs"]
105mod tests;