@devaloop/devalang 0.0.1-alpha.7 → 0.0.1-alpha.8

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 (61) hide show
  1. package/Cargo.toml +1 -1
  2. package/README.md +29 -10
  3. package/docs/CHANGELOG.md +22 -2
  4. package/docs/ROADMAP.md +2 -2
  5. package/docs/SYNTAX.md +41 -7
  6. package/docs/TODO.md +3 -3
  7. package/examples/condition.deva +24 -0
  8. package/examples/index.deva +4 -5
  9. package/examples/variables.deva +1 -1
  10. package/out-tsc/bin/devalang.exe +0 -0
  11. package/package.json +1 -1
  12. package/project-version.json +3 -3
  13. package/rust/cli/build.rs +6 -1
  14. package/rust/core/audio/evaluator.rs +31 -0
  15. package/rust/core/audio/interpreter/call.rs +42 -0
  16. package/rust/core/audio/interpreter/condition.rs +65 -0
  17. package/rust/core/audio/interpreter/driver.rs +204 -0
  18. package/rust/core/audio/interpreter/let_.rs +19 -0
  19. package/rust/core/audio/interpreter/load.rs +18 -0
  20. package/rust/core/audio/interpreter/loop_.rs +59 -0
  21. package/rust/core/audio/interpreter/mod.rs +11 -0
  22. package/rust/core/audio/interpreter/sleep.rs +36 -0
  23. package/rust/core/audio/interpreter/spawn.rs +65 -0
  24. package/rust/core/audio/interpreter/tempo.rs +16 -0
  25. package/rust/core/audio/interpreter/trigger.rs +69 -0
  26. package/rust/core/audio/loader/mod.rs +1 -0
  27. package/rust/core/audio/{loader.rs → loader/trigger.rs} +3 -1
  28. package/rust/core/audio/mod.rs +2 -1
  29. package/rust/core/audio/{render.rs → renderer.rs} +6 -2
  30. package/rust/core/builder/mod.rs +1 -1
  31. package/rust/core/debugger/lexer.rs +1 -1
  32. package/rust/core/debugger/mod.rs +1 -0
  33. package/rust/core/debugger/store.rs +25 -0
  34. package/rust/core/error/mod.rs +1 -1
  35. package/rust/core/lexer/handler/driver.rs +215 -0
  36. package/rust/core/lexer/handler/identifier.rs +2 -0
  37. package/rust/core/lexer/handler/mod.rs +3 -227
  38. package/rust/core/lexer/handler/operator.rs +44 -0
  39. package/rust/core/lexer/mod.rs +1 -1
  40. package/rust/core/lexer/token.rs +36 -9
  41. package/rust/core/parser/driver.rs +312 -0
  42. package/rust/core/parser/handler/at.rs +3 -7
  43. package/rust/core/parser/handler/bank.rs +5 -2
  44. package/rust/core/parser/handler/condition.rs +74 -0
  45. package/rust/core/parser/handler/dot.rs +1 -1
  46. package/rust/core/parser/handler/identifier.rs +38 -36
  47. package/rust/core/parser/handler/loop_.rs +1 -1
  48. package/rust/core/parser/handler/mod.rs +2 -1
  49. package/rust/core/parser/handler/tempo.rs +1 -1
  50. package/rust/core/parser/mod.rs +3 -237
  51. package/rust/core/parser/statement.rs +29 -36
  52. package/rust/core/preprocessor/loader.rs +7 -6
  53. package/rust/core/preprocessor/processor.rs +1 -1
  54. package/rust/core/preprocessor/resolver/call.rs +53 -0
  55. package/rust/core/preprocessor/resolver/condition.rs +66 -0
  56. package/rust/core/preprocessor/resolver/driver.rs +182 -0
  57. package/rust/core/preprocessor/resolver/group.rs +89 -84
  58. package/rust/core/preprocessor/resolver/mod.rs +5 -153
  59. package/rust/core/preprocessor/resolver/spawn.rs +53 -0
  60. package/rust/core/audio/interpreter.rs +0 -317
  61. package/rust/core/lexer/handler/equal.rs +0 -32
