@devaloop/devalang 0.0.1-beta.1 → 0.0.1-beta.2

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 (220) hide show
  1. package/.devalang +9 -10
  2. package/Cargo.toml +5 -4
  3. package/README.md +7 -5
  4. package/docs/CHANGELOG.md +42 -0
  5. package/docs/ROADMAP.md +5 -1
  6. package/docs/TODO.md +3 -14
  7. package/examples/bus.deva +10 -0
  8. package/examples/effect.deva +2 -0
  9. package/examples/filter.deva +11 -0
  10. package/examples/lfo.deva +9 -0
  11. package/examples/synth.deva +11 -1
  12. package/examples/synth_types.deva +17 -0
  13. package/out-tsc/core/functions/index.d.ts +5 -0
  14. package/out-tsc/core/functions/index.js +11 -0
  15. package/out-tsc/pkg/devalang_core.d.ts +2 -0
  16. package/out-tsc/pkg/devalang_core.js +17 -2
  17. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +8 -7
  18. package/package.json +1 -1
  19. package/project-version.json +3 -3
  20. package/rust/cli/bank/api.rs +122 -122
  21. package/rust/cli/bank/commands.rs +33 -2
  22. package/rust/cli/bank/mod.rs +29 -29
  23. package/rust/cli/build/commands.rs +53 -3
  24. package/rust/cli/build/mod.rs +2 -2
  25. package/rust/cli/build/process.rs +26 -7
  26. package/rust/cli/check/mod.rs +2 -2
  27. package/rust/cli/discover/commands.rs +253 -253
  28. package/rust/cli/discover/config.rs +111 -111
  29. package/rust/cli/discover/fs.rs +19 -19
  30. package/rust/cli/discover/install.rs +103 -103
  31. package/rust/cli/discover/metadata.rs +48 -48
  32. package/rust/cli/discover/mod.rs +5 -5
  33. package/rust/cli/install/addon.rs +118 -118
  34. package/rust/cli/install/bank.rs +22 -3
  35. package/rust/cli/install/commands.rs +35 -35
  36. package/rust/cli/install/mod.rs +4 -4
  37. package/rust/cli/install/plugin.rs +80 -61
  38. package/rust/cli/login/commands.rs +124 -124
  39. package/rust/cli/mod.rs +12 -12
  40. package/rust/cli/parser.rs +46 -1
  41. package/rust/cli/play/commands.rs +71 -20
  42. package/rust/cli/play/mod.rs +5 -5
  43. package/rust/cli/play/process.rs +14 -5
  44. package/rust/cli/play/realtime.rs +91 -91
  45. package/rust/cli/telemetry/commands.rs +22 -22
  46. package/rust/cli/telemetry/event_creator.rs +80 -80
  47. package/rust/cli/telemetry/mod.rs +3 -3
  48. package/rust/cli/telemetry/send.rs +51 -51
  49. package/rust/cli/template/commands.rs +69 -69
  50. package/rust/config/driver.rs +112 -103
  51. package/rust/config/mod.rs +3 -3
  52. package/rust/config/ops.rs +26 -26
  53. package/rust/config/settings.rs +101 -101
  54. package/rust/core/audio/engine/driver.rs +220 -0
  55. package/rust/core/audio/engine/export.rs +169 -0
  56. package/rust/core/audio/engine/helpers.rs +178 -170
  57. package/rust/core/audio/engine/mod.rs +51 -2
  58. package/rust/core/audio/engine/notes/dsp.rs +85 -0
  59. package/rust/core/audio/engine/notes/mod.rs +44 -0
  60. package/rust/core/audio/engine/notes/params.rs +294 -0
  61. package/rust/core/audio/engine/sample/insert.rs +199 -0
  62. package/rust/core/audio/engine/sample/mod.rs +40 -0
  63. package/rust/core/audio/engine/sample/padding.rs +170 -0
  64. package/rust/core/audio/evaluator/condition.rs +61 -0
  65. package/rust/core/audio/evaluator/mod.rs +9 -0
  66. package/rust/core/audio/{evaluator.rs → evaluator/numeric.rs} +1 -159
  67. package/rust/core/audio/evaluator/rhs.rs +16 -0
  68. package/rust/core/audio/evaluator/string_expr.rs +94 -0
  69. package/rust/core/audio/interpreter/driver.rs +55 -23
  70. package/rust/core/audio/interpreter/mod.rs +1 -13
  71. package/rust/core/audio/interpreter/statements/arrow_call/interprete.rs +175 -0
  72. package/rust/core/audio/interpreter/statements/arrow_call/methods/chord.rs +384 -0
  73. package/rust/core/audio/interpreter/statements/arrow_call/methods/mod.rs +2 -0
  74. package/rust/core/audio/interpreter/statements/arrow_call/methods/note.rs +316 -0
  75. package/rust/core/audio/interpreter/statements/arrow_call/mod.rs +3 -0
  76. package/rust/core/audio/interpreter/statements/arrow_call/types/arp.rs +192 -0
  77. package/rust/core/audio/interpreter/statements/arrow_call/types/mod.rs +24 -0
  78. package/rust/core/audio/interpreter/statements/arrow_call/types/pad.rs +116 -0
  79. package/rust/core/audio/interpreter/statements/arrow_call/types/pluck.rs +97 -0
  80. package/rust/core/audio/interpreter/statements/arrow_call/types/sub.rs +100 -0
  81. package/rust/core/audio/interpreter/{automate.rs → statements/automate.rs} +16 -18
  82. package/rust/core/audio/interpreter/{call.rs → statements/call.rs} +5 -4
  83. package/rust/core/audio/interpreter/{condition.rs → statements/condition.rs} +2 -1
  84. package/rust/core/audio/interpreter/{function.rs → statements/function.rs} +2 -4
  85. package/rust/core/audio/interpreter/{let_.rs → statements/let_.rs} +2 -4
  86. package/rust/core/audio/interpreter/{load.rs → statements/load.rs} +2 -4
  87. package/rust/core/audio/interpreter/{loop_.rs → statements/loop_.rs} +2 -1
  88. package/rust/core/audio/interpreter/statements/mod.rs +12 -0
  89. package/rust/core/audio/interpreter/{sleep.rs → statements/sleep.rs} +28 -28
  90. package/rust/core/audio/interpreter/{spawn.rs → statements/spawn.rs} +3 -2
  91. package/rust/core/audio/interpreter/{tempo.rs → statements/tempo.rs} +40 -40
  92. package/rust/core/audio/interpreter/{trigger.rs → statements/trigger.rs} +1 -1
  93. package/rust/core/audio/loader/trigger.rs +2 -1
  94. package/rust/core/audio/mod.rs +6 -7
  95. package/rust/core/audio/player.rs +70 -70
  96. package/rust/core/audio/special/easing.rs +189 -189
  97. package/rust/core/audio/special/env.rs +45 -45
  98. package/rust/core/audio/special/math.rs +134 -134
  99. package/rust/core/audio/special/mod.rs +9 -9
  100. package/rust/core/audio/special/modulator.rs +143 -143
  101. package/rust/core/builder/mod.rs +45 -2
  102. package/rust/core/debugger/lexer.rs +27 -27
  103. package/rust/core/debugger/{module.rs → logs.rs} +3 -6
  104. package/rust/core/debugger/mod.rs +30 -30
  105. package/rust/core/debugger/preprocessor.rs +27 -27
  106. package/rust/core/debugger/store.rs +2 -4
  107. package/rust/core/error/mod.rs +269 -269
  108. package/rust/core/lexer/driver.rs +59 -61
  109. package/rust/core/lexer/handler/arrow.rs +82 -82
  110. package/rust/core/lexer/handler/at.rs +21 -21
  111. package/rust/core/lexer/handler/brace.rs +41 -41
  112. package/rust/core/lexer/handler/colon.rs +21 -21
  113. package/rust/core/lexer/handler/comment.rs +30 -30
  114. package/rust/core/lexer/handler/dot.rs +21 -21
  115. package/rust/core/lexer/handler/driver.rs +337 -337
  116. package/rust/core/lexer/handler/identifier.rs +47 -47
  117. package/rust/core/lexer/handler/indent.rs +66 -66
  118. package/rust/core/lexer/handler/mod.rs +15 -15
  119. package/rust/core/lexer/handler/newline.rs +23 -23
  120. package/rust/core/lexer/handler/number.rs +31 -31
  121. package/rust/core/lexer/handler/operator.rs +46 -46
  122. package/rust/core/lexer/handler/parenthesis.rs +41 -41
  123. package/rust/core/lexer/handler/slash.rs +21 -21
  124. package/rust/core/lexer/handler/string.rs +63 -63
  125. package/rust/core/lexer/mod.rs +3 -3
  126. package/rust/core/mod.rs +0 -1
  127. package/rust/core/parser/driver/block.rs +111 -0
  128. package/rust/core/parser/driver/cursor.rs +82 -0
  129. package/rust/core/parser/driver/driver_impl.rs +139 -0
  130. package/rust/core/parser/driver/mod.rs +6 -0
  131. package/rust/core/parser/driver/parse_array.rs +120 -0
  132. package/rust/core/parser/driver/parse_map.rs +223 -0
  133. package/rust/core/parser/driver/parser.rs +160 -0
  134. package/rust/core/parser/handler/arrow_call.rs +28 -4
  135. package/rust/core/parser/handler/at.rs +279 -279
  136. package/rust/core/parser/handler/bank.rs +104 -104
  137. package/rust/core/parser/handler/condition.rs +83 -83
  138. package/rust/core/parser/handler/dot.rs +148 -148
  139. package/rust/core/parser/handler/identifier/automate.rs +254 -254
  140. package/rust/core/parser/handler/identifier/call.rs +91 -91
  141. package/rust/core/parser/handler/identifier/emit.rs +70 -70
  142. package/rust/core/parser/handler/identifier/function.rs +113 -113
  143. package/rust/core/parser/handler/identifier/group.rs +89 -89
  144. package/rust/core/parser/handler/identifier/let_.rs +173 -173
  145. package/rust/core/parser/handler/identifier/mod.rs +55 -55
  146. package/rust/core/parser/handler/identifier/on.rs +107 -107
  147. package/rust/core/parser/handler/identifier/print.rs +49 -49
  148. package/rust/core/parser/handler/identifier/sleep.rs +96 -43
  149. package/rust/core/parser/handler/identifier/spawn.rs +91 -91
  150. package/rust/core/parser/handler/identifier/synth.rs +135 -135
  151. package/rust/core/parser/handler/loop_.rs +194 -194
  152. package/rust/core/parser/handler/mod.rs +9 -9
  153. package/rust/core/parser/handler/pattern.rs +1 -1
  154. package/rust/core/parser/handler/tempo.rs +105 -57
  155. package/rust/core/parser/statement.rs +10 -11
  156. package/rust/core/plugin/loader.rs +1 -1
  157. package/rust/core/plugin/mod.rs +2 -2
  158. package/rust/core/plugin/runner/mod.rs +11 -0
  159. package/rust/core/plugin/{runner.rs → runner/non_wasm.rs} +297 -347
  160. package/rust/core/plugin/runner/wasm32.rs +43 -0
  161. package/rust/core/preprocessor/loader/inject.rs +278 -0
  162. package/rust/core/preprocessor/loader/loader_helpers.rs +110 -0
  163. package/rust/core/preprocessor/loader/mod.rs +235 -0
  164. package/rust/core/preprocessor/module.rs +2 -7
  165. package/rust/core/preprocessor/{processor.rs → processor/handlers.rs} +6 -13
  166. package/rust/core/preprocessor/processor/mod.rs +1 -0
  167. package/rust/core/preprocessor/resolver/bank.rs +49 -49
  168. package/rust/core/preprocessor/resolver/call.rs +124 -124
  169. package/rust/core/preprocessor/resolver/condition.rs +95 -95
  170. package/rust/core/preprocessor/resolver/driver.rs +324 -324
  171. package/rust/core/preprocessor/resolver/function.rs +2 -2
  172. package/rust/core/preprocessor/resolver/group.rs +46 -18
  173. package/rust/core/preprocessor/resolver/let_.rs +32 -32
  174. package/rust/core/preprocessor/resolver/loop_.rs +318 -318
  175. package/rust/core/preprocessor/resolver/mod.rs +16 -16
  176. package/rust/core/preprocessor/resolver/pattern.rs +83 -83
  177. package/rust/core/preprocessor/resolver/spawn.rs +99 -99
  178. package/rust/core/preprocessor/resolver/synth.rs +54 -54
  179. package/rust/core/preprocessor/resolver/tempo.rs +48 -48
  180. package/rust/core/preprocessor/resolver/trigger.rs +116 -116
  181. package/rust/core/preprocessor/resolver/value.rs +176 -176
  182. package/rust/core/store/global.rs +2 -6
  183. package/rust/core/store/mod.rs +1 -5
  184. package/rust/lib.rs +18 -3
  185. package/rust/main.rs +27 -3
  186. package/rust/types/Cargo.toml +1 -1
  187. package/rust/types/src/addons.rs +55 -55
  188. package/rust/types/src/config.rs +84 -74
  189. package/rust/types/src/lib.rs +15 -12
  190. package/rust/types/src/plugin.rs +20 -0
  191. package/rust/types/src/store.rs +139 -0
  192. package/rust/types/src/telemetry.rs +85 -85
  193. package/rust/utils/Cargo.toml +2 -2
  194. package/rust/utils/src/file.rs +94 -94
  195. package/rust/utils/src/first_usage.rs +97 -97
  196. package/rust/utils/src/lib.rs +9 -9
  197. package/rust/utils/src/logger.rs +200 -200
  198. package/rust/utils/src/path.rs +129 -88
  199. package/rust/utils/src/signature.rs +41 -41
  200. package/rust/utils/src/spinner.rs +20 -20
  201. package/rust/utils/src/version.rs +27 -27
  202. package/rust/utils/src/watcher.rs +46 -46
  203. package/rust/web/api.rs +5 -5
  204. package/rust/web/cdn.rs +34 -34
  205. package/rust/web/mod.rs +3 -3
  206. package/tests/integration.rs +21 -21
  207. package/typescript/core/functions/index.ts +11 -0
  208. package/typescript/pkg/devalang_core.ts +20 -4
  209. package/rust/core/audio/engine/sample.rs +0 -366
  210. package/rust/core/audio/engine/synth.rs +0 -325
  211. package/rust/core/audio/interpreter/arrow_call.rs +0 -311
  212. package/rust/core/audio/renderer.rs +0 -54
  213. package/rust/core/parser/driver.rs +0 -584
  214. package/rust/core/preprocessor/loader.rs +0 -637
  215. package/rust/core/store/export.rs +0 -28
  216. package/rust/core/store/function.rs +0 -40
  217. package/rust/core/store/import.rs +0 -28
  218. package/rust/core/store/variable.rs +0 -51
  219. package/rust/core/utils/mod.rs +0 -1
  220. package/rust/core/utils/path.rs +0 -37
