@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,308 @@
1
+ use std::{ collections::{ HashMap, HashSet }, path::Path };
2
+ use crate::{
3
+ core::{
4
+ error::ErrorHandler,
5
+ lexer::{ token::Token, Lexer },
6
+ parser::{ driver::Parser, statement::{ Statement, StatementKind } },
7
+ preprocessor::{ module::Module, processor::process_modules },
8
+ shared::{ bank::BankFile, value::Value },
9
+ store::global::GlobalStore,
10
+ utils::path::normalize_path,
11
+ },
12
+ utils::logger::Logger,
13
+ };
14
+ use crate::core::preprocessor::resolver::driver::{
15
+ resolve_all_modules,
16
+ resolve_and_flatten_all_modules,
17
+ };
18
+ use crate::core::utils::path::resolve_relative_path;
19
+
20
+ pub struct ModuleLoader {
21
+ pub entry: String,
22
+ pub output: String,
23
+ pub base_dir: String,
24
+ }
25
+
26
+ impl ModuleLoader {
27
+ pub fn new(entry: &str, output: &str) -> Self {
28
+ let base_dir = Path::new(entry)
29
+ .parent()
30
+ .unwrap_or(Path::new(""))
31
+ .to_string_lossy()
32
+ .replace('\\', "/");
33
+
34
+ Self {
35
+ entry: entry.to_string(),
36
+ output: output.to_string(),
37
+ base_dir: base_dir,
38
+ }
39
+ }
40
+
41
+ pub fn from_raw_source(
42
+ entry_path: &str,
43
+ output_path: &str,
44
+ content: &str,
45
+ global_store: &mut GlobalStore
46
+ ) -> Self {
47
+ let normalized_entry_path = normalize_path(entry_path);
48
+
49
+ let mut module = Module::new(&entry_path);
50
+ module.content = content.to_string();
51
+
52
+ global_store.insert_module(normalized_entry_path.to_string(), module);
53
+
54
+ Self {
55
+ entry: normalized_entry_path.to_string(),
56
+ output: output_path.to_string(),
57
+ base_dir: "".to_string(),
58
+ }
59
+ }
60
+
61
+ pub fn extract_statements_map(
62
+ &self,
63
+ global_store: &GlobalStore
64
+ ) -> HashMap<String, Vec<Statement>> {
65
+ global_store.modules
66
+ .iter()
67
+ .map(|(path, module)| (path.clone(), module.statements.clone()))
68
+ .collect()
69
+ }
70
+
71
+ pub fn load_single_module(&self, global_store: &mut GlobalStore) -> Result<Module, String> {
72
+ let mut module = global_store.modules
73
+ .remove(&self.entry)
74
+ .ok_or_else(|| format!("Module not found in store for path: {}", self.entry))?;
75
+
76
+ // SECTION Lexing the module content
77
+ let lexer = Lexer::new();
78
+ let tokens = lexer
79
+ .lex_from_source(&module.content)
80
+ .map_err(|e| format!("Lexer failed: {}", e))?;
81
+
82
+ module.tokens = tokens.clone();
83
+
84
+ // SECTION Parsing tokens into statements
85
+ let mut parser = Parser::new();
86
+ parser.set_current_module(self.entry.clone());
87
+ let statements = parser.parse_tokens(tokens, global_store);
88
+ module.statements = statements;
89
+
90
+ // SECTION Injecting bank triggers if any
91
+ if let Err(e) = self.inject_bank_triggers(&mut module, "808") {
92
+ return Err(format!("Failed to inject bank triggers: {}", e));
93
+ }
94
+
95
+ global_store.modules.insert(self.entry.clone(), module.clone());
96
+
97
+ // SECTION Error handling
98
+ let mut error_handler = ErrorHandler::new();
99
+ error_handler.detect_from_statements(&mut parser, &module.statements);
100
+
101
+ Ok(module)
102
+ }
103
+
104
+ pub fn load_wasm_module(&self, global_store: &mut GlobalStore) -> Result<(), String> {
105
+ // Step one : Load the module from the global store
106
+ let module = {
107
+ let module_ref = global_store.modules
108
+ .get(&self.entry)
109
+ .ok_or_else(|| format!("❌ Module not found for path: {}", self.entry))?;
110
+
111
+ Module::from_existing(&self.entry, module_ref.content.clone())
112
+ };
113
+
114
+ // Step two : lexing
115
+ let lexer = Lexer::new();
116
+ let tokens = lexer
117
+ .lex_from_source(&module.content)
118
+ .map_err(|e| format!("Lexer failed: {}", e))?;
119
+
120
+ // Step three : parsing
121
+ let mut parser = Parser::new();
122
+ parser.set_current_module(self.entry.clone());
123
+
124
+ let statements = parser.parse_tokens(tokens.clone(), global_store);
125
+
126
+ let mut updated_module = module;
127
+ updated_module.tokens = tokens;
128
+ updated_module.statements = statements;
129
+
130
+ // Step four : error handling
131
+ let mut error_handler = ErrorHandler::new();
132
+ error_handler.detect_from_statements(&mut parser, &updated_module.statements);
133
+
134
+ // Final step : insert the updated module back into the global store
135
+ global_store.modules.insert(self.entry.clone(), updated_module);
136
+
137
+ Ok(())
138
+ }
139
+
140
+ #[cfg(feature = "cli")]
141
+ pub fn load_all_modules(
142
+ &self,
143
+ global_store: &mut GlobalStore
144
+ ) -> (HashMap<String, Vec<Token>>, HashMap<String, Vec<Statement>>) {
145
+ // SECTION Load the entry module and its dependencies
146
+
147
+ let tokens_by_module = self.load_module_recursively(&self.entry, global_store);
148
+
149
+ // SECTION Process and resolve modules
150
+ process_modules(self, global_store);
151
+ resolve_all_modules(self, global_store);
152
+
153
+ let statemnts_by_module = resolve_and_flatten_all_modules(global_store);
154
+
155
+ (tokens_by_module, statemnts_by_module)
156
+ }
157
+
158
+ #[cfg(feature = "cli")]
159
+ fn load_module_recursively(
160
+ &self,
161
+ raw_path: &str,
162
+ global_store: &mut GlobalStore
163
+ ) -> HashMap<String, Vec<Token>> {
164
+ let path = normalize_path(raw_path);
165
+
166
+ // Check if already loaded
167
+ if global_store.modules.contains_key(&path) {
168
+ return HashMap::new();
169
+ }
170
+
171
+ let lexer = Lexer::new();
172
+ let tokens = lexer.lex_tokens(&path);
173
+
174
+ let mut parser = Parser::new();
175
+ parser.set_current_module(path.clone());
176
+
177
+ let statements = parser.parse_tokens(tokens.clone(), global_store);
178
+
179
+ // Insert module into store
180
+ let mut module = Module::new(&path);
181
+ module.tokens = tokens.clone();
182
+ module.statements = statements.clone();
183
+
184
+ // Inject triggers for each bank used in module
185
+ for bank_name in ModuleLoader::extract_bank_names(&statements) {
186
+ if let Err(e) = self.inject_bank_triggers(&mut module, &bank_name) {
187
+ return HashMap::new(); // Return empty map on error
188
+ }
189
+ }
190
+
191
+ global_store.insert_module(path.clone(), module);
192
+
193
+ // Load dependencies
194
+ self.load_module_imports(&path, global_store);
195
+
196
+ // Error handling
197
+ let mut error_handler = ErrorHandler::new();
198
+ error_handler.detect_from_statements(&mut parser, &statements);
199
+
200
+ if error_handler.has_errors() {
201
+ let logger = Logger::new();
202
+ for error in error_handler.get_errors() {
203
+ let trace = format!("{}:{}:{}", path, error.line, error.column);
204
+ logger.log_error_with_stacktrace(&error.message, &trace);
205
+ }
206
+ }
207
+
208
+ // Return tokens per module
209
+ global_store.modules
210
+ .iter()
211
+ .map(|(p, m)| (p.clone(), m.tokens.clone()))
212
+ .collect()
213
+ }
214
+
215
+ #[cfg(feature = "cli")]
216
+ fn load_module_imports(&self, path: &String, global_store: &mut GlobalStore) {
217
+ let import_paths: Vec<String> = {
218
+ let current_module = match global_store.modules.get(path) {
219
+ Some(module) => module,
220
+ None => {
221
+ eprintln!("[warn] Cannot resolve imports: module '{}' not found in store", path);
222
+ return;
223
+ }
224
+ };
225
+
226
+ current_module.statements
227
+ .iter()
228
+ .filter_map(|stmt| {
229
+ if let StatementKind::Import { source, .. } = &stmt.kind {
230
+ Some(source.clone())
231
+ } else {
232
+ None
233
+ }
234
+ })
235
+ .collect()
236
+ };
237
+
238
+ for import_path in import_paths {
239
+ let resolved = resolve_relative_path(path, &import_path);
240
+ self.load_module_recursively(&resolved, global_store);
241
+ }
242
+ }
243
+
244
+ pub fn inject_bank_triggers(&self, module: &mut Module, bank_name: &str) -> Result<(), String> {
245
+ let bank_path = Path::new("./.deva/bank").join(bank_name);
246
+ let bank_file_path = bank_path.join("bank.toml");
247
+
248
+ if !bank_file_path.exists() {
249
+ return Ok(()); // Pas d'erreur si la banque n'existe pas encore
250
+ }
251
+
252
+ let content = std::fs
253
+ ::read_to_string(&bank_file_path)
254
+ .map_err(|e| format!("Failed to read '{}': {}", bank_file_path.display(), e))?;
255
+
256
+ let parsed: BankFile = toml
257
+ ::from_str(&content)
258
+ .map_err(|e| format!("Failed to parse '{}': {}", bank_file_path.display(), e))?;
259
+
260
+ let mut bank_map = HashMap::new();
261
+
262
+ for bank_trigger in parsed.triggers.unwrap_or_default() {
263
+ let trigger_name = bank_trigger.name.clone().replace("./", "");
264
+ let bank_trigger_path = format!("devalang://bank/{}/{}", bank_name, trigger_name);
265
+
266
+ bank_map.insert(bank_trigger.name.clone(), Value::String(bank_trigger_path.clone()));
267
+
268
+ if module.variable_table.variables.contains_key(bank_name) {
269
+ eprintln!(
270
+ "⚠️ Trigger '{}' already defined in module '{}', skipping injection.",
271
+ bank_name, module.path
272
+ );
273
+ continue;
274
+ }
275
+
276
+ module.variable_table.set(
277
+ format!("{}.{}", bank_name, bank_trigger.name),
278
+ Value::String(bank_trigger_path.clone())
279
+ );
280
+ }
281
+
282
+ // Inject the map under the bank name
283
+ module.variable_table.set(bank_name.to_string(), Value::Map(bank_map));
284
+
285
+ Ok(())
286
+ }
287
+
288
+ fn extract_bank_names(statements: &[Statement]) -> HashSet<String> {
289
+ let mut banks = HashSet::new();
290
+
291
+ for stmt in statements {
292
+ if let StatementKind::Trigger { entity, .. } = &stmt.kind {
293
+ let parts: Vec<&str> = entity.split('.').collect();
294
+ if parts.len() >= 2 {
295
+ banks.insert(parts[0].to_string()); // "808.kick" → "808"
296
+ }
297
+ }
298
+
299
+ if let StatementKind::Bank = &stmt.kind {
300
+ if let Value::String(name) = &stmt.value {
301
+ banks.insert(name.clone());
302
+ }
303
+ }
304
+ }
305
+
306
+ banks
307
+ }
308
+ }
@@ -1,26 +1,4 @@
1
1
  pub mod module;