@@ -1,238 +1,4 @@
1
- pub mod statement;
2
- pub mod handler;
3
-
4
- use crate::core::{
5
- lexer::token::{ Token, TokenKind },
6
- parser::{
7
- handler::{
8
- at::parse_at_token,
9
- bank::parse_bank_token,
10
- dot::parse_dot_token,
11
- identifier::parse_identifier_token,
12
- loop_::parse_loop_token,
13
- tempo::parse_tempo_token,
14
- },
15
- statement::{ Statement, StatementKind },
16
- },
17
- shared::value::Value,
18
- store::global::GlobalStore,
19
- };
20
-
21
- #[derive(Debug, Clone, PartialEq)]
22
- pub struct Parser {
23
- pub resolve_modules: bool,
24
- pub tokens: Vec<Token>,
25
- pub token_index: usize,
26
- pub current_module: String,
27
- pub previous: Option<Token>,
28
- }
29
-
30
- impl Parser {
31
- pub fn new() -> Self {
32
- Parser {
33
- resolve_modules: false,
34
- tokens: Vec::new(),
35
- token_index: 0,
36
- current_module: String::new(),
37
- previous: None,
38
- }
39
- }
40
-
41
- pub fn set_current_module(&mut self, module_path: String) {
42
- self.current_module = module_path;
43
- }
44
-
45
- pub fn advance(&mut self) -> Option<&Token> {
46
- if self.is_eof() {
47
- return None;
48
- }
49
-
50
- self.previous = self.tokens.get(self.token_index).cloned(); // mémorise avant de bouger
51
- self.token_index += 1;
52
-
53
- self.tokens.get(self.token_index - 1)
54
- }
55
-
56
- pub fn match_token(&mut self, kind: TokenKind) -> bool {
57
- if let Some(tok) = self.peek() {
58
- if tok.kind == kind {
59
- self.advance();
60
- return true;
61
- }
62
- }
63
- false
64
- }
65
-
66
- pub fn previous_clone(&self) -> Option<Token> {
67
- self.previous.clone()
68
- }
69
-
70
- pub fn parse_block(
71
- &self,
72
- tokens: Vec<Token>,
73
- global_store: &mut GlobalStore
74
- ) -> Vec<Statement> {
75
- let mut inner_parser = Parser {
76
- resolve_modules: self.resolve_modules,
77
- tokens,
78
- token_index: 0,
79
- current_module: self.current_module.clone(),
80
- previous: None,
81
- };
82
-
83
- inner_parser.parse_tokens(inner_parser.tokens.clone(), global_store)
84
- }
85
-
86
- pub fn parse_tokens(
87
- &mut self,
88
- tokens: Vec<Token>,
89
- global_store: &mut GlobalStore
90
- ) -> Vec<Statement> {
91
- self.tokens = tokens;
92
- self.token_index = 0;
93
-
94
- let mut statements = Vec::new();
95
-
96
- while !self.is_eof() {
97
- let token = match self.peek() {
98
- Some(t) => t.clone(),
99
- None => {
100
- break;
101
- }
102
- };
103
-
104
- let mut statement = match &token.kind {
105
- TokenKind::At => parse_at_token(self, global_store),
106
- TokenKind::Identifier => parse_identifier_token(self, global_store),
107
- TokenKind::Dot => parse_dot_token(self, global_store),
108
- TokenKind::Tempo => parse_tempo_token(self, global_store),
109
- TokenKind::Bank => parse_bank_token(self, global_store),
110
- TokenKind::Loop => parse_loop_token(self, global_store),
111
-
112
- | TokenKind::Comment
113
- | TokenKind::Equals
114
- | TokenKind::Colon
115
- | TokenKind::Number
116
- | TokenKind::String
117
- | TokenKind::LBrace
118
- | TokenKind::RBrace
119
- | TokenKind::Comma
120
- | TokenKind::Newline
121
- | TokenKind::Dedent
122
- | TokenKind::Indent => {
123
- self.advance();
124
- continue;
125
- }
126
-
127
- TokenKind::EOF => {
128
- break;
129
- }
1
+ pub mod driver;
130
2
 
131
- _ => {
132
- println!("Unhandled token: {:?}", token);
133
- self.advance();
134
- Statement::unknown()
135
- }
136
- };
137
-
138
- statements.push(statement);
139
- }
140
-
141
- statements
142
- }
143
-
144
- pub fn check_token(&self, kind: TokenKind) -> bool {
145
- self.peek().map_or(false, |t| t.kind == kind)
146
- }
147
-
148
- pub fn parse_map_value(&mut self) -> Option<Value> {
149
- if !self.match_token(TokenKind::LBrace) {
150
- return None;
151
- }
152
-
153
- let mut map = std::collections::HashMap::new();
154
-
155
- while !self.check_token(TokenKind::RBrace) && !self.is_eof() {
156
- let key = if let Some(token) = self.advance() {
157
- token.lexeme.clone()
158
- } else {
159
- break;
160
- };
161
-
162
- if !self.match_token(TokenKind::Colon) {
163
- println!("Expected ':' after map key '{}'", key);
164
- break;
165
- }
166
-
167
- let value = if let Some(token) = self.peek_clone() {
168
- match token.kind {
169
- TokenKind::String => {
170
- self.advance();
171
- Value::String(token.lexeme.clone())
172
- }
173
- TokenKind::Number => {
174
- self.advance();
175
- Value::Number(token.lexeme.parse().unwrap_or(0.0))
176
- }
177
- TokenKind::Identifier => {
178
- self.advance();
179
- Value::Identifier(token.lexeme.clone())
180
- }
181
- _ => {
182
- println!("Unexpected token in map value: {:?}", token);
183
- Value::Null
184
- }
185
- }
186
- } else {
187
- Value::Null
188
- };
189
-
190
- map.insert(key, value);
191
- }
192
-
193
- if !self.match_token(TokenKind::RBrace) {
194
- println!("Expected '}}' at end of map");
195
- }
196
-
197
- Some(Value::Map(map))
198
- }
199
-
200
- pub fn peek(&self) -> Option<&Token> {
201
- self.tokens.get(self.token_index)
202
- }
203
-
204
- pub fn peek_clone(&self) -> Option<Token> {
205
- self.tokens.get(self.token_index).cloned()
206
- }
207
-
208
- pub fn expect(&mut self, kind: TokenKind) -> Result<&Token, String> {
209
- let tok = self.advance().ok_or("Unexpected end of input")?;
210
- if tok.kind == kind {
211
- Ok(tok)
212
- } else {
213
- Err(format!("Expected {:?}, got {:?}", kind, tok.kind))
214
- }
215
- }
216
-
217
- pub fn collect_until<F>(&mut self, condition: F) -> Vec<Token> where F: Fn(&Token) -> bool {
218
- let mut collected = Vec::new();
219
- while let Some(token) = self.peek() {
220
- if token.kind == TokenKind::Newline || token.kind == TokenKind::Indent {
221
- self.advance(); // Skip newlines and indents
222
- continue;
223
- }
224
- if token.kind == TokenKind::EOF {
225
- break;
226
- }
227
- if condition(token) {
228
- break;
229
- }
230
- collected.push(self.advance().unwrap().clone());
231
- }
232
- collected
233
- }
234
-
235
- pub fn is_eof(&self) -> bool {
236
- self.token_index >= self.tokens.len()
237
- }
238
- }
3
+ pub mod statement;
4
+ pub mod handler;
@@ -1,5 +1,4 @@
1
1
  use serde::{ Deserialize, Serialize };
