@devaloop/devalang 0.0.1-alpha.8 → 0.0.1-beta.1

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 (277) hide show
  1. package/.cargo/config.toml +2 -0
  2. package/.devalang +10 -4
  3. package/.github/workflows/ci.yml +103 -0
  4. package/Cargo.toml +80 -48
  5. package/README.md +135 -158
  6. package/docs/CHANGELOG.md +413 -1
  7. package/docs/CONTRIBUTING.md +101 -0
  8. package/docs/ROADMAP.md +10 -7
  9. package/docs/TODO.md +21 -9
  10. package/examples/automation.deva +42 -0
  11. package/examples/bank.deva +7 -0
  12. package/examples/condition.deva +8 -12
  13. package/examples/duration.deva +9 -0
  14. package/examples/events.deva +12 -0
  15. package/examples/function.deva +15 -0
  16. package/examples/group.deva +3 -3
  17. package/examples/index.deva +57 -10
  18. package/examples/loop.deva +7 -12
  19. package/examples/pattern.deva +8 -0
  20. package/examples/plugin.deva +16 -0
  21. package/examples/synth.deva +14 -0
  22. package/examples/variables.deva +2 -2
  23. package/out-tsc/bin/index.d.ts +2 -0
  24. package/out-tsc/bin/index.js +51 -7
  25. package/out-tsc/core/functions/index.d.ts +37 -0
  26. package/out-tsc/core/functions/index.js +76 -0
  27. package/out-tsc/core/index.d.ts +6 -0
  28. package/out-tsc/core/index.js +22 -0
  29. package/out-tsc/core/types/index.d.ts +4 -0
  30. package/out-tsc/core/types/index.js +20 -0
  31. package/out-tsc/core/types/plugin.d.ts +18 -0
  32. package/out-tsc/core/types/plugin.js +2 -0
  33. package/out-tsc/core/types/result.d.ts +27 -0
  34. package/out-tsc/core/types/result.js +2 -0
  35. package/out-tsc/core/types/statement.d.ts +106 -0
  36. package/out-tsc/core/types/statement.js +2 -0
  37. package/out-tsc/core/types/value.d.ts +43 -0
  38. package/out-tsc/core/types/value.js +2 -0
  39. package/out-tsc/index.d.ts +7 -0
  40. package/out-tsc/index.js +42 -1
  41. package/out-tsc/pkg/devalang_core.d.ts +13 -0
  42. package/out-tsc/pkg/devalang_core.js +50 -0
  43. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +33 -0
  44. package/out-tsc/scripts/copy-wasm-dts.d.ts +1 -0
  45. package/out-tsc/scripts/copy-wasm-dts.js +73 -0
  46. package/out-tsc/scripts/postinstall.d.ts +1 -0
  47. package/out-tsc/scripts/postinstall.js +83 -0
  48. package/out-tsc/scripts/version/bump.d.ts +1 -0
  49. package/out-tsc/scripts/version/fetch.d.ts +1 -0
  50. package/out-tsc/scripts/version/fetch.js +1 -5
  51. package/out-tsc/scripts/version/index.d.ts +1 -0
  52. package/out-tsc/scripts/version/sync.d.ts +1 -0
  53. package/package.json +28 -7
  54. package/project-version.json +4 -4
  55. package/rust/cli/bank/api.rs +122 -0
  56. package/rust/cli/bank/commands.rs +275 -0
  57. package/rust/cli/bank/mod.rs +29 -0
  58. package/rust/cli/build/commands.rs +103 -0
  59. package/rust/cli/build/mod.rs +2 -0
  60. package/rust/cli/build/process.rs +146 -0
  61. package/rust/cli/check/mod.rs +208 -0
  62. package/rust/cli/discover/commands.rs +253 -0
  63. package/rust/cli/discover/config.rs +111 -0
  64. package/rust/cli/discover/fs.rs +19 -0
  65. package/rust/cli/discover/install.rs +103 -0
  66. package/rust/cli/discover/metadata.rs +48 -0
  67. package/rust/cli/discover/mod.rs +5 -0
  68. package/rust/cli/{init.rs → init/commands.rs} +32 -23
  69. package/rust/cli/init/mod.rs +1 -0
  70. package/rust/cli/install/addon.rs +118 -0
  71. package/rust/cli/install/bank.rs +53 -0
  72. package/rust/cli/install/commands.rs +35 -0
  73. package/rust/cli/install/mod.rs +4 -0
  74. package/rust/cli/install/plugin.rs +61 -0
  75. package/rust/cli/login/commands.rs +124 -0
  76. package/rust/cli/login/mod.rs +1 -0
  77. package/rust/cli/mod.rs +12 -205
  78. package/rust/cli/parser.rs +314 -0
  79. package/rust/cli/play/commands.rs +324 -0
  80. package/rust/cli/play/io.rs +17 -0
  81. package/rust/cli/play/mod.rs +5 -0
  82. package/rust/cli/play/process.rs +150 -0
  83. package/rust/cli/play/realtime.rs +91 -0
  84. package/rust/cli/play/utils.rs +23 -0
  85. package/rust/cli/telemetry/commands.rs +22 -0
  86. package/rust/cli/telemetry/event_creator.rs +80 -0
  87. package/rust/cli/telemetry/mod.rs +3 -0
  88. package/rust/cli/telemetry/send.rs +51 -0
  89. package/rust/cli/{template.rs → template/commands.rs} +69 -57
  90. package/rust/cli/template/mod.rs +1 -0
  91. package/rust/cli/update/commands.rs +6 -0
  92. package/rust/cli/update/mod.rs +1 -0
  93. package/rust/config/driver.rs +103 -0
  94. package/rust/config/mod.rs +3 -16
  95. package/rust/config/ops.rs +26 -0
  96. package/rust/config/settings.rs +101 -0
  97. package/rust/core/audio/engine/helpers.rs +170 -0
  98. package/rust/core/audio/engine/mod.rs +7 -0
  99. package/rust/core/audio/engine/sample.rs +366 -0
  100. package/rust/core/audio/engine/synth.rs +325 -0
  101. package/rust/core/audio/evaluator.rs +310 -31
  102. package/rust/core/audio/interpreter/arrow_call.rs +311 -0
  103. package/rust/core/audio/interpreter/automate.rs +18 -0
  104. package/rust/core/audio/interpreter/call.rs +294 -42
  105. package/rust/core/audio/interpreter/condition.rs +71 -65
  106. package/rust/core/audio/interpreter/driver.rs +542 -204
  107. package/rust/core/audio/interpreter/function.rs +26 -0
  108. package/rust/core/audio/interpreter/let_.rs +38 -19
  109. package/rust/core/audio/interpreter/load.rs +19 -18
  110. package/rust/core/audio/interpreter/loop_.rs +114 -59
  111. package/rust/core/audio/interpreter/mod.rs +14 -11
  112. package/rust/core/audio/interpreter/sleep.rs +28 -36
  113. package/rust/core/audio/interpreter/spawn.rs +252 -65
  114. package/rust/core/audio/interpreter/tempo.rs +40 -16
  115. package/rust/core/audio/interpreter/trigger.rs +239 -69
  116. package/rust/core/audio/loader/mod.rs +1 -1
  117. package/rust/core/audio/loader/trigger.rs +97 -52
  118. package/rust/core/audio/mod.rs +7 -6
  119. package/rust/core/audio/player.rs +70 -54
  120. package/rust/core/audio/renderer.rs +54 -57
  121. package/rust/core/audio/special/easing.rs +189 -0
  122. package/rust/core/audio/special/env.rs +45 -0
  123. package/rust/core/audio/special/math.rs +134 -0
  124. package/rust/core/audio/special/mod.rs +9 -0
  125. package/rust/core/audio/special/modulator.rs +143 -0
  126. package/rust/core/builder/mod.rs +86 -80
  127. package/rust/core/debugger/lexer.rs +27 -27
  128. package/rust/core/debugger/mod.rs +30 -21
  129. package/rust/core/debugger/module.rs +55 -0
  130. package/rust/core/debugger/preprocessor.rs +27 -27
  131. package/rust/core/debugger/store.rs +40 -25
  132. package/rust/core/error/mod.rs +269 -60
  133. package/rust/core/lexer/driver.rs +61 -0
  134. package/rust/core/lexer/handler/arrow.rs +82 -0
  135. package/rust/core/lexer/handler/at.rs +21 -21
  136. package/rust/core/lexer/handler/brace.rs +41 -41
  137. package/rust/core/lexer/handler/colon.rs +21 -21
  138. package/rust/core/lexer/handler/comment.rs +30 -30
  139. package/rust/core/lexer/handler/dot.rs +21 -21
  140. package/rust/core/lexer/handler/driver.rs +337 -215
  141. package/rust/core/lexer/handler/identifier.rs +47 -40
  142. package/rust/core/lexer/handler/indent.rs +66 -52
  143. package/rust/core/lexer/handler/mod.rs +15 -13
  144. package/rust/core/lexer/handler/newline.rs +23 -23
  145. package/rust/core/lexer/handler/number.rs +31 -31
  146. package/rust/core/lexer/handler/operator.rs +46 -44
  147. package/rust/core/lexer/handler/parenthesis.rs +41 -0
  148. package/rust/core/lexer/handler/slash.rs +21 -0
  149. package/rust/core/lexer/handler/string.rs +63 -63
  150. package/rust/core/lexer/mod.rs +3 -30
  151. package/rust/core/lexer/token.rs +21 -12
  152. package/rust/core/mod.rs +10 -10
  153. package/rust/core/parser/driver.rs +584 -312
  154. package/rust/core/parser/handler/arrow_call.rs +253 -0
  155. package/rust/core/parser/handler/at.rs +279 -162
  156. package/rust/core/parser/handler/bank.rs +104 -41
  157. package/rust/core/parser/handler/condition.rs +83 -74
  158. package/rust/core/parser/handler/dot.rs +148 -112
  159. package/rust/core/parser/handler/identifier/automate.rs +254 -0
  160. package/rust/core/parser/handler/identifier/call.rs +91 -0
  161. package/rust/core/parser/handler/identifier/emit.rs +70 -0
  162. package/rust/core/parser/handler/identifier/function.rs +113 -0
  163. package/rust/core/parser/handler/identifier/group.rs +89 -0
  164. package/rust/core/parser/handler/identifier/let_.rs +173 -0
  165. package/rust/core/parser/handler/identifier/mod.rs +55 -0
  166. package/rust/core/parser/handler/identifier/on.rs +107 -0
  167. package/rust/core/parser/handler/identifier/print.rs +49 -0
  168. package/rust/core/parser/handler/identifier/sleep.rs +43 -0
  169. package/rust/core/parser/handler/identifier/spawn.rs +91 -0
  170. package/rust/core/parser/handler/identifier/synth.rs +135 -0
  171. package/rust/core/parser/handler/loop_.rs +194 -66
  172. package/rust/core/parser/handler/mod.rs +9 -7
  173. package/rust/core/parser/handler/pattern.rs +74 -0
  174. package/rust/core/parser/handler/tempo.rs +57 -47
  175. package/rust/core/parser/mod.rs +3 -4
  176. package/rust/core/parser/statement.rs +11 -88
  177. package/rust/core/plugin/loader.rs +137 -0
  178. package/rust/core/plugin/mod.rs +2 -0
  179. package/rust/core/plugin/runner.rs +347 -0
  180. package/rust/core/preprocessor/loader.rs +637 -179
  181. package/rust/core/preprocessor/mod.rs +4 -4
  182. package/rust/core/preprocessor/module.rs +60 -53
  183. package/rust/core/preprocessor/processor.rs +114 -67
  184. package/rust/core/preprocessor/resolver/bank.rs +49 -47
  185. package/rust/core/preprocessor/resolver/call.rs +124 -53
  186. package/rust/core/preprocessor/resolver/condition.rs +95 -66
  187. package/rust/core/preprocessor/resolver/driver.rs +324 -182
  188. package/rust/core/preprocessor/resolver/function.rs +69 -0
  189. package/rust/core/preprocessor/resolver/group.rs +94 -118
  190. package/rust/core/preprocessor/resolver/let_.rs +32 -0
  191. package/rust/core/preprocessor/resolver/loop_.rs +318 -145
  192. package/rust/core/preprocessor/resolver/mod.rs +16 -10
  193. package/rust/core/preprocessor/resolver/pattern.rs +83 -0
  194. package/rust/core/preprocessor/resolver/spawn.rs +99 -53
  195. package/rust/core/preprocessor/resolver/synth.rs +54 -0
  196. package/rust/core/preprocessor/resolver/tempo.rs +48 -49
  197. package/rust/core/preprocessor/resolver/trigger.rs +116 -111
  198. package/rust/core/preprocessor/resolver/value.rs +176 -0
  199. package/rust/core/store/export.rs +28 -28
  200. package/rust/core/store/function.rs +40 -0
  201. package/rust/core/store/global.rs +61 -39
  202. package/rust/core/store/import.rs +28 -28
  203. package/rust/core/store/mod.rs +5 -4
  204. package/rust/core/store/variable.rs +51 -28
  205. package/rust/core/utils/mod.rs +1 -2
  206. package/rust/core/utils/path.rs +37 -46
  207. package/rust/lib.rs +308 -117
  208. package/rust/main.rs +364 -65
  209. package/rust/types/Cargo.toml +11 -0
  210. package/rust/types/src/addons.rs +55 -0
  211. package/rust/types/src/ast.rs +202 -0
  212. package/rust/types/src/config.rs +74 -0
  213. package/rust/types/src/lib.rs +12 -0
  214. package/rust/types/src/telemetry.rs +85 -0
  215. package/rust/utils/Cargo.toml +26 -0
  216. package/rust/utils/src/error.rs +186 -0
  217. package/rust/utils/src/file.rs +94 -0
  218. package/rust/utils/src/first_usage.rs +97 -0
  219. package/rust/utils/{mod.rs → src/lib.rs} +9 -6
  220. package/rust/utils/{logger.rs → src/logger.rs} +200 -123
  221. package/rust/utils/src/path.rs +88 -0
  222. package/rust/utils/src/signature.rs +41 -0
  223. package/rust/utils/{spinner.rs → src/spinner.rs} +20 -21
  224. package/rust/utils/src/version.rs +27 -0
  225. package/rust/utils/{watcher.rs → src/watcher.rs} +46 -33
  226. package/rust/web/api.rs +5 -0
  227. package/rust/web/cdn.rs +34 -0
  228. package/rust/web/mod.rs +3 -0
  229. package/rust/web/sso.rs +5 -0
  230. package/templates/minimal/README.md +143 -127
  231. package/templates/welcome/README.md +143 -127
  232. package/templates/welcome/src/index.deva +56 -8
  233. package/templates/welcome/src/variables.deva +2 -4
  234. package/tests/integration.rs +21 -0
  235. package/tests/rust/cli_check_build.rs +21 -0
  236. package/tests/rust/cli_help.rs +12 -0
  237. package/tests/rust/cli_template_list.rs +10 -0
  238. package/tests/rust/cli_version.rs +11 -0
  239. package/tests/typescript/index.spec.ts +136 -0
  240. package/tests/typescript/playhead.spec.ts +36 -0
  241. package/tests/typescript/render_e2e.spec.ts +77 -0
  242. package/tsconfig.json +12 -10
  243. package/typescript/bin/index.ts +19 -5
  244. package/typescript/core/functions/index.ts +83 -0
  245. package/typescript/core/index.ts +6 -0
  246. package/typescript/core/types/index.ts +4 -0
  247. package/typescript/core/types/plugin.ts +19 -0
  248. package/typescript/core/types/result.ts +29 -0
  249. package/typescript/core/types/statement.ts +47 -0
  250. package/typescript/core/types/value.ts +29 -0
  251. package/typescript/index.ts +8 -1
  252. package/typescript/pkg/devalang_core.d.ts +4 -0
  253. package/typescript/pkg/devalang_core.ts +49 -0
  254. package/typescript/scripts/copy-wasm-dts.ts +41 -0
  255. package/typescript/scripts/postinstall.ts +85 -0
  256. package/typescript/scripts/version/bump.ts +0 -1
  257. package/typescript/scripts/version/fetch.ts +1 -6
  258. package/typescript/scripts/version/index.ts +0 -1
  259. package/docs/COMMANDS.md +0 -85
  260. package/docs/CONFIG.md +0 -30
  261. package/docs/SYNTAX.md +0 -210
  262. package/out-tsc/bin/devalang.exe +0 -0
  263. package/out-tsc/scripts/postbuild.js +0 -11
  264. package/rust/cli/build.rs +0 -137
  265. package/rust/cli/check.rs +0 -117
  266. package/rust/cli/play.rs +0 -193
  267. package/rust/config/loader.rs +0 -13
  268. package/rust/core/audio/engine.rs +0 -126
  269. package/rust/core/parser/handler/identifier.rs +0 -262
  270. package/rust/core/shared/duration.rs +0 -8
  271. package/rust/core/shared/mod.rs +0 -2
  272. package/rust/core/shared/value.rs +0 -18
  273. package/rust/core/utils/validation.rs +0 -35
  274. package/rust/utils/file.rs +0 -35
  275. package/rust/utils/signature.rs +0 -17
  276. package/rust/utils/version.rs +0 -15
  277. package/typescript/scripts/postbuild.ts +0 -8
