@devaloop/devalang 0.0.1-alpha.1 → 0.0.1-alpha.11

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 (168) hide show
  1. package/.devalang +9 -0
  2. package/Cargo.toml +15 -6
  3. package/README.md +79 -81
  4. package/docs/CHANGELOG.md +213 -0
  5. package/docs/ROADMAP.md +11 -8
  6. package/docs/TODO.md +32 -29
  7. package/examples/bank.deva +9 -0
  8. package/examples/condition.deva +20 -0
  9. package/examples/duration.deva +9 -0
  10. package/examples/group.deva +12 -0
  11. package/examples/index.deva +12 -5
  12. package/examples/loop.deva +16 -0
  13. package/examples/samples/hat-808.wav +0 -0
  14. package/examples/synth.deva +14 -0
  15. package/examples/variables.deva +9 -0
  16. package/out-tsc/bin/devalang.exe +0 -0
  17. package/out-tsc/scripts/version/fetch.js +1 -5
  18. package/package.json +5 -4
  19. package/project-version.json +3 -3
  20. package/rust/cli/bank.rs +455 -0
  21. package/rust/cli/build.rs +114 -28
  22. package/rust/cli/check.rs +96 -103
  23. package/rust/cli/driver.rs +280 -0
  24. package/rust/cli/init.rs +79 -0
  25. package/rust/cli/install.rs +17 -0
  26. package/rust/cli/mod.rs +8 -1
  27. package/rust/cli/play.rs +193 -0
  28. package/rust/cli/template.rs +57 -0
  29. package/rust/cli/update.rs +4 -0
  30. package/rust/common/cdn.rs +11 -0
  31. package/rust/common/mod.rs +1 -0
  32. package/rust/config/driver.rs +76 -0
  33. package/rust/config/loader.rs +110 -0
  34. package/rust/config/mod.rs +2 -0
  35. package/rust/core/audio/engine.rs +242 -0
  36. package/rust/core/audio/evaluator.rs +31 -0
  37. package/rust/core/audio/interpreter/arrow_call.rs +142 -0
  38. package/rust/core/audio/interpreter/call.rs +70 -0
  39. package/rust/core/audio/interpreter/condition.rs +69 -0
  40. package/rust/core/audio/interpreter/driver.rs +236 -0
  41. package/rust/core/audio/interpreter/let_.rs +19 -0
  42. package/rust/core/audio/interpreter/load.rs +18 -0
  43. package/rust/core/audio/interpreter/loop_.rs +67 -0
  44. package/rust/core/audio/interpreter/mod.rs +12 -0
  45. package/rust/core/audio/interpreter/sleep.rs +36 -0
  46. package/rust/core/audio/interpreter/spawn.rs +84 -0
  47. package/rust/core/audio/interpreter/tempo.rs +16 -0
  48. package/rust/core/audio/interpreter/trigger.rs +102 -0
  49. package/rust/core/audio/loader/mod.rs +1 -0
  50. package/rust/core/audio/loader/trigger.rs +64 -0
  51. package/rust/core/audio/mod.rs +6 -0
  52. package/rust/core/audio/player.rs +54 -0
  53. package/rust/core/audio/renderer.rs +54 -0
  54. package/rust/core/builder/mod.rs +70 -27
  55. package/rust/core/debugger/lexer.rs +27 -0
  56. package/rust/core/debugger/mod.rs +13 -49
  57. package/rust/core/debugger/preprocessor.rs +27 -0
  58. package/rust/core/debugger/store.rs +25 -0
  59. package/rust/core/error/mod.rs +60 -0
  60. package/rust/core/lexer/handler/arrow.rs +31 -0
  61. package/rust/core/lexer/handler/at.rs +21 -0
  62. package/rust/core/lexer/handler/brace.rs +41 -0
  63. package/rust/core/lexer/handler/colon.rs +21 -0
  64. package/rust/core/lexer/handler/comment.rs +30 -0
  65. package/rust/core/lexer/handler/dot.rs +21 -0
  66. package/rust/core/lexer/handler/driver.rs +241 -0
  67. package/rust/core/lexer/handler/identifier.rs +41 -0
  68. package/rust/core/lexer/handler/indent.rs +52 -0
  69. package/rust/core/lexer/handler/mod.rs +15 -0
  70. package/rust/core/lexer/handler/newline.rs +23 -0
  71. package/rust/core/lexer/handler/number.rs +31 -0
  72. package/rust/core/lexer/handler/operator.rs +44 -0
  73. package/rust/core/lexer/handler/slash.rs +21 -0
  74. package/rust/core/lexer/handler/string.rs +63 -0
  75. package/rust/core/lexer/mod.rs +37 -319
  76. package/rust/core/lexer/token.rs +87 -0
  77. package/rust/core/mod.rs +6 -2
  78. package/rust/core/parser/driver.rs +339 -0
  79. package/rust/core/parser/handler/arrow_call.rs +151 -0
  80. package/rust/core/parser/handler/at.rs +162 -0
  81. package/rust/core/parser/handler/bank.rs +41 -0
  82. package/rust/core/parser/handler/condition.rs +74 -0
  83. package/rust/core/parser/handler/dot.rs +178 -0
  84. package/rust/core/parser/handler/identifier/call.rs +41 -0
  85. package/rust/core/parser/handler/identifier/group.rs +75 -0
  86. package/rust/core/parser/handler/identifier/let_.rs +133 -0
  87. package/rust/core/parser/handler/identifier/mod.rs +51 -0
  88. package/rust/core/parser/handler/identifier/sleep.rs +33 -0
  89. package/rust/core/parser/handler/identifier/spawn.rs +41 -0
  90. package/rust/core/parser/handler/identifier/synth.rs +65 -0
  91. package/rust/core/parser/handler/loop_.rs +72 -0
  92. package/rust/core/parser/handler/mod.rs +8 -0
  93. package/rust/core/parser/handler/tempo.rs +47 -0
  94. package/rust/core/parser/mod.rs +3 -200
  95. package/rust/core/parser/statement.rs +96 -0
  96. package/rust/core/preprocessor/loader.rs +308 -0
  97. package/rust/core/preprocessor/mod.rs +2 -24
  98. package/rust/core/preprocessor/module.rs +42 -56
  99. package/rust/core/preprocessor/processor.rs +76 -0
  100. package/rust/core/preprocessor/resolver/bank.rs +41 -51
  101. package/rust/core/preprocessor/resolver/call.rs +123 -0
  102. package/rust/core/preprocessor/resolver/condition.rs +92 -0
  103. package/rust/core/preprocessor/resolver/driver.rs +232 -0
  104. package/rust/core/preprocessor/resolver/group.rs +61 -0
  105. package/rust/core/preprocessor/resolver/let_.rs +31 -0
  106. package/rust/core/preprocessor/resolver/loop_.rs +76 -67
  107. package/rust/core/preprocessor/resolver/mod.rs +12 -111
  108. package/rust/core/preprocessor/resolver/spawn.rs +58 -0
  109. package/rust/core/preprocessor/resolver/synth.rs +50 -0
  110. package/rust/core/preprocessor/resolver/tempo.rs +40 -61
  111. package/rust/core/preprocessor/resolver/trigger.rs +90 -154
  112. package/rust/core/preprocessor/resolver/value.rs +78 -0
  113. package/rust/core/shared/bank.rs +21 -0
  114. package/rust/core/shared/duration.rs +9 -0
  115. package/rust/core/shared/mod.rs +3 -0
  116. package/rust/core/shared/value.rs +29 -0
  117. package/rust/core/store/export.rs +28 -0
  118. package/rust/core/store/global.rs +39 -0
  119. package/rust/core/store/import.rs +28 -0
  120. package/rust/core/store/mod.rs +4 -0
  121. package/rust/core/store/variable.rs +28 -0
  122. package/rust/core/utils/mod.rs +2 -0
  123. package/rust/core/utils/path.rs +31 -0
  124. package/rust/core/utils/validation.rs +37 -0
  125. package/rust/installer/bank.rs +55 -0
  126. package/rust/installer/mod.rs +1 -0
  127. package/rust/lib.rs +162 -1
  128. package/rust/main.rs +104 -31
  129. package/rust/utils/file.rs +35 -0
  130. package/rust/utils/installer.rs +56 -0
  131. package/rust/utils/logger.rs +108 -34
  132. package/rust/utils/mod.rs +5 -3
  133. package/rust/utils/{loader.rs → spinner.rs} +2 -0
  134. package/rust/utils/watcher.rs +33 -0
  135. package/templates/minimal/.devalang +5 -0
  136. package/templates/minimal/README.md +202 -0
  137. package/templates/minimal/src/index.deva +2 -0
  138. package/templates/welcome/.devalang +5 -0
  139. package/templates/welcome/README.md +202 -0
  140. package/templates/welcome/samples/kick-808.wav +0 -0
  141. package/templates/welcome/src/index.deva +13 -0
  142. package/templates/welcome/src/variables.deva +5 -0
  143. package/typescript/scripts/version/fetch.ts +1 -6
  144. package/docs/COMMANDS.md +0 -31
  145. package/docs/SYNTAX.md +0 -148
  146. package/examples/exported.deva +0 -7
  147. package/rust/audio/mod.rs +0 -1
  148. package/rust/cli/new.rs +0 -1
  149. package/rust/core/parser/at.rs +0 -142
  150. package/rust/core/parser/bank.rs +0 -42
  151. package/rust/core/parser/dot.rs +0 -107
  152. package/rust/core/parser/identifer.rs +0 -91
  153. package/rust/core/parser/loop_.rs +0 -62
  154. package/rust/core/parser/tempo.rs +0 -42
  155. package/rust/core/parser/variable.rs +0 -129
  156. package/rust/core/preprocessor/dependencies.rs +0 -54
  157. package/rust/core/preprocessor/resolver/at.rs +0 -24
  158. package/rust/core/types/cli.rs +0 -160
  159. package/rust/core/types/mod.rs +0 -7
  160. package/rust/core/types/module.rs +0 -41
  161. package/rust/core/types/parser.rs +0 -73
  162. package/rust/core/types/statement.rs +0 -105
  163. package/rust/core/types/store.rs +0 -116
  164. package/rust/core/types/token.rs +0 -83
  165. package/rust/core/types/variable.rs +0 -32
  166. package/rust/runner/executer.rs +0 -44
  167. package/rust/runner/mod.rs +0 -1
  168. package/rust/utils/path.rs +0 -46