2
- pub mod dependencies;
2
+ pub mod loader;
3
3
  pub mod resolver;
4
-
5
- use crate::core::{
6
- preprocessor::{
7
- dependencies::collect_dependencies_recursively,
8
- module::load_module_into_global_store,
9
- },
10
- types::{ store::GlobalStore },
11
- };
12
-
13
- pub fn preprocess(entry_file: &str) -> GlobalStore {
14
- println!("📦 Collecting dependencies for: {}", entry_file);
15
-
16
- let files = collect_dependencies_recursively(entry_file);
17
- let mut store = GlobalStore::default();
18
-
19
- for file in &files {
20
- if let Err(e) = load_module_into_global_store(file, &mut store) {
21
- eprintln!("❌ Error while loading {}: {}", file, e);
22
- }
23
- }
24
-
25
- store
26
- }
4
+ pub mod processor;
@@ -1,70 +1,56 @@
1
1
  use crate::core::{
2
- lexer::lex,
3
- parser::{ parse_without_resolving },
4
- preprocessor::{
5
- collect_dependencies_recursively,
6
- resolver::{ resolve_exports, resolve_imports },
7
- },
8
- types::{ module::Module, parser::Parser, store::{ ExportTable, GlobalStore, ImportTable } },
2
+ lexer::token::Token,
3
+ parser::statement::Statement,
4
+ store::{ export::ExportTable, import::ImportTable, variable::VariableTable },
9
5
  };