@@ -1,324 +1,324 @@
1
- use crate::core::{
2
- parser::statement::{Statement, StatementKind},
3
- preprocessor::{
4
- loader::ModuleLoader,
5
- module::Module,
6
- resolver::{
7
- bank::resolve_bank, call::resolve_call, condition::resolve_condition,
8
- function::resolve_function, group::resolve_group, let_::resolve_let,
9
- loop_::resolve_loop, pattern::resolve_pattern, spawn::resolve_spawn,
10
- tempo::resolve_tempo, trigger::resolve_trigger,
11
- },
12
- },
13
- store::global::GlobalStore,
14
- };
15
- use devalang_types::Value;
16
- use devalang_utils::logger::LogLevel;
17
- use devalang_utils::logger::Logger;
18
- use std::collections::HashMap;
19
-
20
- pub fn resolve_all_modules(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
21
- for _module in global_store.clone().modules.values_mut() {
22
- resolve_imports(module_loader, global_store);
23
- }
24
- }
25
-
26
- pub fn resolve_statement(
27
- stmt: &Statement,
28
- module: &Module,
29
- path: &str,
30
- global_store: &mut GlobalStore,
31
- ) -> Statement {
32
- match &stmt.kind {
33
- StatementKind::On { event, args, body } => {
34
- let resolved_body: Vec<Statement> = body
35
- .iter()
36
- .map(|s| resolve_statement(s, module, path, global_store))
37
- .collect();
38
- Statement {
39
- kind: StatementKind::On {
40
- event: event.clone(),
41
- args: args.clone(),
42
- body: resolved_body,
43
- },
44
- value: resolve_value(&stmt.value, module, global_store),
45
- ..stmt.clone()
46
- }
47
- }
48
- StatementKind::Emit { event, payload: _ } => Statement {
49
- kind: StatementKind::Emit {
50
- event: event.clone(),
51
- payload: Some(resolve_value(&stmt.value, module, global_store)),
52
- },
53
- value: resolve_value(&stmt.value, module, global_store),
54
- ..stmt.clone()
55
- },
56
- StatementKind::Trigger {
57
- entity,
58
- duration,
59
- effects,
60
- } => resolve_trigger(
61
- stmt,
62
- entity,
63
- &mut duration.clone(),
64
- effects.clone(),
65
- module,
66
- path,
67
- global_store,
68
- ),
69
- StatementKind::If => resolve_condition(stmt, module, path, global_store),
70
- StatementKind::Group => resolve_group(stmt, module, path, global_store),
71
- StatementKind::Pattern { .. } => resolve_pattern(stmt, module, path, global_store),
72
- StatementKind::Call { name, args } => {
73
- resolve_call(stmt, name.clone(), args.clone(), module, path, global_store)
74
- }
75
- StatementKind::Spawn { name, args } => {
76
- resolve_spawn(stmt, name.clone(), args.clone(), module, path, global_store)
77
- }
78
- StatementKind::Bank { .. } => resolve_bank(stmt, module, path, global_store),
79
- StatementKind::Tempo => resolve_tempo(stmt, module, path, global_store),
80
- StatementKind::Loop => resolve_loop(stmt, module, path, global_store),
81
- StatementKind::Let { name, .. } => resolve_let(stmt, name, module, path, global_store),
82
-
83
- _ => {
84
- let resolved_value = resolve_value(&stmt.value, module, global_store);
85
-
86
- Statement {
87
- value: resolved_value,
88
- ..stmt.clone()
89
- }
90
- }
91
- }
92
- }
93
-
94
- fn resolve_value(value: &Value, module: &Module, global_store: &mut GlobalStore) -> Value {
95
- let logger = Logger::new();
96
- match value {
97
- Value::Identifier(name) => {
98
- if let Some(original_val) = module.variable_table.get(name) {
99
- return resolve_value(original_val, module, global_store);
100
- }
101
-
102
- if let Some(export_val) = find_export_value(name, global_store) {
103
- return resolve_value(&export_val, module, global_store);
104
- }
105
-
106
- // Leave unresolved identifiers as-is; they might be runtime-bound (e.g., foreach vars)
107
- Value::Identifier(name.clone())
108
- }
109
-
110
- Value::String(s) => Value::String(s.clone()),
111
-
112
- Value::Beat(beat_str) => {
113
- logger.log_message(
114
- LogLevel::Warning,
115
- &format!("[warn] '{:?}': unresolved beat '{}'", module.path, beat_str),
116
- );
117
- Value::Beat(beat_str.clone())
118
- }
119
-
120
- Value::Map(map) => {
121
- let mut resolved = HashMap::new();
122
- for (k, v) in map {
123
- resolved.insert(k.clone(), resolve_value(v, module, global_store));
124
- }
125
- Value::Map(resolved)
126
- }
127
-
128
- Value::Block(stmts) => {
129
- let resolved_stmts = stmts
130
- .iter()
131
- .map(|stmt| resolve_statement(stmt, module, &module.path, global_store))
132
- .collect();
133
- Value::Block(resolved_stmts)
134
- }
135
-
136
- other => other.clone(),
137
- }
138
- }
139
-
140
- fn find_export_value(name: &str, global_store: &GlobalStore) -> Option<Value> {
141
- for module in global_store.modules.values() {
142
- if let Some(val) = module.export_table.get_export(name) {
143
- return Some(val.clone());
144
- }
145
- }
146
- None
147
- }
148
-
149
- pub fn resolve_imports(_module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
150
- let logger = Logger::new();
151
- for (module_path, module) in global_store.clone().modules.iter_mut() {
152
- for (name, source_path) in &module.import_table.imports {
153
- match source_path {
154
- Value::String(source_path) => {
155
- if let Some(source_module) = global_store.modules.get(source_path) {
156
- if let Some(value) = source_module.export_table.get_export(name) {
157
- module.variable_table.set(name.clone(), value.clone());
158
- } else {
159
- logger.log_message(LogLevel::Warning, &format!("[warn] '{module_path}': '{name}' not found in exports of '{source_path}'"));
160
- }
161
- } else {
162
- logger.log_message(
163
- LogLevel::Warning,
164
- &format!(
165
- "[warn] '{module_path}': cannot find source module '{source_path}'"
166
- ),
167
- );
168
- }
169
- }
170
- _ => {
171
- logger.log_message(
172
- LogLevel::Warning,
173
- &format!(
174
- "[warn] '{module_path}': expected string for import source, found {:?}",
175
- source_path
176
- ),
177
- );
178
- }
179
- }
180
- }
181
- }
182
- }
183
-
184
- pub fn resolve_and_flatten_all_modules(
185
- global_store: &mut GlobalStore,
186
- ) -> HashMap<String, Vec<Statement>> {
187
- let logger = Logger::new();
188
- let snapshot = global_store.clone();
189
-
190
- // 1. Imports resolution
191
- for (module_path, module) in global_store.modules.iter_mut() {
192
- for (name, source_path) in &module.import_table.imports {
193
- if let Value::String(source_path_str) = source_path {
194
- match snapshot.modules.get(source_path_str) {
195
- Some(source_module) => {
196
- if let Some(value) = source_module.export_table.get_export(name) {
197
- module.variable_table.set(name.clone(), value.clone());
198
- } else {
199
- logger.log_error_with_stacktrace(
200
- &format!("'{name}' not found in exports of '{source_path_str}'"),
201
- module_path,
202
- );
203
- }
204
- }
205
- None => {
206
- logger.log_error_with_stacktrace(
207
- &format!("Cannot find source module '{source_path_str}'"),
208
- module_path,
209
- );
210
- }
211
- }
212
- } else {
213
- logger.log_error_with_stacktrace(
214
- &format!("Expected string for import source, found {:?}", source_path),
215
- module_path,
216
- );
217
- }
218
- }
219
- }
220
-
221
- // 2. Statements resolution
222
- let mut resolved_map: HashMap<String, Vec<Statement>> = HashMap::new();
223
- for (path, module) in global_store.modules.clone() {
224
- let mut resolved = Vec::new();
225
-
226
- for stmt in &module.statements {
227
- let stmt = stmt.clone();
228
-
229
- match &stmt.kind {
230
- StatementKind::Let { name } => {
231
- let resolved_stmt = resolve_let(&stmt, name, &module, &path, global_store);
232
- resolved.push(resolved_stmt);
233
- }
234
-
235
- StatementKind::Trigger {
236
- entity,
237
- duration,
238
- effects,
239
- } => {
240
- let resolved_stmt = resolve_trigger(
241
- &stmt,
242
- entity.as_str(),
243
- &mut duration.clone(),
244
- effects.clone(),
245
- &module,
246
- &path,
247
- global_store,
248
- );
249
- resolved.push(resolved_stmt);
250
- }
251
-
252
- StatementKind::Loop => {
253
- let resolved_stmt = resolve_loop(&stmt, &module, &path, global_store);
254
- resolved.push(resolved_stmt);
255
- }
256
-
257
- StatementKind::Bank { .. } => {
258
- let resolved_stmt = resolve_bank(&stmt, &module, &path, global_store);
259
- resolved.push(resolved_stmt);
260
- }
261
-
262
- StatementKind::Tempo => {
263
- let resolved_stmt = resolve_tempo(&stmt, &module, &path, global_store);
264
- resolved.push(resolved_stmt);
265
- }
266
-
267
- StatementKind::Import { .. } | StatementKind::Export { .. } => {
268
- resolved.push(stmt.clone());
269
- }
270
-
271
- StatementKind::Call { name, args } => {
272
- let resolved_stmt = resolve_call(
273
- &stmt,
274
- name.clone(),
275
- args.clone(),
276
- &module,
277
- &path,
278
- global_store,
279
- );
280
- resolved.push(resolved_stmt);
281
- }
282
-
283
- StatementKind::Spawn { name, args } => {
284
- let resolved_stmt = resolve_spawn(
285
- &stmt,
286
- name.clone(),
287
- args.clone(),
288
- &module,
289
- &path,
290
- global_store,
291
- );
292
- resolved.push(resolved_stmt);
293
- }
294
-
295
- StatementKind::Group => {
296
- let resolved_stmt = resolve_group(&stmt, &module, &path, global_store);
297
- resolved.push(resolved_stmt);
298
- }
299
-
300
- StatementKind::Pattern { .. } => {
301
- let resolved_stmt = resolve_pattern(&stmt, &module, &path, global_store);
302
- resolved.push(resolved_stmt);
303
- }
304
-
305
- StatementKind::Function {
306
- name: _,
307
- parameters: _,
308
- body: _,
309
- } => {
310
- let resolved_function = resolve_function(&stmt, &module, &path, global_store);
311
- resolved.push(resolved_function);
312
- }
313
-
314
- _ => {
315
- resolved.push(stmt);
316
- }
317
- }
318
- }
319
-
320
- resolved_map.insert(path.clone(), resolved);
321
- }
322
-
323
- resolved_map
324
- }
1
+ use crate::core::{
2
+ parser::statement::{Statement, StatementKind},
3
+ preprocessor::{
4
+ loader::ModuleLoader,
5
+ module::Module,
6
+ resolver::{
7
+ bank::resolve_bank, call::resolve_call, condition::resolve_condition,
8
+ function::resolve_function, group::resolve_group, let_::resolve_let,
9
+ loop_::resolve_loop, pattern::resolve_pattern, spawn::resolve_spawn,
10
+ tempo::resolve_tempo, trigger::resolve_trigger,
11
+ },
12
+ },
13
+ store::global::GlobalStore,
14
+ };
15
+ use devalang_types::Value;
16
+ use devalang_utils::logger::LogLevel;
17
+ use devalang_utils::logger::Logger;
18
+ use std::collections::HashMap;
19
+
20
+ pub fn resolve_all_modules(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
21
+ for _module in global_store.clone().modules.values_mut() {
22
+ resolve_imports(module_loader, global_store);
23
+ }
24
+ }
25
+
26
+ pub fn resolve_statement(
27
+ stmt: &Statement,
28
+ module: &Module,
29
+ path: &str,
30
+ global_store: &mut GlobalStore,
31
+ ) -> Statement {
32
+ match &stmt.kind {
33
+ StatementKind::On { event, args, body } => {
34
+ let resolved_body: Vec<Statement> = body
35
+ .iter()
36
+ .map(|s| resolve_statement(s, module, path, global_store))
37
+ .collect();
38
+ Statement {
39
+ kind: StatementKind::On {
40
+ event: event.clone(),
41
+ args: args.clone(),
42
+ body: resolved_body,
43
+ },
44
+ value: resolve_value(&stmt.value, module, global_store),
45
+ ..stmt.clone()
46
+ }
47
+ }
48
+ StatementKind::Emit { event, payload: _ } => Statement {
49
+ kind: StatementKind::Emit {
50
+ event: event.clone(),
51
+ payload: Some(resolve_value(&stmt.value, module, global_store)),
52
+ },
53
+ value: resolve_value(&stmt.value, module, global_store),
54
+ ..stmt.clone()
55
+ },
56
+ StatementKind::Trigger {
57
+ entity,
58
+ duration,
59
+ effects,
60
+ } => resolve_trigger(
61
+ stmt,
62
+ entity,
63
+ &mut duration.clone(),
64
+ effects.clone(),
65
+ module,
66
+ path,
67
+ global_store,
68
+ ),
69
+ StatementKind::If => resolve_condition(stmt, module, path, global_store),
70
+ StatementKind::Group => resolve_group(stmt, module, path, global_store),
71
+ StatementKind::Pattern { .. } => resolve_pattern(stmt, module, path, global_store),
72
+ StatementKind::Call { name, args } => {
73
+ resolve_call(stmt, name.clone(), args.clone(), module, path, global_store)
74
+ }
75
+ StatementKind::Spawn { name, args } => {
76
+ resolve_spawn(stmt, name.clone(), args.clone(), module, path, global_store)
77
+ }
78
+ StatementKind::Bank { .. } => resolve_bank(stmt, module, path, global_store),
79
+ StatementKind::Tempo => resolve_tempo(stmt, module, path, global_store),
80
+ StatementKind::Loop => resolve_loop(stmt, module, path, global_store),
81
+ StatementKind::Let { name, .. } => resolve_let(stmt, name, module, path, global_store),
82
+
83
+ _ => {
84
+ let resolved_value = resolve_value(&stmt.value, module, global_store);
85
+
86
+ Statement {
87
+ value: resolved_value,
88
+ ..stmt.clone()
89
+ }
90
+ }
91
+ }
92
+ }
93
+
94
+ fn resolve_value(value: &Value, module: &Module, global_store: &mut GlobalStore) -> Value {
95
+ let logger = Logger::new();
96
+ match value {
97
+ Value::Identifier(name) => {
98
+ if let Some(original_val) = module.variable_table.get(name) {
99
+ return resolve_value(original_val, module, global_store);
100
+ }
101
+
102
+ if let Some(export_val) = find_export_value(name, global_store) {
103
+ return resolve_value(&export_val, module, global_store);
104
+ }
105
+
106
+ // Leave unresolved identifiers as-is; they might be runtime-bound (e.g., foreach vars)
107
+ Value::Identifier(name.clone())
108
+ }
109
+
110
+ Value::String(s) => Value::String(s.clone()),
111
+
112
+ Value::Beat(beat_str) => {
113
+ logger.log_message(
114
+ LogLevel::Warning,
115
+ &format!("[warn] '{:?}': unresolved beat '{}'", module.path, beat_str),
116
+ );
117
+ Value::Beat(beat_str.clone())
118
+ }
119
+
120
+ Value::Map(map) => {
121
+ let mut resolved = HashMap::new();
122
+ for (k, v) in map {
123
+ resolved.insert(k.clone(), resolve_value(v, module, global_store));
124
+ }
125
+ Value::Map(resolved)
126
+ }
127
+
128
+ Value::Block(stmts) => {
129
+ let resolved_stmts = stmts
130
+ .iter()
131
+ .map(|stmt| resolve_statement(stmt, module, &module.path, global_store))
132
+ .collect();
133
+ Value::Block(resolved_stmts)
134
+ }
135
+
136
+ other => other.clone(),
137
+ }
138
+ }
139
+
140
+ fn find_export_value(name: &str, global_store: &GlobalStore) -> Option<Value> {
141
+ for module in global_store.modules.values() {
142
+ if let Some(val) = module.export_table.get_export(name) {
143
+ return Some(val.clone());
144
+ }
145
+ }
146
+ None
147
+ }
148
+
149
+ pub fn resolve_imports(_module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
150
+ let logger = Logger::new();
151
+ for (module_path, module) in global_store.clone().modules.iter_mut() {
152
+ for (name, source_path) in &module.import_table.imports {
153
+ match source_path {
154
+ Value::String(source_path) => {
155
+ if let Some(source_module) = global_store.modules.get(source_path) {
156
+ if let Some(value) = source_module.export_table.get_export(name) {
157
+ module.variable_table.set(name.clone(), value.clone());
158
+ } else {
159
+ logger.log_message(LogLevel::Warning, &format!("[warn] '{module_path}': '{name}' not found in exports of '{source_path}'"));
160
+ }
161
+ } else {
162
+ logger.log_message(
163
+ LogLevel::Warning,
164
+ &format!(
165
+ "[warn] '{module_path}': cannot find source module '{source_path}'"
166
+ ),
167
+ );
168
+ }
169
+ }
170
+ _ => {
171
+ logger.log_message(
172
+ LogLevel::Warning,
173
+ &format!(
174
+ "[warn] '{module_path}': expected string for import source, found {:?}",
175
+ source_path
176
+ ),
177
+ );
178
+ }
179
+ }
180
+ }
181
+ }
182
+ }
183
+
184
+ pub fn resolve_and_flatten_all_modules(
185
+ global_store: &mut GlobalStore,
186
+ ) -> HashMap<String, Vec<Statement>> {
187
+ let logger = Logger::new();
188
+ let snapshot = global_store.clone();
189
+
190
+ // 1. Imports resolution
191
+ for (module_path, module) in global_store.modules.iter_mut() {
192
+ for (name, source_path) in &module.import_table.imports {
193
+ if let Value::String(source_path_str) = source_path {
194
+ match snapshot.modules.get(source_path_str) {
195
+ Some(source_module) => {
196
+ if let Some(value) = source_module.export_table.get_export(name) {
197
+ module.variable_table.set(name.clone(), value.clone());
198
+ } else {
199
+ logger.log_error_with_stacktrace(
200
+ &format!("'{name}' not found in exports of '{source_path_str}'"),
201
+ module_path,
202
+ );
203
+ }
204
+ }
205
+ None => {
206
+ logger.log_error_with_stacktrace(
207
+ &format!("Cannot find source module '{source_path_str}'"),
208
+ module_path,
209
+ );
210
+ }
211
+ }
212
+ } else {
213
+ logger.log_error_with_stacktrace(
214
+ &format!("Expected string for import source, found {:?}", source_path),
215
+ module_path,
216
+ );
217
+ }
218
+ }
219
+ }
220
+
221
+ // 2. Statements resolution
222
+ let mut resolved_map: HashMap<String, Vec<Statement>> = HashMap::new();
223
+ for (path, module) in global_store.modules.clone() {
224
+ let mut resolved = Vec::new();
225
+
226
+ for stmt in &module.statements {
227
+ let stmt = stmt.clone();
228
+
229
+ match &stmt.kind {
230
+ StatementKind::Let { name } => {
231
+ let resolved_stmt = resolve_let(&stmt, name, &module, &path, global_store);
232
+ resolved.push(resolved_stmt);
233
+ }
234
+
235
+ StatementKind::Trigger {
236
+ entity,
237
+ duration,
238
+ effects,
239
+ } => {
240
+ let resolved_stmt = resolve_trigger(
241
+ &stmt,
242
+ entity.as_str(),
243
+ &mut duration.clone(),
244
+ effects.clone(),
245
+ &module,
246
+ &path,
247
+ global_store,
248
+ );
249
+ resolved.push(resolved_stmt);
250
+ }
251
+
252
+ StatementKind::Loop => {
253
+ let resolved_stmt = resolve_loop(&stmt, &module, &path, global_store);
254
+ resolved.push(resolved_stmt);
255
+ }
256
+
257
+ StatementKind::Bank { .. } => {
258
+ let resolved_stmt = resolve_bank(&stmt, &module, &path, global_store);
259
+ resolved.push(resolved_stmt);
260
+ }
261
+
262
+ StatementKind::Tempo => {
263
+ let resolved_stmt = resolve_tempo(&stmt, &module, &path, global_store);
264
+ resolved.push(resolved_stmt);
265
+ }
266
+
267
+ StatementKind::Import { .. } | StatementKind::Export { .. } => {
268
+ resolved.push(stmt.clone());
269
+ }
270
+
271
+ StatementKind::Call { name, args } => {
272
+ let resolved_stmt = resolve_call(
273
+ &stmt,
274
+ name.clone(),
275
+ args.clone(),
276
+ &module,
277
+ &path,
278
+ global_store,
279
+ );
280
+ resolved.push(resolved_stmt);
281
+ }
282
+
283
+ StatementKind::Spawn { name, args } => {
284
+ let resolved_stmt = resolve_spawn(
285
+ &stmt,
286
+ name.clone(),
287
+ args.clone(),
288
+ &module,
289
+ &path,
290
+ global_store,
291
+ );
292
+ resolved.push(resolved_stmt);
293
+ }
294
+
295
+ StatementKind::Group => {
296
+ let resolved_stmt = resolve_group(&stmt, &module, &path, global_store);
297
+ resolved.push(resolved_stmt);
298
+ }
299
+
300
+ StatementKind::Pattern { .. } => {
301
+ let resolved_stmt = resolve_pattern(&stmt, &module, &path, global_store);
302
+ resolved.push(resolved_stmt);
303
+ }
304
+
305
+ StatementKind::Function {
306
+ name: _,
307
+ parameters: _,
308
+ body: _,
309
+ } => {
310
+ let resolved_function = resolve_function(&stmt, &module, &path, global_store);
311
+ resolved.push(resolved_function);
312
+ }
313
+
314
+ _ => {
315
+ resolved.push(stmt);
316
+ }
317
+ }
318
+ }
319
+
320
+ resolved_map.insert(path.clone(), resolved);
321
+ }
322
+
323
+ resolved_map
324
+ }
@@ -1,9 +1,9 @@
1
1
  use crate::core::{
2
2
  parser::statement::{Statement, StatementKind},
3
3
  preprocessor::{module::Module, resolver::driver::resolve_statement},
4
- store::{function::FunctionDef, global::GlobalStore},
4
+ store::global::GlobalStore,
5
5
  };
6
- use devalang_types::Value;
6
+ use devalang_types::{FunctionDef, Value};
7
7
 
8
8
  pub fn resolve_function(
9
9
  stmt: &Statement,