@devaloop/devalang 0.0.1-alpha.15 → 0.0.1-alpha.16-hotfix.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/.devalang +2 -0
  2. package/.github/workflows/ci.yml +92 -0
  3. package/Cargo.toml +60 -58
  4. package/README.md +1 -1
  5. package/docs/CHANGELOG.md +34 -1
  6. package/docs/CONTRIBUTING.md +101 -1
  7. package/docs/ROADMAP.md +1 -1
  8. package/docs/TODO.md +1 -1
  9. package/examples/automation.deva +1 -3
  10. package/examples/bank.deva +4 -4
  11. package/examples/events.deva +12 -0
  12. package/examples/function.deva +4 -4
  13. package/examples/index.deva +3 -5
  14. package/examples/loop.deva +5 -11
  15. package/examples/pattern.deva +8 -0
  16. package/examples/plugin.deva +12 -11
  17. package/examples/variables.deva +1 -1
  18. package/out-tsc/bin/index.js +51 -7
  19. package/out-tsc/index.js +3 -1
  20. package/out-tsc/scripts/postbuild.js +9 -10
  21. package/out-tsc/scripts/postinstall.js +49 -0
  22. package/package.json +12 -4
  23. package/project-version.json +3 -3
  24. package/rust/cli/bank.rs +462 -455
  25. package/rust/cli/build.rs +252 -199
  26. package/rust/cli/check.rs +221 -180
  27. package/rust/cli/driver.rs +297 -292
  28. package/rust/cli/generator.rs +1 -0
  29. package/rust/cli/init.rs +87 -79
  30. package/rust/cli/install.rs +35 -32
  31. package/rust/cli/login.rs +127 -134
  32. package/rust/cli/mod.rs +13 -11
  33. package/rust/cli/play.rs +1123 -218
  34. package/rust/cli/telemetry.rs +19 -0
  35. package/rust/cli/template.rs +69 -57
  36. package/rust/cli/update.rs +6 -4
  37. package/rust/common/api.rs +5 -5
  38. package/rust/common/mod.rs +3 -3
  39. package/rust/config/driver.rs +118 -94
  40. package/rust/config/loader.rs +165 -156
  41. package/rust/config/mod.rs +4 -2
  42. package/rust/config/settings.rs +91 -0
  43. package/rust/config/stats.rs +257 -0
  44. package/rust/core/audio/engine.rs +696 -659
  45. package/rust/core/audio/evaluator.rs +263 -132
  46. package/rust/core/audio/interpreter/arrow_call.rs +198 -187
  47. package/rust/core/audio/interpreter/call.rs +98 -95
  48. package/rust/core/audio/interpreter/condition.rs +70 -71
  49. package/rust/core/audio/interpreter/driver.rs +487 -231
  50. package/rust/core/audio/interpreter/function.rs +26 -21
  51. package/rust/core/audio/interpreter/let_.rs +38 -26
  52. package/rust/core/audio/interpreter/load.rs +18 -18
  53. package/rust/core/audio/interpreter/loop_.rs +113 -106
  54. package/rust/core/audio/interpreter/mod.rs +14 -14
  55. package/rust/core/audio/interpreter/sleep.rs +27 -28
  56. package/rust/core/audio/interpreter/spawn.rs +105 -102
  57. package/rust/core/audio/interpreter/tempo.rs +19 -16
  58. package/rust/core/audio/interpreter/trigger.rs +239 -210
  59. package/rust/core/audio/loader/mod.rs +1 -1
  60. package/rust/core/audio/loader/trigger.rs +100 -94
  61. package/rust/core/audio/mod.rs +7 -7
  62. package/rust/core/audio/player.rs +64 -64
  63. package/rust/core/audio/renderer.rs +56 -53
  64. package/rust/core/audio/special/easing.rs +189 -120
  65. package/rust/core/audio/special/env.rs +43 -41
  66. package/rust/core/audio/special/math.rs +102 -92
  67. package/rust/core/audio/special/mod.rs +9 -9
  68. package/rust/core/audio/special/modulator.rs +143 -120
  69. package/rust/core/builder/mod.rs +80 -85
  70. package/rust/core/debugger/lexer.rs +27 -27
  71. package/rust/core/debugger/mod.rs +24 -23
  72. package/rust/core/debugger/module.rs +55 -47
  73. package/rust/core/debugger/preprocessor.rs +27 -27
  74. package/rust/core/debugger/store.rs +40 -39
  75. package/rust/core/error/mod.rs +80 -69
  76. package/rust/core/lexer/handler/arrow.rs +82 -82
  77. package/rust/core/lexer/handler/at.rs +21 -21
  78. package/rust/core/lexer/handler/brace.rs +41 -41
  79. package/rust/core/lexer/handler/colon.rs +21 -21
  80. package/rust/core/lexer/handler/comment.rs +30 -30
  81. package/rust/core/lexer/handler/dot.rs +21 -21
  82. package/rust/core/lexer/handler/driver.rs +337 -292
  83. package/rust/core/lexer/handler/identifier.rs +46 -43
  84. package/rust/core/lexer/handler/indent.rs +66 -66
  85. package/rust/core/lexer/handler/mod.rs +16 -16
  86. package/rust/core/lexer/handler/newline.rs +23 -23
  87. package/rust/core/lexer/handler/number.rs +31 -31
  88. package/rust/core/lexer/handler/operator.rs +46 -46
  89. package/rust/core/lexer/handler/parenthesis.rs +41 -41
  90. package/rust/core/lexer/handler/slash.rs +21 -21
  91. package/rust/core/lexer/handler/string.rs +63 -63
  92. package/rust/core/lexer/mod.rs +54 -51
  93. package/rust/core/lexer/token.rs +97 -94
  94. package/rust/core/mod.rs +11 -11
  95. package/rust/core/parser/driver.rs +513 -490
  96. package/rust/core/parser/handler/arrow_call.rs +233 -227
  97. package/rust/core/parser/handler/at.rs +245 -162
  98. package/rust/core/parser/handler/bank.rs +94 -69
  99. package/rust/core/parser/handler/condition.rs +80 -74
  100. package/rust/core/parser/handler/dot.rs +143 -135
  101. package/rust/core/parser/handler/identifier/automate.rs +257 -194
  102. package/rust/core/parser/handler/identifier/call.rs +91 -88
  103. package/rust/core/parser/handler/identifier/emit.rs +66 -0
  104. package/rust/core/parser/handler/identifier/function.rs +100 -91
  105. package/rust/core/parser/handler/identifier/group.rs +85 -75
  106. package/rust/core/parser/handler/identifier/let_.rs +158 -143
  107. package/rust/core/parser/handler/identifier/mod.rs +54 -56
  108. package/rust/core/parser/handler/identifier/on.rs +98 -0
  109. package/rust/core/parser/handler/identifier/print.rs +52 -29
  110. package/rust/core/parser/handler/identifier/sleep.rs +36 -33
  111. package/rust/core/parser/handler/identifier/spawn.rs +91 -88
  112. package/rust/core/parser/handler/identifier/synth.rs +65 -63
  113. package/rust/core/parser/handler/loop_.rs +170 -89
  114. package/rust/core/parser/handler/mod.rs +8 -8
  115. package/rust/core/parser/handler/tempo.rs +53 -47
  116. package/rust/core/parser/mod.rs +4 -4
  117. package/rust/core/parser/statement.rs +142 -113
  118. package/rust/core/plugin/loader.rs +123 -48
  119. package/rust/core/plugin/mod.rs +2 -1
  120. package/rust/core/plugin/runner.rs +296 -0
  121. package/rust/core/preprocessor/loader.rs +515 -326
  122. package/rust/core/preprocessor/mod.rs +4 -4
  123. package/rust/core/preprocessor/module.rs +60 -58
  124. package/rust/core/preprocessor/processor.rs +99 -101
  125. package/rust/core/preprocessor/resolver/bank.rs +51 -48
  126. package/rust/core/preprocessor/resolver/call.rs +100 -101
  127. package/rust/core/preprocessor/resolver/condition.rs +97 -97
  128. package/rust/core/preprocessor/resolver/driver.rs +310 -280
  129. package/rust/core/preprocessor/resolver/function.rs +69 -68
  130. package/rust/core/preprocessor/resolver/group.rs +96 -91
  131. package/rust/core/preprocessor/resolver/let_.rs +32 -28
  132. package/rust/core/preprocessor/resolver/loop_.rs +320 -121
  133. package/rust/core/preprocessor/resolver/mod.rs +15 -15
  134. package/rust/core/preprocessor/resolver/spawn.rs +76 -73
  135. package/rust/core/preprocessor/resolver/synth.rs +56 -50
  136. package/rust/core/preprocessor/resolver/tempo.rs +50 -49
  137. package/rust/core/preprocessor/resolver/trigger.rs +113 -115
  138. package/rust/core/preprocessor/resolver/value.rs +81 -81
  139. package/rust/core/shared/duration.rs +9 -9
  140. package/rust/core/shared/mod.rs +3 -3
  141. package/rust/core/shared/value.rs +35 -32
  142. package/rust/core/store/function.rs +34 -34
  143. package/rust/core/store/global.rs +55 -38
  144. package/rust/core/store/mod.rs +5 -5
  145. package/rust/core/store/variable.rs +37 -34
  146. package/rust/core/utils/mod.rs +2 -2
  147. package/rust/core/utils/path.rs +37 -31
  148. package/rust/core/utils/validation.rs +35 -36
  149. package/rust/installer/addon.rs +84 -80
  150. package/rust/installer/bank.rs +62 -65
  151. package/rust/installer/mod.rs +5 -5
  152. package/rust/installer/plugin.rs +54 -55
  153. package/rust/installer/utils.rs +56 -56
  154. package/rust/lib.rs +156 -164
  155. package/rust/main.rs +250 -144
  156. package/rust/utils/error.rs +200 -51
  157. package/rust/utils/file.rs +38 -35
  158. package/rust/utils/first_usage.rs +76 -0
  159. package/rust/utils/logger.rs +195 -143
  160. package/rust/utils/mod.rs +9 -7
  161. package/rust/utils/signature.rs +19 -17
  162. package/rust/utils/spinner.rs +22 -19
  163. package/rust/utils/telemetry.rs +292 -0
  164. package/rust/utils/watcher.rs +34 -33
  165. package/templates/minimal/README.md +97 -121
  166. package/templates/welcome/README.md +97 -121
  167. package/typescript/bin/index.ts +19 -5
  168. package/typescript/index.ts +3 -1
  169. package/typescript/scripts/postbuild.ts +10 -6
  170. package/typescript/scripts/postinstall.ts +56 -0
  171. package/typescript/scripts/version/bump.ts +0 -1
  172. package/typescript/scripts/version/index.ts +0 -1
  173. package/out-tsc/bin/devalang.exe +0 -0