10
6
 
11
- pub fn load_all_modules(entry_file: &str) -> GlobalStore {
12
- let mut global_store = GlobalStore::default();
13
- let files = collect_dependencies_recursively(entry_file);
7
+ #[derive(Debug, Clone)]
8
+ pub struct Module {
9
+ pub path: String,
10
+ pub resolved: bool,
11
+ pub tokens: Vec<Token>,
12
+ pub statements: Vec<Statement>,
13
+ pub variable_table: VariableTable,
14
+ pub export_table: ExportTable,
15
+ pub import_table: ImportTable,
16
+ pub content: String,
17
+ pub current_dir: String,
18
+ }
14
19
 
15
- for file in &files {
16
- if let Err(e) = load_module_into_global_store(file, &mut global_store) {
17
- eprintln!("❌ Error loading {}: {}", file, e);
20
+ impl Module {
21
+ pub fn new(path: &str) -> Self {
22
+ Module {
23
+ path: path.to_string(),
24
+ tokens: Vec::new(),
25
+ statements: Vec::new(),
26
+ variable_table: VariableTable::new(),
27
+ export_table: ExportTable::new(),
28
+ import_table: ImportTable::new(),
29
+ resolved: false,
30
+ content: String::new(),
31
+ current_dir: String::new(),
18
32
  }
19
33
  }
20
34
 
21
- for file in &files {
22
- if let Some(module) = global_store.modules.clone().get_mut(file) {
23
- let imports = resolve_imports(module, &mut global_store);
24
- module.import_table = imports.clone();
25
-
26
- let global_store_module = global_store.modules.get(&file.clone().to_string());
27
- if let Some(global_store_module_found) = global_store_module {
28
- global_store.insert_module(file.to_string(), module.clone());
29
- } else {
30
- eprintln!("❌ Module {} not found in global store after import resolution", file);
31
- }
32
- }
35
+ pub fn is_resolved(&self) -> bool {
36
+ self.resolved
33
37
  }
34
38
 
35
- global_store
36
- }
37
-
38
- pub fn load_module_into_global_store(
39
- path: &str,
40
- global_store: &mut GlobalStore
41
- ) -> Result<(), String> {
42
- if global_store.modules.contains_key(path) {
43
- return Ok(());
39
+ pub fn set_resolved(&mut self, resolved: bool) {
40
+ self.resolved = resolved;
44
41
  }
45
42
 
46
- let content = std::fs::read_to_string(path).map_err(|_| format!("Cannot read file: {}", path))?;
47
-
48
- let tokens = lex(content);
49
-
50
- let mut parser = Parser::new(tokens.clone());
51
-
52
- parser.current_module = path.to_string();
53
-
54
- let raw_statements = parse_without_resolving(tokens.clone(), &mut parser, global_store);
55
-
56
- let export_table = resolve_exports(&raw_statements, &mut parser);
57
-
58
- let mut module = Module {
59
- path: path.to_string(),
60
- tokens: tokens.clone(),
61
- statements: raw_statements,
62
- variable_table: parser.variable_table.clone(),
63
- export_table: export_table.clone(),
64
- import_table: parser.import_table.clone(),
65
- };
43
+ pub fn add_token(&mut self, token: Token) {
44
+ self.tokens.push(token);
45
+ }
66
46
 
67
- global_store.insert_module(path.to_string(), module.clone());
47
+ pub fn add_statement(&mut self, statement: Statement) {
48
+ self.statements.push(statement);
49
+ }
68
50
 
69
- Ok(())
51
+ pub fn from_existing(path: &str, content: String) -> Self {
52
+ let mut module = Module::new(path);
53
+ module.content = content;
54
+ module
55
+ }
70
56
  }
@@ -0,0 +1,76 @@
1
+ use std::{ collections::HashMap, path::Path };
2
+
3
+ use crate::core::{
4
+ parser::{ driver::Parser, statement::StatementKind },
5
+ preprocessor::{ loader::ModuleLoader, resolver::group },
6
+ shared::value::Value,
7
+ store::global::GlobalStore,
8
+ utils::path::{normalize_path, resolve_relative_path},
9
+ };
10
+
11
+ pub fn process_modules(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
12
+ for module in global_store.modules.values_mut() {
13
+ for stmt in &module.statements {
14
+ match &stmt.kind {
15
+ StatementKind::Let { name } => {
16
+ module.variable_table.variables.insert(name.clone(), stmt.value.clone());
17
+ }
18
+
19
+ StatementKind::Load { source, alias } => {
20
+ let module_dir = Path::new(&module.path).parent().unwrap_or(Path::new(""));
21
+
22
+ let resolved_path = normalize_path(&module_dir.join(source));
23
+
24
+ module.variable_table.variables.insert(
25
+ alias.clone(),
26
+ Value::Sample(resolved_path)
27
+ );
28
+ }
29
+
30
+ StatementKind::Export { names, source } => {
31
+ for name in names {
32
+ if let Some(val) = module.variable_table.get(name) {
33
+ module.export_table.add_export(name.clone(), val.clone());
34
+ }
35
+ }
36
+ }
37
+
38
+ StatementKind::Import { names, source } => {
39
+ let resolved = resolve_relative_path(&module.path, source);
40
+ for name in names {
41
+ module.import_table.add_import(
42
+ name.clone(),
43
+ Value::String(resolved.clone())
44
+ );
45
+ }
46
+ }
47
+
48
+ StatementKind::Group => {
49
+ if let Value::Map(map) = &stmt.value {
50
+ if
51
+ let (Some(Value::String(name)), Some(Value::Block(body))) = (
52
+ map.get("identifier"),
53
+ map.get("body"),
54
+ )
55
+ {
56
+ let mut stored_map = HashMap::new();
57
+
58
+ stored_map.insert(
59
+ "identifier".to_string(),
60
+ Value::String(name.clone())
61
+ );
62
+
63
+ stored_map.insert("body".to_string(), Value::Block(body.clone()));
64
+
65
+ module.variable_table.set(name.to_string(), Value::Map(stored_map));
66
+ } else {
67
+ eprintln!("❌ Invalid group definition: {:?}", stmt.value);
68
+ }
69
+ }
70
+ }
71
+
72
+ _ => {}
73
+ }
74
+ }
75
+ }
76
+ }
@@ -1,59 +1,49 @@
1
- use crate::core::{parser::parse_with_resolving_with_module, types::{
2
- module::Module,
3
- statement::{ Statement, StatementKind, StatementResolved, StatementResolvedValue },
4
- variable::VariableValue,
5
- }};
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
+ };
6
10
 
7
- pub fn resolve_bank_statement(stmt: &Statement, module: &Module) -> StatementResolved {
8
- match &stmt.value {
9
- VariableValue::Text(name) => {
10
- if
11
- let Some(value) = module.import_table.imports
12
- .get(name)
13
- .or_else(|| module.variable_table.variables.get(name))
14
- {
15
- let statement_value: StatementResolvedValue = match value {
16
- VariableValue::Array(arr) => {
17
- StatementResolvedValue::Array(
18
- parse_with_resolving_with_module(arr.clone(), module)
19
- )
20
- }
21
- VariableValue::Text(text) => StatementResolvedValue::String(text.clone()),
22
- VariableValue::Number(num) => StatementResolvedValue::Number(*num),
23
- VariableValue::Boolean(b) => StatementResolvedValue::Boolean(*b),
24
- _ => {
25
- eprintln!("⚠️ Unsupported variable type for Bank: {:?}", value);
26
- StatementResolvedValue::Unknown
27
- }
28
- };
11
+ pub fn resolve_bank(
12
+ stmt: &Statement,
13
+ module: &Module,
14
+ path: &str,
15
+ _global_store: &GlobalStore
16
+ ) -> Statement {
17
+ let mut new_stmt = stmt.clone();
18
+ let logger = Logger::new();
29
19
 
30
- StatementResolved {
31
- kind: StatementKind::Bank,
32
- value: statement_value,
33
- indent: stmt.indent,
34
- line: stmt.line,
35
- column: stmt.column,
36
- }
20
+ match &stmt.value {
21
+ Value::Identifier(ident) => {
22
+ if let Some(val) = module.variable_table.get(ident) {
23
+ new_stmt.value = val.clone();
37
24
  } else {
38
- eprintln!("⚠️ Bank variable '{}' not found", name);
39
- StatementResolved {
40
- kind: StatementKind::Bank,
41
- value: StatementResolvedValue::Unknown,
42
- indent: stmt.indent,
43
- line: stmt.line,
44
- column: stmt.column,
45
- }
25
+ let message = format!("Bank identifier '{ident}' not found in variable table");
26
+ logger.log_error_with_stacktrace(&message, &module.path);
27
+ new_stmt.kind = StatementKind::Error {
28
+ message: message.clone(),
29
+ };
30
+ new_stmt.value = Value::Null;
46
31
  }
47
32
  }
48
- _ => {
49
- eprintln!("⚠️ Invalid value type for Bank statement: {:?}", stmt.value);
50
- StatementResolved {
51
- kind: StatementKind::Bank,
52
- value: StatementResolvedValue::Unknown,
53
- indent: stmt.indent,
54
- line: stmt.line,
55
- column: stmt.column,
56
- }
33
+
34
+ Value::String(_) => {}
35
+
36
+ Value::Number(_) => {}
37
+
38
+ other => {
39
+ let message = format!("Expected a string or identifier for bank, found {:?}", other);
40
+ logger.log_error_with_stacktrace(&message, &module.path);
41
+ new_stmt.kind = StatementKind::Error {
42
+ message: "Expected a string or identifier for bank".to_string(),
43
+ };
44
+ new_stmt.value = Value::Null;
57
45
  }
58
46
  }
47
+
48
+ new_stmt
59
49
  }