@@ -1,182 +1,324 @@
1
- use std::collections::HashMap;
2
- use crate::{
3
- core::{
4
- parser::statement::{ self, Statement, StatementKind },
5
- preprocessor::{
6
- loader::ModuleLoader,
7
- module::Module,
8
- resolver::{
9
- bank::resolve_bank, call::resolve_call, condition::resolve_condition, group::resolve_group, loop_::resolve_loop, spawn::resolve_spawn, tempo::resolve_tempo, trigger::resolve_trigger
10
- },
11
- },
12
- shared::{ duration::Duration, value::Value },
13
- store::global::GlobalStore,
14
- utils::validation::{ is_valid_entity, is_valid_identifier },
15
- },
16
- utils::logger::Logger,
17
- };
18
-
19
- pub fn resolve_all_modules(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
20
- for module in global_store.clone().modules.values_mut() {
21
- resolve_imports(module_loader, global_store);
22
- }
23
- }
24
-
25
- pub fn resolve_statement(
26
- stmt: &Statement,
27
- module: &Module,
28
- path: &str,
29
- global_store: &GlobalStore
30
- ) -> Statement {
31
- match &stmt.kind {
32
- StatementKind::Trigger { entity, duration } => {
33
- resolve_trigger(
34
- &mut stmt.clone(),
35
- entity,
36
- &mut duration.clone(),
37
- module,
38
- path,
39
- global_store
40
- )
41
- }
42
-
43
- StatementKind::If => { resolve_condition(stmt, module, path, global_store) }
44
-
45
- StatementKind::Group => { resolve_group(stmt, module, path, global_store) }
46
-
47
- StatementKind::Call => { resolve_call(stmt, module, path, global_store) }
48
-
49
- StatementKind::Spawn => { resolve_spawn(stmt, module, path, global_store) }
50
-
51
- // TODO: Handle other statement kinds if necessary
52
- // ...
53
-
54
- _ => stmt.clone(),
55
- }
56
- }
57
-
58
- pub fn resolve_imports(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
59
- for (module_path, module) in global_store.clone().modules.iter_mut() {
60
- for (name, source_path) in &module.import_table.imports {
61
- match source_path {
62
- Value::String(source_path) => {
63
- if let Some(source_module) = global_store.modules.get(source_path) {
64
- if let Some(value) = source_module.export_table.get_export(name) {
65
- module.variable_table.set(name.clone(), value.clone());
66
- } else {
67
- println!(
68
- "[warn] '{module_path}': '{name}' not found in exports of '{source_path}'"
69
- );
70
- }
71
- } else {
72
- println!(
73
- "[warn] '{module_path}': cannot find source module '{source_path}'"
74
- );
75
- }
76
- }
77
- _ => {
78
- println!(
79
- "[warn] '{module_path}': expected string for import source, found {:?}",
80
- source_path
81
- );
82
- }
83
- }
84
- }
85
- }
86
- }
87
-
88
- pub fn resolve_and_flatten_all_modules(
89
- global_store: &mut GlobalStore
90
- ) -> HashMap<String, Vec<Statement>> {
91
- let logger = Logger::new();
92
- let snapshot = global_store.clone();
93
-
94
- // 1. Imports resolution
95
- for (module_path, module) in global_store.modules.iter_mut() {
96
- for (name, source_path) in &module.import_table.imports {
97
- if let Value::String(source_path_str) = source_path {
98
- match snapshot.modules.get(source_path_str) {
99
- Some(source_module) => {
100
- if let Some(value) = source_module.export_table.get_export(name) {
101
- module.variable_table.set(name.clone(), value.clone());
102
- } else {
103
- logger.log_error_with_stacktrace(
104
- &format!("'{name}' not found in exports of '{source_path_str}'"),
105
- module_path
106
- );
107
- }
108
- }
109
- None => {
110
- logger.log_error_with_stacktrace(
111
- &format!("Cannot find source module '{source_path_str}'"),
112
- module_path
113
- );
114
- }
115
- }
116
- } else {
117
- logger.log_error_with_stacktrace(
118
- &format!("Expected string for import source, found {:?}", source_path),
119
- module_path
120
- );
121
- }
122
- }
123
- }
124
-
125
- // 2. Statements resolution
126
- let mut resolved_map: HashMap<String, Vec<Statement>> = HashMap::new();
127
- let store_snapshot = global_store.clone();
128
-
129
- for (path, module) in &store_snapshot.modules {
130
- let mut resolved = Vec::new();
131
-
132
- for stmt in &module.statements {
133
- let mut stmt = stmt.clone();
134
-
135
- match &stmt.kind {
136
- StatementKind::Trigger { entity, duration } => {
137
- let resolved_stmt = resolve_trigger(
138
- &stmt,
139
- entity.as_str(),
140
- &mut duration.clone(),
141
- &module,
142
- &path,
143
- &store_snapshot
144
- );
145
- resolved.push(resolved_stmt);
146
- }
147
-
148
- StatementKind::Loop => {
149
- let resolved_stmt = resolve_loop(&stmt, &module, &path, &store_snapshot);
150
- resolved.push(resolved_stmt);
151
- }
152
-
153
- StatementKind::Bank => {
154
- let resolved_stmt = resolve_bank(&stmt, &module, &path, &store_snapshot);
155
- resolved.push(resolved_stmt);
156
- }
157
-
158
- StatementKind::Tempo => {
159
- let resolved_stmt = resolve_tempo(&stmt, &module, &path, &store_snapshot);
160
- resolved.push(resolved_stmt);
161
- }
162
-
163
- StatementKind::Import { .. } | StatementKind::Export { .. } => {
164
- resolved.push(stmt.clone());
165
- }
166
-
167
- StatementKind::Group => {
168
- let resolved_stmt = resolve_group(&stmt, &module, &path, &store_snapshot);
169
- resolved.push(resolved_stmt);
170
- }
171
-
172
- _ => {
173
- resolved.push(stmt);
174
- }
175
- }
176
- }
177
-
178
- resolved_map.insert(path.clone(), resolved);
179
- }
180
-
181
- resolved_map
182
- }
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
+ }
@@ -0,0 +1,69 @@
1
+ use crate::core::{
2
+ parser::statement::{Statement, StatementKind},
3
+ preprocessor::{module::Module, resolver::driver::resolve_statement},
4
+ store::{function::FunctionDef, global::GlobalStore},
5
+ };
6
+ use devalang_types::Value;
7
+
8
+ pub fn resolve_function(
9
+ stmt: &Statement,
10
+ module: &Module,
11
+ path: &str,
12
+ global_store: &mut GlobalStore,
13
+ ) -> Statement {
14
+ if let StatementKind::Function {
15
+ name,
16
+ parameters,
17
+ body,
18
+ } = &stmt.kind
19
+ {
20
+ let resolved_body = resolve_block_statements(body, module, path, global_store);
21
+
22
+ global_store.functions.add_function(FunctionDef {
23
+ name: name.clone(),
24
+ parameters: parameters.clone(),
25
+ body: resolved_body.clone(),
26
+ });
27
+
28
+ if let Some(current_mod) = global_store.modules.get_mut(path) {
29
+ current_mod.function_table.add_function(FunctionDef {
30
+ name: name.clone(),
31
+ parameters: parameters.clone(),
32
+ body: resolved_body.clone(),
33
+ });
34
+ } else {
35
+ eprintln!("[resolve_statement] ❌ Module path not found: {path}");
36
+ }
37
+
38
+ Statement {
39
+ kind: StatementKind::Function {
40
+ name: name.clone(),
41
+ parameters: parameters.clone(),
42
+ body: resolved_body,
43
+ },
44
+ value: Value::Null,
45
+ ..stmt.clone()
46
+ }
47
+ } else {
48
+ Statement {
49
+ kind: StatementKind::Error {
50
+ message: "Expected a function statement".to_string(),
51
+ },
52
+ value: Value::Null,
53
+ ..stmt.clone()
54
+ }
55
+ }
56
+ }
57
+
58
+ fn resolve_block_statements(
59
+ body: &[Statement],
60
+ module: &Module,
61
+ path: &str,
62
+ global_store: &mut GlobalStore,
63
+ ) -> Vec<Statement> {
64
+ body.iter()
65
+ .map(|stmt| resolve_statement(stmt, module, path, global_store))
66
+ .collect()
67
+ }
68
+
69
+ // (removed unused helper type_error)