neutralts/bif/
parse_bif_for.rs

1#![doc = include_str!("../../doc/bif-for.md")]
2
3use crate::{bif::constants::*, bif::Bif, bif::BifError};
4
5impl<'a> Bif<'a> {
6    /*
7       {:for; varname 1 10 >>
8           var is:{:;varname:}
9       :}
10    */
11    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 range = if from > to {
57            (to..=from).rev().collect::<Vec<i32>>()
58        } else {
59            (from..=to).collect::<Vec<i32>>()
60        };
61
62        let restore_var = self.get_data(&var_name);
63        for i in range {
64            self.set_data(&var_name, &i.to_string());
65            self.out += &new_child_parse!(self, &self.code, self.mod_scope);
66        }
67        self.set_data(&var_name, &restore_var);
68
69        Ok(())
70    }
71}
72
73#[cfg(test)]
74#[path = "parse_bif_for_tests.rs"]
75mod tests;