@@ -0,0 +1,123 @@
1
+ use crate::{
2
+ core::{
3
+ parser::statement::{ Statement, StatementKind },
4
+ preprocessor::{ module::Module, resolver::driver::resolve_statement },
5
+ shared::value::Value,
6
+ store::global::GlobalStore,
7
+ },
8
+ utils::logger::{ Logger, LogLevel },
9
+ };
10
+
11
+ pub fn resolve_call(
12
+ stmt: &Statement,
13
+ module: &Module,
14
+ path: &str,
15
+ global_store: &mut GlobalStore
16
+ ) -> Statement {
17
+ let logger = Logger::new();
18
+
19
+ match &stmt.value {
20
+ Value::Identifier(ident) => {
21
+ match module.variable_table.get(ident) {
22
+ Some(Value::String(group_name)) =>
23
+ resolve_group_by_name(group_name, stmt, module, path, global_store, &logger),
24
+ Some(Value::Map(group_map)) =>
25
+ resolved_call(stmt, group_map, module, path, global_store),
26
+ Some(other) =>
27
+ error_stmt(
28
+ &logger,
29
+ module,
30
+ stmt,
31
+ &format!(
32
+ "Identifier '{ident}' must resolve to a group name or map, found {:?}",
33
+ other
34
+ )
35
+ ),
36
+ None =>
37
+ error_stmt(
38
+ &logger,
39
+ module,
40
+ stmt,
41
+ &format!("Identifier '{ident}' not found in variable table")
42
+ ),
43
+ }
44
+ }
45
+
46
+ Value::String(name) =>
47
+ resolve_group_by_name(name, stmt, module, path, global_store, &logger),
48
+
49
+ Value::Map(group_map) => resolved_call(stmt, group_map, module, path, global_store),
50
+
51
+ other =>
52
+ error_stmt(
53
+ &logger,
54
+ module,
55
+ stmt,
56
+ &format!("Call expects a group name as string or identifier, found {:?}", other)
57
+ ),
58
+ }
59
+ }
60
+
61
+ fn resolve_group_by_name(
62
+ name: &str,
63
+ stmt: &Statement,
64
+ module: &Module,
65
+ path: &str,
66
+ global_store: &mut GlobalStore,
67
+ logger: &Logger
68
+ ) -> Statement {
69
+ match module.variable_table.get(name) {
70
+ Some(Value::Map(group_map)) => resolved_call(stmt, group_map, module, path, global_store),
71
+ Some(other) =>
72
+ error_stmt(
73
+ logger,
74
+ module,
75
+ stmt,
76
+ &format!("Expected a group for '{}', but found {:?}", name, other)
77
+ ),
78
+ None =>
79
+ error_stmt(
80
+ logger,
81
+ module,
82
+ stmt,
83
+ &format!("Group '{}' not found in module '{}'", name, module.path)
84
+ ),
85
+ }
86
+ }
87
+
88
+ fn resolved_call(
89
+ stmt: &Statement,
90
+ group_map: &std::collections::HashMap<String, Value>,
91
+ module: &Module,
92
+ path: &str,
93
+ global_store: &mut GlobalStore
94
+ ) -> Statement {
95
+ let mut cloned_map = group_map.clone();
96
+
97
+ if let Some(Value::Block(stmts)) = group_map.get("body") {
98
+ let resolved = stmts
99
+ .iter()
100
+ .map(|s| resolve_statement(s, module, path, global_store))
101
+ .collect();
102
+ cloned_map.insert("body".to_string(), Value::Block(resolved));
103
+ }
104
+
105
+ Statement {
106
+ kind: StatementKind::Call,
107
+ value: Value::Map(cloned_map),
108
+ ..stmt.clone()
109
+ }
110
+ }
111
+
112
+ fn error_stmt(logger: &Logger, module: &Module, stmt: &Statement, message: &str) -> Statement {
113
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
114
+ logger.log_message(LogLevel::Error, &format!("{message}\n → at {stacktrace}"));
115
+
116
+ Statement {
117
+ kind: StatementKind::Error {
118
+ message: message.to_string(),
119
+ },
120
+ value: Value::Null,
121
+ ..stmt.clone()
122
+ }
123
+ }
@@ -0,0 +1,92 @@
1
+ use crate::{
2
+ core::{
3
+ parser::statement::{Statement, StatementKind},
4
+ preprocessor::{module::Module, resolver::driver::resolve_statement},
5
+ shared::value::Value,
6
+ store::global::GlobalStore,
7
+ },
8
+ utils::logger::Logger,
9
+ };
10
+
11
+ pub fn resolve_condition(
12
+ stmt: &Statement,
13
+ module: &Module,
14
+ path: &str,
15
+ global_store: &mut GlobalStore,
16
+ ) -> Statement {
17
+ let logger = Logger::new();
18
+
19
+ let Value::Map(condition_map) = &stmt.value else {
20
+ return type_error(&logger, module, stmt, "Expected a map in condition statement".to_string());
21
+ };
22
+
23
+ let mut resolved_map = condition_map.clone();
24
+
25
+ // Main body resolution
26
+ if let Some(Value::Block(body)) = condition_map.get("body") {
27
+ let resolved_body = resolve_block_statements(body, module, path, global_store);
28
+ resolved_map.insert("body".to_string(), Value::Block(resolved_body));
29
+ }
30
+
31
+ // Recursive resolution of next condition
32
+ if let Some(Value::Map(next_map)) = condition_map.get("next") {
33
+ let next_stmt = Statement {
34
+ kind: StatementKind::If,
35
+ value: Value::Map(next_map.clone()),
36
+ ..stmt.clone()
37
+ };
38
+
39
+ let resolved_next = resolve_condition(&next_stmt, module, path, global_store);
40
+
41
+ if let Value::Map(mut resolved_next_map) = resolved_next.value {
42
+ // Body next resolution
43
+ if let Some(Value::Block(body)) = resolved_next_map.get("body") {
44
+ let resolved_body = resolve_block_statements(body, module, path, global_store);
45
+ resolved_next_map.insert("body".to_string(), Value::Block(resolved_body));
46
+ }
47
+
48
+ resolved_map.insert("next".to_string(), Value::Map(resolved_next_map));
49
+ }
50
+ }
51
+
52
+ Statement {
53
+ kind: StatementKind::If,
54
+ value: Value::Map(resolved_map),
55
+ ..stmt.clone()
56
+ }
57
+ }
58
+
59
+ fn resolve_block_statements(
60
+ body: &[Statement],
61
+ module: &Module,
62
+ path: &str,
63
+ global_store: &mut GlobalStore,
64
+ ) -> Vec<Statement> {
65
+ body.iter()
66
+ .flat_map(|stmt| {
67
+ let resolved = resolve_statement(stmt, module, path, global_store);
68
+
69
+ if let StatementKind::Call = resolved.kind {
70
+ if let Value::Block(inner) = &resolved.value {
71
+ return inner
72
+ .iter()
73
+ .map(|s| resolve_statement(s, module, path, global_store))
74
+ .collect();
75
+ }
76
+ }
77
+
78
+ vec![resolved]
79
+ })
80
+ .collect()
81
+ }
82
+
83
+ fn type_error(logger: &Logger, module: &Module, stmt: &Statement, message: String) -> Statement {
84
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
85
+ logger.log_error_with_stacktrace(&message, &stacktrace);
86
+
87
+ Statement {
88
+ kind: StatementKind::Error { message },
89
+ value: Value::Null,
90
+ ..stmt.clone()
91
+ }
92
+ }
@@ -0,0 +1,232 @@
1
+ use std::collections::HashMap;
2
+ use crate::{
3
+ core::{
4
+ parser::statement::{ Statement, StatementKind },
5
+ preprocessor::{
6
+ loader::ModuleLoader,
7
+ module::Module,
8
+ resolver::{
9
+ bank::resolve_bank,
10
+ call::resolve_call,
11
+ condition::resolve_condition,
12
+ group::resolve_group,
13
+ let_::resolve_let,
14
+ loop_::resolve_loop,
15
+ spawn::resolve_spawn,
16
+ tempo::resolve_tempo,
17
+ trigger::resolve_trigger,
18
+ },
19
+ },
20
+ shared::value::Value,
21
+ store::global::GlobalStore,
22
+ },
23
+ utils::logger::Logger,
24
+ };
25
+
26
+ pub fn resolve_all_modules(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
27
+ for module in global_store.clone().modules.values_mut() {
28
+ resolve_imports(module_loader, global_store);
29
+ }
30
+ }
31
+
32
+ pub fn resolve_statement(
33
+ stmt: &Statement,
34
+ module: &Module,
35
+ path: &str,
36
+ global_store: &mut GlobalStore
37
+ ) -> Statement {
38
+ match &stmt.kind {
39
+ StatementKind::Trigger { entity, duration } =>
40
+ resolve_trigger(stmt, entity, &mut duration.clone(), module, path, global_store),
41
+ StatementKind::If => resolve_condition(stmt, module, path, global_store),
42
+ StatementKind::Group => resolve_group(stmt, module, path, global_store),
43
+ StatementKind::Call => resolve_call(stmt, module, path, global_store),
44
+ StatementKind::Spawn => resolve_spawn(stmt, module, path, global_store),
45
+ StatementKind::Bank => resolve_bank(stmt, module, path, global_store),
46
+ StatementKind::Tempo => resolve_tempo(stmt, module, path, global_store),
47
+ StatementKind::Loop => resolve_loop(stmt, module, path, global_store),
48
+ StatementKind::Let { name, .. } => resolve_let(stmt, name, module, path, global_store),
49
+
50
+ _ => {
51
+ let resolved_value = resolve_value(&stmt.value, module, global_store);
52
+
53
+ Statement {
54
+ value: resolved_value,
55
+ ..stmt.clone()
56
+ }
57
+ }
58
+ }
59
+ }
60
+
61
+ fn resolve_value(value: &Value, module: &Module, global_store: &mut GlobalStore) -> Value {
62
+ match value {
63
+ Value::Identifier(name) => {
64
+ if let Some(original_val) = module.variable_table.get(name) {
65
+ return resolve_value(original_val, module, global_store);
66
+ }
67
+
68
+ if let Some(export_val) = find_export_value(name, global_store) {
69
+ return resolve_value(&export_val, module, global_store);
70
+ }
71
+
72
+ eprintln!("⚠️ Unresolved identifier '{}'", name);
73
+ Value::Null
74
+ }
75
+
76
+ Value::Beat(beat_str) => {
77
+ println!("[warn] '{:?}': unresolved beat '{}'", module.path, beat_str);
78
+ Value::Beat(beat_str.clone())
79
+ }
80
+
81
+ Value::Map(map) => {
82
+ let mut resolved = HashMap::new();
83
+ for (k, v) in map {
84
+ resolved.insert(k.clone(), resolve_value(v, module, global_store));
85
+ }
86
+ Value::Map(resolved)
87
+ }
88
+
89
+ Value::Block(stmts) => {
90
+ let resolved_stmts = stmts
91
+ .iter()
92
+ .map(|stmt| resolve_statement(stmt, module, &module.path, global_store))
93
+ .collect();
94
+ Value::Block(resolved_stmts)
95
+ }
96
+
97
+ other => other.clone(),
98
+ }
99
+ }
100
+
101
+ fn find_export_value(name: &str, global_store: &GlobalStore) -> Option<Value> {
102
+ for (_path, module) in &global_store.modules {
103
+ if let Some(val) = module.export_table.get_export(name) {
104
+ return Some(val.clone());
105
+ }
106
+ }
107
+ None
108
+ }
109
+
110
+ pub fn resolve_imports(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
111
+ for (module_path, module) in global_store.clone().modules.iter_mut() {
112
+ for (name, source_path) in &module.import_table.imports {
113
+ match source_path {
114
+ Value::String(source_path) => {
115
+ if let Some(source_module) = global_store.modules.get(source_path) {
116
+ if let Some(value) = source_module.export_table.get_export(name) {
117
+ module.variable_table.set(name.clone(), value.clone());
118
+ } else {
119
+ println!(
120
+ "[warn] '{module_path}': '{name}' not found in exports of '{source_path}'"
121
+ );
122
+ }
123
+ } else {
124
+ println!(
125
+ "[warn] '{module_path}': cannot find source module '{source_path}'"
126
+ );
127
+ }
128
+ }
129
+ _ => {
130
+ println!(
131
+ "[warn] '{module_path}': expected string for import source, found {:?}",
132
+ source_path
133
+ );
134
+ }
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+ pub fn resolve_and_flatten_all_modules(
141
+ global_store: &mut GlobalStore
142
+ ) -> HashMap<String, Vec<Statement>> {
143
+ let logger = Logger::new();
144
+ let snapshot = global_store.clone();
145
+
146
+ // 1. Imports resolution
147
+ for (module_path, module) in global_store.modules.iter_mut() {
148
+ for (name, source_path) in &module.import_table.imports {
149
+ if let Value::String(source_path_str) = source_path {
150
+ match snapshot.modules.get(source_path_str) {
151
+ Some(source_module) => {
152
+ if let Some(value) = source_module.export_table.get_export(name) {
153
+ module.variable_table.set(name.clone(), value.clone());
154
+ } else {
155
+ logger.log_error_with_stacktrace(
156
+ &format!("'{name}' not found in exports of '{source_path_str}'"),
157
+ module_path
158
+ );
159
+ }
160
+ }
161
+ None => {
162
+ logger.log_error_with_stacktrace(
163
+ &format!("Cannot find source module '{source_path_str}'"),
164
+ module_path
165
+ );
166
+ }
167
+ }
168
+ } else {
169
+ logger.log_error_with_stacktrace(
170
+ &format!("Expected string for import source, found {:?}", source_path),
171
+ module_path
172
+ );
173
+ }
174
+ }
175
+ }
176
+
177
+ // 2. Statements resolution
178
+ let mut resolved_map: HashMap<String, Vec<Statement>> = HashMap::new();
179
+ for (path, module) in global_store.modules.clone() {
180
+ let mut resolved = Vec::new();
181
+
182
+ for stmt in &module.statements {
183
+ let mut stmt = stmt.clone();
184
+
185
+ match &stmt.kind {
186
+ StatementKind::Trigger { entity, duration } => {
187
+ let resolved_stmt = resolve_trigger(
188
+ &stmt,
189
+ entity.as_str(),
190
+ &mut duration.clone(),
191
+ &module,
192
+ &path,
193
+ global_store
194
+ );
195
+ resolved.push(resolved_stmt);
196
+ }
197
+
198
+ StatementKind::Loop => {
199
+ let resolved_stmt = resolve_loop(&stmt, &module, &path, global_store);
200
+ resolved.push(resolved_stmt);
201
+ }
202
+
203
+ StatementKind::Bank => {
204
+ let resolved_stmt = resolve_bank(&stmt, &module, &path, global_store);
205
+ resolved.push(resolved_stmt);
206
+ }
207
+
208
+ StatementKind::Tempo => {
209
+ let resolved_stmt = resolve_tempo(&stmt, &module, &path, global_store);
210
+ resolved.push(resolved_stmt);
211
+ }
212
+
213
+ StatementKind::Import { .. } | StatementKind::Export { .. } => {
214
+ resolved.push(stmt.clone());
215
+ }
216
+
217
+ StatementKind::Group => {
218
+ let resolved_stmt = resolve_group(&stmt, &module, &path, global_store);
219
+ resolved.push(resolved_stmt);
220
+ }
221
+
222
+ _ => {
223
+ resolved.push(stmt);
224
+ }
225
+ }
226
+ }
227
+
228
+ resolved_map.insert(path.clone(), resolved);
229
+ }
230
+
231
+ resolved_map
232
+ }
@@ -0,0 +1,61 @@
1
+ use std::collections::HashMap;
2
+
3
+ use crate::{
4
+ core::{
5
+ parser::statement::{ Statement, StatementKind },
6
+ preprocessor::{ module::Module, resolver::driver::resolve_statement },
7
+ shared::value::Value,
8
+ store::{ global::GlobalStore, variable::VariableTable },
9
+ },
10
+ utils::logger::{ LogLevel, Logger },
11
+ };
12
+
13
+ pub fn resolve_group(
14
+ stmt: &Statement,
15
+ module: &Module,
16
+ path: &str,
17
+ global_store: &mut GlobalStore
18
+ ) -> Statement {
19
+ let logger = Logger::new();
20
+
21
+ let Value::Map(group_map) = &stmt.value else {
22
+ return type_error(&logger, module, stmt, "Expected a map in group statement".to_string());
23
+ };
24
+
25
+ let mut resolved_map = group_map.clone();
26
+
27
+ if let Some(Value::Block(body)) = group_map.get("body") {
28
+ let resolved_body = resolve_block_statements(body, module, path, global_store);
29
+ resolved_map.insert("body".to_string(), Value::Block(resolved_body));
30
+ } else {
31
+ logger.log_message(LogLevel::Warning, "group without a body");
32
+ }
33
+
34
+ Statement {
35
+ kind: StatementKind::Group,
36
+ value: Value::Map(resolved_map),
37
+ ..stmt.clone()
38
+ }
39
+ }
40
+
41
+ fn resolve_block_statements(
42
+ body: &[Statement],
43
+ module: &Module,
44
+ path: &str,
45
+ global_store: &mut GlobalStore
46
+ ) -> Vec<Statement> {
47
+ body.iter()
48
+ .map(|stmt| resolve_statement(stmt, module, path, global_store))
49
+ .collect()
50
+ }
51
+
52
+ fn type_error(logger: &Logger, module: &Module, stmt: &Statement, message: String) -> Statement {
53
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
54
+ logger.log_error_with_stacktrace(&message, &stacktrace);
55
+
56
+ Statement {
57
+ kind: StatementKind::Error { message },
58
+ value: Value::Null,
59
+ ..stmt.clone()
60
+ }
61
+ }
@@ -0,0 +1,31 @@
1
+ use crate::
2
+ core::{
3
+ parser::statement:: Statement ,
4
+ preprocessor::{
5
+ module::Module,
6
+ resolver:: value::resolve_value ,
7
+ },
8
+ store:: global::GlobalStore ,
9
+ }
10
+ ;
11
+
12
+ pub fn resolve_let(
13
+ stmt: &Statement,
14
+ name: &str,
15
+ module: &Module,
16
+ path: &str,
17
+ global_store: &mut GlobalStore
18
+ ) -> Statement {
19
+ let resolved_value = resolve_value(&stmt.value, module, global_store);
20
+
21
+ if let Some(current_mod) = global_store.modules.get_mut(path) {
22
+ current_mod.variable_table.set(name.to_string(), resolved_value.clone());
23
+ } else {
24
+ eprintln!("[resolve_statement] ❌ Module path not found: {path}");
25
+ }
26
+
27
+ Statement {
28
+ value: resolved_value,
29
+ ..stmt.clone()
30
+ }
31
+ }