2
-
3
2
  use crate::core::{ lexer::token::Token, shared::{ duration::Duration, value::Value } };
4
3
 
5
4
  #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@@ -34,39 +33,32 @@ impl Statement {
34
33
  }
35
34
 
36
35
  #[derive(Debug, Serialize, Clone, Deserialize, PartialEq)]
37
- /// Represents the kind of a statement
38
36
  pub enum StatementKind {
39
- // Trigger statements
40
- Trigger {
41
- entity: String,
42
- duration: Duration,
43
- // params: Vec<TokenParam>,
37
+ // ───── Core Instructions ─────
38
+ Tempo,
39
+ Bank,
40
+ Load {
41
+ source: String,
42
+ alias: String,
44
43
  },
45
-
46
- // Variable statements
47
44
  Let {
48
45
  name: String,
49
46
  },
50
47
 
51
- // Loop statements
52
- Loop,
53
-
54
- // Group statements
55
- Group,
56
-
57
- // Special statements
48
+ // ───── Playback / Scheduling ─────
49
+ Trigger {
50
+ entity: String,
51
+ duration: Duration,
52
+ },
53
+ Sleep,
58
54
  Call,
59
55
  Spawn,
60
- Sleep,
61
-
62
- // Conditional statements
63
- // If
64
-
65
- // Keyword statements
66
- Tempo,
67
- Bank,
56
+ Loop,
57
+
58
+ // ───── Structure & Logic ─────
59
+ Group,
68
60
 
69
- // At (@) statements
61
+ // ───── Module System ─────
70
62
  Include(String),
71
63
  Export {
72
64
  names: Vec<String>,
@@ -76,20 +68,21 @@ pub enum StatementKind {
76
68
  names: Vec<String>,
77
69
  source: String,
78
70
  },
79
- Load {
80
- source: String,
81
- alias: String,
82
- },
83
71
 
84
- // Error & Unknown statements
85
- Unknown,
86
- Error {
87
- message: String,
88
- },
72
+ // ───── Conditions ─────
73
+ If,
74
+ Else,
75
+ ElseIf,
89
76
 
90
- // Empty or ignored statements
77
+ // ───── Internal / Utility ─────
91
78
  Comment,
92
79
  Indent,
93
80
  Dedent,
94
81
  NewLine,
95
- }
82
+
83
+ // ───── Error Handling ─────
84
+ Unknown,
85
+ Error {
86
+ message: String,
87
+ },
88
+ }
@@ -3,17 +3,17 @@ use crate::{
3
3
  core::{
4
4
  error::ErrorHandler,
5
5
  lexer::{ token::Token, Lexer },
6
- parser::{ statement::{ Statement, StatementKind }, Parser },
7
- preprocessor::{
8
- module::Module,
9
- processor::process_modules,
10
- resolver::{ resolve_all_modules, resolve_and_flatten_all_modules },
11
- },
6
+ parser::{ statement::{ Statement, StatementKind }, driver::Parser },
7
+ preprocessor::{ module::Module, processor::process_modules },
12
8
  store::global::GlobalStore,
13
9
  utils::path::normalize_path,
14
10
  },
15
11
  utils::logger::Logger,
16
12
  };
13
+ use crate::core::preprocessor::resolver::driver::{
14
+ resolve_all_modules,
15
+ resolve_and_flatten_all_modules,
16
+ };
17
17
 
18
18
  pub struct ModuleLoader {
19
19
  pub entry: String,
@@ -93,6 +93,7 @@ impl ModuleLoader {
93
93
  global_store: &mut GlobalStore
94
94
  ) -> (HashMap<String, Vec<Token>>, HashMap<String, Vec<Statement>>) {
95
95
  // SECTION Load the entry module and its dependencies
96
+
96
97
  let tokens_by_module = self.load_module_recursively(&self.entry, global_store);
97
98
 
98
99
  // SECTION Process and resolve modules
@@ -1,7 +1,7 @@
1
1
  use std::collections::HashMap;
2
2
 
3
3
  use crate::core::{
4
- parser::{ statement::StatementKind, Parser },
4
+ parser::{ statement::StatementKind, driver::Parser },
5
5
  preprocessor::{ loader::ModuleLoader, resolver::group },
6
6
  shared::value::Value,
7
7
  store::global::GlobalStore,
@@ -0,0 +1,53 @@
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,
9
+ };
10
+
11
+ pub fn resolve_call(
12
+ stmt: &Statement,
13
+ module: &Module,
14
+ _path: &str,
15
+ _global_store: &GlobalStore,
16
+ ) -> Statement {
17
+ let logger = Logger::new();
18
+
19
+ let Value::String(name) = &stmt.value else {
20
+ return type_error(&logger, module, stmt, "Call expects a group name as string.".to_string());
21
+ };
22
+
23
+ match module.variable_table.variables.get(name) {
24
+ Some(Value::Map(group_stmt)) => Statement {
25
+ kind: StatementKind::Call,
26
+ value: Value::Map(group_stmt.clone()),
27
+ ..stmt.clone()
28
+ },
29
+ Some(other) => type_error(
30
+ &logger,
31
+ module,
32
+ stmt,
33
+ format!("Expected a group for '{}', but found {:?}", name, other),
34
+ ),
35
+ None => type_error(
36
+ &logger,
37
+ module,
38
+ stmt,
39
+ format!("Group '{}' not found in module '{}'", name, module.path),
40
+ ),
41
+ }
42
+ }
43
+
44
+ fn type_error(logger: &Logger, module: &Module, stmt: &Statement, message: String) -> Statement {
45
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
46
+ logger.log_error_with_stacktrace(&message, &stacktrace);
47
+
48
+ Statement {
49
+ kind: StatementKind::Error { message },
50
+ value: Value::Null,
51
+ ..stmt.clone()
52
+ }
53
+ }
@@ -0,0 +1,66 @@
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: &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
+ // Body resolution
26
+ if let Some(Value::Block(body)) = condition_map.get("body") {
27
+ let resolved_body = body
28
+ .iter()
29
+ .map(|s| resolve_statement(s, module, path, global_store))
30
+ .collect::<Vec<_>>();
31
+
32
+ resolved_map.insert("body".to_string(), Value::Block(resolved_body));
33
+ }
34
+
35
+ // Next resolution
36
+ if let Some(Value::Map(next)) = condition_map.get("next") {
37
+ let next_stmt = Statement {
38
+ kind: StatementKind::If,
39
+ value: Value::Map(next.clone()),
40
+ ..stmt.clone()
41
+ };
42
+
43
+ let resolved_next = resolve_condition(&next_stmt, module, path, global_store);
44
+
45
+ if let Value::Map(resolved_next_map) = resolved_next.value {
46
+ resolved_map.insert("next".to_string(), Value::Map(resolved_next_map));
47
+ }
48
+ }
49
+
50
+ Statement {
51
+ kind: StatementKind::If,
52
+ value: Value::Map(resolved_map),
53
+ ..stmt.clone()
54
+ }
55
+ }
56
+
57
+ fn type_error(logger: &Logger, module: &Module, stmt: &Statement, message: String) -> Statement {
58
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
59
+ logger.log_error_with_stacktrace(&message, &stacktrace);
60
+
61
+ Statement {
62
+ kind: StatementKind::Error { message },
63
+ value: Value::Null,
64
+ ..stmt.clone()
65
+ }
66
+ }
@@ -0,0 +1,182 @@
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
+ }