@@ -1,121 +1,320 @@
1
- use std::collections::HashMap;
2
-
3
- use crate::{
4
- core::{
5
- parser::statement::{ Statement, StatementKind },
6
- preprocessor::{
7
- module::Module,
8
- resolver::{ driver::resolve_statement, value::resolve_value },
9
- },
10
- shared::value::Value,
11
- store::global::GlobalStore,
12
- },
13
- utils::logger::Logger,
14
- };
15
-
16
- pub fn resolve_loop(
17
- stmt: &Statement,
18
- module: &Module,
19
- path: &str,
20
- global_store: &mut GlobalStore
21
- ) -> Statement {
22
- let logger = Logger::new();
23
-
24
- let resolved_value = resolve_value(&stmt.value, module, global_store);
25
-
26
- let Value::Map(value_map) = &resolved_value else {
27
- return error_stmt(&logger, module, stmt, "Expected a map for loop value");
28
- };
29
-
30
- let mut resolved_map: HashMap<String, Value> = HashMap::new();
31
- for (key, val) in value_map {
32
- resolved_map.insert(key.clone(), resolve_value(val, module, global_store));
33
- }
34
-
35
- // Foreach form takes precedence if present
36
- if let (Some(Value::Identifier(var_name)), Some(array_val)) = (resolved_map.get("foreach"), resolved_map.get("array")) {
37
- // Resolve array elements
38
- let resolved_array = match array_val {
39
- Value::Array(items) => Value::Array(items.iter().map(|v| resolve_value(v, module, global_store)).collect()),
40
- other => resolve_value(other, module, global_store),
41
- };
42
-
43
- let body_value = match resolved_map.get("body") {
44
- Some(Value::Block(stmts)) => {
45
- let resolved = stmts
46
- .iter()
47
- .map(|s| resolve_statement(s, module, path, global_store))
48
- .collect();
49
- Value::Block(resolved)
50
- }
51
- _ => {
52
- error_value(&logger, module, stmt, "Invalid or missing loop body");
53
- Value::Block(vec![])
54
- }
55
- };
56
-
57
- let mut final_map = HashMap::new();
58
- final_map.insert("foreach".to_string(), Value::Identifier(var_name.clone()));
59
- final_map.insert("array".to_string(), resolved_array);
60
- final_map.insert("body".to_string(), body_value);
61
-
62
- return Statement { kind: StatementKind::Loop, value: Value::Map(final_map), ..stmt.clone() };
63
- }
64
-
65
- let iterator_value = match resolved_map.get("iterator") {
66
- Some(Value::Number(n)) => Value::Number(*n),
67
- Some(other) => {
68
- error_value(
69
- &logger,
70
- module,
71
- stmt,
72
- &format!("Loop iterator must be a number, found: {:?}", other)
73
- );
74
- Value::Number(1.0)
75
- }
76
- None => {
77
- error_value(&logger, module, stmt, "Missing 'iterator' in loop");
78
- Value::Number(1.0)
79
- }
80
- };
81
-
82
- let body_value = match resolved_map.get("body") {
83
- Some(Value::Block(stmts)) => {
84
- let resolved = stmts
85
- .iter()
86
- .map(|s| resolve_statement(s, module, path, global_store))
87
- .collect();
88
- Value::Block(resolved)
89
- }
90
- _ => {
91
- error_value(&logger, module, stmt, "Invalid or missing loop body");
92
- Value::Block(vec![])
93
- }
94
- };
95
-
96
- let mut final_map = HashMap::new();
97
- final_map.insert("iterator".to_string(), iterator_value);
98
- final_map.insert("body".to_string(), body_value);
99
-
100
- Statement {
101
- kind: StatementKind::Loop,
102
- value: Value::Map(final_map),
103
- ..stmt.clone()
104
- }
105
- }
106
-
107
- fn error_value(logger: &Logger, module: &Module, stmt: &Statement, msg: &str) {
108
- let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
109
- logger.log_error_with_stacktrace(msg, &stacktrace);
110
- }
111
-
112
- fn error_stmt(logger: &Logger, module: &Module, stmt: &Statement, msg: &str) -> Statement {
113
- error_value(logger, module, stmt, msg);
114
- Statement {
115
- kind: StatementKind::Error {
116
- message: msg.to_string(),
117
- },
118
- value: Value::Null,
119
- ..stmt.clone()
120
- }
121
- }
1
+ use std::collections::HashMap;
2
+
3
+ use crate::{
4
+ core::{
5
+ parser::statement::{Statement, StatementKind},
6
+ preprocessor::{
7
+ module::Module,
8
+ resolver::{driver::resolve_statement, value::resolve_value},
9
+ },
10
+ shared::value::Value,
11
+ store::global::GlobalStore,
12
+ },
13
+ utils::logger::Logger,
14
+ };
15
+
16
+ pub fn resolve_loop(
17
+ stmt: &Statement,
18
+ module: &Module,
19
+ path: &str,
20
+ global_store: &mut GlobalStore,
21
+ ) -> Statement {
22
+ let logger = Logger::new();
23
+
24
+ let resolved_value = resolve_value(&stmt.value, module, global_store);
25
+
26
+ let Value::Map(value_map) = &resolved_value else {
27
+ return error_stmt(&logger, module, stmt, "Expected a map for loop value");
28
+ };
29
+
30
+ let mut resolved_map: HashMap<String, Value> = HashMap::new();
31
+ for (key, val) in value_map {
32
+ resolved_map.insert(key.clone(), resolve_value(val, module, global_store));
33
+ }
34
+
35
+ // Foreach form takes precedence if present
36
+ if let (Some(Value::Identifier(var_name)), Some(array_val)) =
37
+ (resolved_map.get("foreach"), resolved_map.get("array"))
38
+ {
39
+ // Normalize array_val into an iterable Array
40
+ let resolved_array = match array_val {
41
+ Value::Array(items) => Value::Array(
42
+ items
43
+ .iter()
44
+ .map(|v| resolve_value(v, module, global_store))
45
+ .collect(),
46
+ ),
47
+ Value::Number(n) => {
48
+ // Iterate 0..n-1
49
+ let count = (*n).max(0.0) as usize;
50
+ let mut items = Vec::with_capacity(count);
51
+ for i in 0..count {
52
+ items.push(Value::Number(i as f32));
53
+ }
54
+ Value::Array(items)
55
+ }
56
+ Value::String(s) => {
57
+ // Try to parse a simple comma-separated list: "a,b,c" -> ["a","b","c"]
58
+ // If numeric string: iterate 0..n-1
59
+ if let Ok(n) = s.parse::<f32>() {
60
+ let count = n.max(0.0) as usize;
61
+ let mut items = Vec::with_capacity(count);
62
+ for i in 0..count {
63
+ items.push(Value::Number(i as f32));
64
+ }
65
+ Value::Array(items)
66
+ } else if s.contains(',') {
67
+ let parts: Vec<Value> = s
68
+ .split(',')
69
+ .map(|p| Value::String(p.trim().to_string()))
70
+ .collect();
71
+ Value::Array(parts)
72
+ } else {
73
+ // Fallback: iterate characters
74
+ let parts: Vec<Value> =
75
+ s.chars().map(|c| Value::String(c.to_string())).collect();
76
+ Value::Array(parts)
77
+ }
78
+ }
79
+ Value::Identifier(name) => {
80
+ // Resolve identifier from module variables (already resolved map above)
81
+ let v = if let Some(v) = module.variable_table.get(name) {
82
+ v.clone()
83
+ } else {
84
+ Value::Null
85
+ };
86
+ match v {
87
+ Value::Array(items) => Value::Array(
88
+ items
89
+ .iter()
90
+ .map(|v| resolve_value(v, module, global_store))
91
+ .collect(),
92
+ ),
93
+ Value::Number(n) => {
94
+ let count = n.max(0.0) as usize;
95
+ let mut items = Vec::with_capacity(count);
96
+ for i in 0..count {
97
+ items.push(Value::Number(i as f32));
98
+ }
99
+ Value::Array(items)
100
+ }
101
+ Value::String(s) => {
102
+ if let Ok(n) = s.parse::<f32>() {
103
+ let count = n.max(0.0) as usize;
104
+ let mut items = Vec::with_capacity(count);
105
+ for i in 0..count {
106
+ items.push(Value::Number(i as f32));
107
+ }
108
+ Value::Array(items)
109
+ } else if s.contains(',') {
110
+ let parts: Vec<Value> = s
111
+ .split(',')
112
+ .map(|p| Value::String(p.trim().to_string()))
113
+ .collect();
114
+ Value::Array(parts)
115
+ } else {
116
+ let parts: Vec<Value> =
117
+ s.chars().map(|c| Value::String(c.to_string())).collect();
118
+ Value::Array(parts)
119
+ }
120
+ }
121
+ other => {
122
+ error_value(
123
+ &logger,
124
+ module,
125
+ stmt,
126
+ &format!(
127
+ "Foreach identifier '{}' resolves to unsupported value: {:?}",
128
+ name, other
129
+ ),
130
+ );
131
+ Value::Array(vec![])
132
+ }
133
+ }
134
+ }
135
+ other => {
136
+ // Resolve and normalize if possible
137
+ let v = resolve_value(other, module, global_store);
138
+ match v {
139
+ Value::Array(items) => Value::Array(items),
140
+ Value::Number(n) => {
141
+ let count = n.max(0.0) as usize;
142
+ let mut items = Vec::with_capacity(count);
143
+ for i in 0..count {
144
+ items.push(Value::Number(i as f32));
145
+ }
146
+ Value::Array(items)
147
+ }
148
+ Value::String(s) => {
149
+ if let Ok(n) = s.parse::<f32>() {
150
+ let count = n.max(0.0) as usize;
151
+ let mut items = Vec::with_capacity(count);
152
+ for i in 0..count {
153
+ items.push(Value::Number(i as f32));
154
+ }
155
+ Value::Array(items)
156
+ } else if s.contains(',') {
157
+ let parts: Vec<Value> = s
158
+ .split(',')
159
+ .map(|p| Value::String(p.trim().to_string()))
160
+ .collect();
161
+ Value::Array(parts)
162
+ } else {
163
+ let parts: Vec<Value> =
164
+ s.chars().map(|c| Value::String(c.to_string())).collect();
165
+ Value::Array(parts)
166
+ }
167
+ }
168
+ other => {
169
+ error_value(
170
+ &logger,
171
+ module,
172
+ stmt,
173
+ &format!("Unsupported foreach array value: {:?}", other),
174
+ );
175
+ Value::Array(vec![])
176
+ }
177
+ }
178
+ }
179
+ };
180
+
181
+ let body_value = match resolved_map.get("body") {
182
+ Some(Value::Block(stmts)) => {
183
+ let resolved = stmts
184
+ .iter()
185
+ .map(|s| resolve_statement(s, module, path, global_store))
186
+ .collect();
187
+ Value::Block(resolved)
188
+ }
189
+ _ => {
190
+ error_value(&logger, module, stmt, "Invalid or missing loop body");
191
+ Value::Block(vec![])
192
+ }
193
+ };
194
+
195
+ let mut final_map = HashMap::new();
196
+ final_map.insert("foreach".to_string(), Value::Identifier(var_name.clone()));
197
+ final_map.insert("array".to_string(), resolved_array);
198
+ final_map.insert("body".to_string(), body_value);
199
+
200
+ return Statement {
201
+ kind: StatementKind::Loop,
202
+ value: Value::Map(final_map),
203
+ ..stmt.clone()
204
+ };
205
+ }
206
+
207
+ let iterator_value = match resolved_map.get("iterator") {
208
+ Some(Value::Number(n)) => Value::Number(*n),
209
+ Some(Value::String(s)) => {
210
+ if let Ok(n) = s.parse::<f32>() {
211
+ Value::Number(n)
212
+ } else {
213
+ error_value(
214
+ &logger,
215
+ module,
216
+ stmt,
217
+ &format!("Loop iterator string not numeric: '{}'", s),
218
+ );
219
+ Value::Number(1.0)
220
+ }
221
+ }
222
+ Some(Value::Identifier(name)) => {
223
+ // Try resolving from module vars (may be number or numeric string)
224
+ if let Some(v) = module.variable_table.get(name) {
225
+ match v {
226
+ Value::Number(n) => Value::Number(*n),
227
+ Value::String(s) => {
228
+ if let Ok(n) = s.parse::<f32>() {
229
+ Value::Number(n)
230
+ } else {
231
+ error_value(
232
+ &logger,
233
+ module,
234
+ stmt,
235
+ &format!(
236
+ "Loop iterator '{}' resolves to non-numeric string: '{}'",
237
+ name, s
238
+ ),
239
+ );
240
+ Value::Number(1.0)
241
+ }
242
+ }
243
+ other => {
244
+ error_value(
245
+ &logger,
246
+ module,
247
+ stmt,
248
+ &format!(
249
+ "Loop iterator '{}' resolves to non-number: {:?}",
250
+ name, other
251
+ ),
252
+ );
253
+ Value::Number(1.0)
254
+ }
255
+ }
256
+ } else {
257
+ error_value(
258
+ &logger,
259
+ module,
260
+ stmt,
261
+ &format!("Loop iterator identifier '{}' not found", name),
262
+ );
263
+ Value::Number(1.0)
264
+ }
265
+ }
266
+ Some(other) => {
267
+ error_value(
268
+ &logger,
269
+ module,
270
+ stmt,
271
+ &format!("Loop iterator must be a number, found: {:?}", other),
272
+ );
273
+ Value::Number(1.0)
274
+ }
275
+ None => {
276
+ error_value(&logger, module, stmt, "Missing 'iterator' in loop");
277
+ Value::Number(1.0)
278
+ }
279
+ };
280
+
281
+ let body_value = match resolved_map.get("body") {
282
+ Some(Value::Block(stmts)) => {
283
+ let resolved = stmts
284
+ .iter()
285
+ .map(|s| resolve_statement(s, module, path, global_store))
286
+ .collect();
287
+ Value::Block(resolved)
288
+ }
289
+ _ => {
290
+ error_value(&logger, module, stmt, "Invalid or missing loop body");
291
+ Value::Block(vec![])
292
+ }
293
+ };
294
+
295
+ let mut final_map = HashMap::new();
296
+ final_map.insert("iterator".to_string(), iterator_value);
297
+ final_map.insert("body".to_string(), body_value);
298
+
299
+ Statement {
300
+ kind: StatementKind::Loop,
301
+ value: Value::Map(final_map),
302
+ ..stmt.clone()
303
+ }
304
+ }
305
+
306
+ fn error_value(logger: &Logger, module: &Module, stmt: &Statement, msg: &str) {
307
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
308
+ logger.log_error_with_stacktrace(msg, &stacktrace);
309
+ }
310
+
311
+ fn error_stmt(logger: &Logger, module: &Module, stmt: &Statement, msg: &str) -> Statement {
312
+ error_value(logger, module, stmt, msg);
313
+ Statement {
314
+ kind: StatementKind::Error {
315
+ message: msg.to_string(),
316
+ },
317
+ value: Value::Null,
318
+ ..stmt.clone()
319
+ }
320
+ }
@@ -1,15 +1,15 @@
1
- pub mod driver;
2
-
3
- pub mod value;
4
-
5
- pub mod trigger;
6
- pub mod loop_;
7
- pub mod bank;
8
- pub mod tempo;
9
- pub mod group;
10
- pub mod condition;
11
- pub mod spawn;
12
- pub mod call;
13
- pub mod synth;
14
- pub mod let_;
15
- pub mod function;
1
+ pub mod driver;
2
+
3
+ pub mod value;
4
+
5
+ pub mod bank;
6
+ pub mod call;
7
+ pub mod condition;
8
+ pub mod function;
9
+ pub mod group;
10
+ pub mod let_;
11
+ pub mod loop_;
12
+ pub mod spawn;
13
+ pub mod synth;
14
+ pub mod tempo;
15
+ pub mod trigger;
@@ -1,73 +1,76 @@
1
- use crate::{
2
- core::{
3
- parser::statement::{ Statement, StatementKind },
4
- preprocessor::module::Module,
5
- shared::value::Value,
6
- store::global::GlobalStore,
7
- },
8
- utils::logger::{ Logger, LogLevel },
9
- };
10
-
11
- pub fn resolve_spawn(
12
- stmt: &Statement,
13
- name: String,
14
- args: Vec<Value>,
15
- module: &Module,
16
- _path: &str,
17
- global_store: &mut GlobalStore
18
- ) -> Statement {
19
- let logger = Logger::new();
20
-
21
- // Si c'est une fonction
22
- if let Some(func) = global_store.functions.functions.get(&name) {
23
- let mut resolved_map = std::collections::HashMap::new();
24
- resolved_map.insert("name".to_string(), Value::String(name.clone()));
25
- resolved_map.insert("args".to_string(), Value::Array(args.clone()));
26
- resolved_map.insert("body".to_string(), Value::Block(func.body.clone()));
27
-
28
- return Statement {
29
- kind: StatementKind::Spawn { name, args },
30
- value: Value::Map(resolved_map),
31
- ..stmt.clone()
32
- };
33
- }
34
-
35
- // Si c'est un group dans les variables
36
- if let Some(variable) = global_store.variables.variables.get(&name) {
37
- if let Value::Statement(stmt_box) = variable {
38
- if let StatementKind::Group = stmt_box.kind {
39
- if let Value::Map(map) = &stmt_box.value {
40
- if let Some(Value::Block(body)) = map.get("body") {
41
- let mut resolved_map = std::collections::HashMap::new();
42
- resolved_map.insert("identifier".to_string(), Value::String(name.clone()));
43
- resolved_map.insert("args".to_string(), Value::Array(args.clone()));
44
- resolved_map.insert("body".to_string(), Value::Block(body.clone()));
45
-
46
- return Statement {
47
- kind: StatementKind::Spawn { name, args },
48
- value: Value::Map(resolved_map),
49
- ..stmt.clone()
50
- };
51
- }
52
- }
53
- }
54
- }
55
- }
56
-
57
- // Sinon erreur
58
- let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
59
- logger.log_message(
60
- LogLevel::Error,
61
- &format!("Function or group '{}' not found for spawn\n → at {stacktrace}", name)
62
- );
63
-
64
- Statement {
65
- kind: StatementKind::Error {
66
- message: format!("Function or group '{}' not found for spawn", name),
67
- },
68
- value: Value::Null,
69
- ..stmt.clone()
70
- }
71
- }
72
-
73
- // (removed unused helpers get_group_body, error_stmt)
1
+ use crate::{
2
+ core::{
3
+ parser::statement::{Statement, StatementKind},
4
+ preprocessor::module::Module,
5
+ shared::value::Value,
6
+ store::global::GlobalStore,
7
+ },
8
+ utils::logger::{LogLevel, Logger},
9
+ };
10
+
11
+ pub fn resolve_spawn(
12
+ stmt: &Statement,
13
+ name: String,
14
+ args: Vec<Value>,
15
+ module: &Module,
16
+ _path: &str,
17
+ global_store: &mut GlobalStore,
18
+ ) -> Statement {
19
+ let logger = Logger::new();
20
+
21
+ // If it's a function
22
+ if let Some(func) = global_store.functions.functions.get(&name) {
23
+ let mut resolved_map = std::collections::HashMap::new();
24
+ resolved_map.insert("name".to_string(), Value::String(name.clone()));
25
+ resolved_map.insert("args".to_string(), Value::Array(args.clone()));
26
+ resolved_map.insert("body".to_string(), Value::Block(func.body.clone()));
27
+
28
+ return Statement {
29
+ kind: StatementKind::Spawn { name, args },
30
+ value: Value::Map(resolved_map),
31
+ ..stmt.clone()
32
+ };
33
+ }
34
+
35
+ // If it's a group stored in variables
36
+ if let Some(variable) = global_store.variables.variables.get(&name) {
37
+ if let Value::Statement(stmt_box) = variable {
38
+ if let StatementKind::Group = stmt_box.kind {
39
+ if let Value::Map(map) = &stmt_box.value {
40
+ if let Some(Value::Block(body)) = map.get("body") {
41
+ let mut resolved_map = std::collections::HashMap::new();
42
+ resolved_map.insert("identifier".to_string(), Value::String(name.clone()));
43
+ resolved_map.insert("args".to_string(), Value::Array(args.clone()));
44
+ resolved_map.insert("body".to_string(), Value::Block(body.clone()));
45
+
46
+ return Statement {
47
+ kind: StatementKind::Spawn { name, args },
48
+ value: Value::Map(resolved_map),
49
+ ..stmt.clone()
50
+ };
51
+ }
52
+ }
53
+ }
54
+ }
55
+ }
56
+
57
+ // Otherwise, log an error
58
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
59
+ logger.log_message(
60
+ LogLevel::Error,
61
+ &format!(
62
+ "Function or group '{}' not found for spawn\n → at {stacktrace}",
63
+ name
64
+ ),
65
+ );
66
+
67
+ Statement {
68
+ kind: StatementKind::Error {
69
+ message: format!("Function or group '{}' not found for spawn", name),
70
+ },
71
+ value: Value::Null,
72
+ ..stmt.clone()
73
+ }
74
+ }
75
+
76
+ // (removed unused helpers get_group_body, error_stmt)