devalang_wasm/engine/audio/interpreter/statements/
loop_.rs1use crate::engine::audio::interpreter::driver::AudioInterpreter;
2use crate::language::syntax::ast::{Statement, Value};
3use anyhow::Result;
5
6impl AudioInterpreter {
7 pub fn execute_loop(&mut self, count: &Value, body: &[Statement]) -> Result<()> {
9 let loop_count = match count {
11 Value::Number(n) => *n as usize,
12 Value::Identifier(ident) => {
13 if let Some(Value::Number(n)) = self.variables.get(ident) {
15 *n as usize
16 } else {
17 anyhow::bail!("❌ Loop iterator '{}' must be a number", ident);
18 }
19 }
20 _ => {
21 anyhow::bail!("❌ Loop iterator must be a number, found: {:?}", count);
22 }
23 };
24
25 println!("🔁 Loop: {} iterations", loop_count);
26
27 for iteration in 0..loop_count {
29 if iteration > 0 && iteration % 10 == 0 {
30 println!(" └─ Iteration {}/{}", iteration, loop_count);
31 }
32 self.collect_events(body)?;
33 }
34
35 Ok(())
36 }
37
38 pub fn execute_for(
40 &mut self,
41 variable: &str,
42 iterable: &Value,
43 body: &[Statement],
44 ) -> Result<()> {
45 let items = match iterable {
47 Value::Array(arr) => arr.clone(),
48 Value::Identifier(ident) => {
49 if let Some(Value::Array(arr)) = self.variables.get(ident) {
51 arr.clone()
52 } else {
53 anyhow::bail!("❌ For iterable '{}' must be an array", ident);
54 }
55 }
56 Value::Range { start, end } => {
57 let start_val = match start.as_ref() {
59 Value::Number(n) => *n as i32,
60 _ => anyhow::bail!("❌ Range start must be a number"),
61 };
62 let end_val = match end.as_ref() {
63 Value::Number(n) => *n as i32,
64 _ => anyhow::bail!("❌ Range end must be a number"),
65 };
66
67 (start_val..=end_val)
69 .map(|i| Value::Number(i as f32))
70 .collect()
71 }
72 _ => {
73 anyhow::bail!(
74 "❌ For iterable must be an array or range, found: {:?}",
75 iterable
76 );
77 }
78 };
79
80 println!("🔄 For: {} in {} items", variable, items.len());
81
82 for (idx, item) in items.iter().enumerate() {
84 let old_value = self.variables.insert(variable.to_string(), item.clone());
86
87 if idx < 5 || (idx + 1) == items.len() {
88 println!(" └─ {} = {:?}", variable, item);
90 } else if idx == 5 {
91 println!(" └─ ... ({} more items)", items.len() - 6);
92 }
93
94 self.collect_events(body)?;
96
97 match old_value {
99 Some(val) => self.variables.insert(variable.to_string(), val),
100 None => self.variables.remove(variable),
101 };
102 }
103
104 Ok(())
105 }
106}