@devaloop/devalang 0.0.1-alpha.17 → 0.0.1-alpha.18

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 (44) hide show
  1. package/.devalang +5 -1
  2. package/Cargo.toml +4 -4
  3. package/README.md +9 -6
  4. package/docs/CHANGELOG.md +46 -1
  5. package/docs/TODO.md +1 -1
  6. package/examples/index.deva +9 -6
  7. package/examples/pattern.deva +5 -5
  8. package/out-tsc/pkg/devalang_core.d.ts +1 -1
  9. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +7 -7
  10. package/package.json +1 -1
  11. package/project-version.json +3 -3
  12. package/rust/cli/build/commands.rs +10 -0
  13. package/rust/cli/install/addon.rs +84 -38
  14. package/rust/cli/telemetry/event_creator.rs +17 -17
  15. package/rust/core/audio/engine/helpers.rs +21 -9
  16. package/rust/core/audio/engine/sample.rs +68 -7
  17. package/rust/core/audio/engine/synth.rs +19 -4
  18. package/rust/core/audio/evaluator.rs +64 -26
  19. package/rust/core/audio/interpreter/arrow_call.rs +21 -16
  20. package/rust/core/audio/interpreter/call.rs +156 -1
  21. package/rust/core/audio/interpreter/spawn.rs +145 -1
  22. package/rust/core/audio/special/math.rs +22 -2
  23. package/rust/core/lexer/driver.rs +61 -0
  24. package/rust/core/lexer/handler/identifier.rs +3 -2
  25. package/rust/core/lexer/mod.rs +1 -62
  26. package/rust/core/lexer/token.rs +1 -0
  27. package/rust/core/parser/driver.rs +12 -9
  28. package/rust/core/parser/handler/dot.rs +3 -2
  29. package/rust/core/parser/handler/loop_.rs +2 -2
  30. package/rust/core/parser/handler/mod.rs +1 -0
  31. package/rust/core/parser/handler/pattern.rs +74 -0
  32. package/rust/core/preprocessor/loader.rs +87 -127
  33. package/rust/core/preprocessor/processor.rs +7 -7
  34. package/rust/core/preprocessor/resolver/call.rs +28 -0
  35. package/rust/core/preprocessor/resolver/driver.rs +15 -13
  36. package/rust/core/preprocessor/resolver/mod.rs +1 -0
  37. package/rust/core/preprocessor/resolver/pattern.rs +75 -0
  38. package/rust/core/preprocessor/resolver/spawn.rs +27 -0
  39. package/rust/core/store/variable.rs +15 -1
  40. package/rust/main.rs +4 -1
  41. package/rust/types/Cargo.toml +3 -0
  42. package/rust/types/src/ast.rs +4 -0
  43. package/rust/utils/Cargo.toml +4 -1
  44. package/rust/web/api.rs +2 -2
@@ -1,26 +1,23 @@
1
1
  #[cfg(feature = "cli")]
2
2
  use crate::core::preprocessor::resolver::driver::{
3
- resolve_all_modules, resolve_and_flatten_all_modules,
3
+ resolve_all_modules,
4
+ resolve_and_flatten_all_modules,
4
5
  };
5
6
  #[cfg(feature = "cli")]
6
7
  use crate::core::utils::path::resolve_relative_path;
7
8
  #[cfg_attr(not(feature = "cli"), allow(unused_imports))]
8
9
  use crate::core::{
9
10
  error::ErrorHandler,
10
- lexer::{Lexer, token::Token},
11
- parser::{
12
- driver::Parser,
13
- statement::{Statement, StatementKind},
14
- },
11
+ lexer::{ token::Token, driver::Lexer },
12
+ parser::{ driver::Parser, statement::{ Statement, StatementKind } },
15
13
  plugin::loader::load_plugin,
16
- preprocessor::{module::Module, processor::process_modules},
14
+ preprocessor::{ module::Module, processor::process_modules },
17
15
  store::global::GlobalStore,
18
16
  utils::path::normalize_path,
19
17
  };
20
- use devalang_types::{BankFile, Value};
21
- #[cfg(feature = "cli")]
22
- use devalang_utils::logger::{LogLevel, Logger};
23
- use std::{collections::HashMap, path::Path};
18
+ use devalang_types::{ BankFile, Value };
19
+ use devalang_utils::logger::{ LogLevel, Logger };
20
+ use std::{ collections::HashMap, path::Path };
24
21
 
25
22
  pub struct ModuleLoader {
26
23
  pub entry: String,
@@ -47,7 +44,7 @@ impl ModuleLoader {
47
44
  entry_path: &str,
48
45
  output_path: &str,
49
46
  content: &str,
50
- global_store: &mut GlobalStore,
47
+ global_store: &mut GlobalStore
51
48
  ) -> Self {
52
49
  let normalized_entry_path = normalize_path(entry_path);
53
50
 
@@ -68,18 +65,16 @@ impl ModuleLoader {
68
65
 
69
66
  pub fn extract_statements_map(
70
67
  &self,
71
- global_store: &GlobalStore,
68
+ global_store: &GlobalStore
72
69
  ) -> HashMap<String, Vec<Statement>> {
73
- global_store
74
- .modules
70
+ global_store.modules
75
71
  .iter()
76
72
  .map(|(path, module)| (path.clone(), module.statements.clone()))
77
73
  .collect()
78
74
  }
79
75
 
80
76
  pub fn load_single_module(&self, global_store: &mut GlobalStore) -> Result<Module, String> {
81
- let mut module = global_store
82
- .modules
77
+ let mut module = global_store.modules
83
78
  .remove(&self.entry)
84
79
  .ok_or_else(|| format!("Module not found in store for path: {}", self.entry))?;
85
80
 
@@ -106,9 +101,7 @@ impl ModuleLoader {
106
101
  self.load_plugin_and_register(&mut module, &plugin_name, &alias, global_store);
107
102
  }
108
103
 
109
- global_store
110
- .modules
111
- .insert(self.entry.clone(), module.clone());
104
+ global_store.modules.insert(self.entry.clone(), module.clone());
112
105
 
113
106
  // SECTION Error handling
114
107
  let mut error_handler = ErrorHandler::new();
@@ -120,8 +113,7 @@ impl ModuleLoader {
120
113
  pub fn load_wasm_module(&self, global_store: &mut GlobalStore) -> Result<(), String> {
121
114
  // Step one : Load the module from the global store
122
115
  let module = {
123
- let module_ref = global_store
124
- .modules
116
+ let module_ref = global_store.modules
125
117
  .get(&self.entry)
126
118
  .ok_or_else(|| format!("❌ Module not found for path: {}", self.entry))?;
127
119
 
@@ -152,9 +144,7 @@ impl ModuleLoader {
152
144
  // Insert the updated module into the global store before processing so
153
145
  // process_modules can operate on it and populate variable_table, imports,
154
146
  // and other derived structures.
155
- global_store
156
- .modules
157
- .insert(self.entry.clone(), updated_module.clone());
147
+ global_store.modules.insert(self.entry.clone(), updated_module.clone());
158
148
 
159
149
  // Process modules to populate module.variable_table, import/export tables,
160
150
  // and other derived structures so runtime execution can resolve groups/synths.
@@ -174,25 +164,17 @@ impl ModuleLoader {
174
164
  // (it lives in `global_store.modules`) because `updated_module` is a local
175
165
  // clone and won't contain the mutations applied by `process_modules`.
176
166
  if let Some(stored_module) = global_store.modules.get(&self.entry) {
177
- global_store
178
- .variables
179
- .variables
180
- .extend(stored_module.variable_table.variables.clone());
181
- global_store
182
- .functions
183
- .functions
184
- .extend(stored_module.function_table.functions.clone());
167
+ global_store.variables.variables.extend(stored_module.variable_table.variables.clone());
168
+ global_store.functions.functions.extend(stored_module.function_table.functions.clone());
185
169
  } else {
186
170
  // Fallback to the local updated_module if for any reason the module
187
171
  // wasn't inserted into the store (defensive programming).
188
- global_store
189
- .variables
190
- .variables
191
- .extend(updated_module.variable_table.variables.clone());
192
- global_store
193
- .functions
194
- .functions
195
- .extend(updated_module.function_table.functions.clone());
172
+ global_store.variables.variables.extend(
173
+ updated_module.variable_table.variables.clone()
174
+ );
175
+ global_store.functions.functions.extend(
176
+ updated_module.function_table.functions.clone()
177
+ );
196
178
  }
197
179
 
198
180
  Ok(())
@@ -201,7 +183,7 @@ impl ModuleLoader {
201
183
  #[cfg(feature = "cli")]
202
184
  pub fn load_all_modules(
203
185
  &self,
204
- global_store: &mut GlobalStore,
186
+ global_store: &mut GlobalStore
205
187
  ) -> (HashMap<String, Vec<Token>>, HashMap<String, Vec<Statement>>) {
206
188
  // SECTION Load the entry module and its dependencies
207
189
  let tokens_by_module = self.load_module_recursively(&self.entry, global_store);
@@ -220,7 +202,7 @@ impl ModuleLoader {
220
202
  fn load_module_recursively(
221
203
  &self,
222
204
  raw_path: &str,
223
- global_store: &mut GlobalStore,
205
+ global_store: &mut GlobalStore
224
206
  ) -> HashMap<String, Vec<Token>> {
225
207
  let path = normalize_path(raw_path);
226
208
 
@@ -261,14 +243,8 @@ impl ModuleLoader {
261
243
  }
262
244
 
263
245
  // Inject module variables and functions into global store
264
- global_store
265
- .variables
266
- .variables
267
- .extend(module.variable_table.variables.clone());
268
- global_store
269
- .functions
270
- .functions
271
- .extend(module.function_table.functions.clone());
246
+ global_store.variables.variables.extend(module.variable_table.variables.clone());
247
+ global_store.functions.functions.extend(module.function_table.functions.clone());
272
248
 
273
249
  // Inject the module into the global store
274
250
  global_store.insert_module(path.clone(), module);
@@ -293,8 +269,7 @@ impl ModuleLoader {
293
269
  }
294
270
 
295
271
  // Return tokens per module
296
- global_store
297
- .modules
272
+ global_store.modules
298
273
  .iter()
299
274
  .map(|(p, m)| (p.clone(), m.tokens.clone()))
300
275
  .collect()
@@ -306,16 +281,12 @@ impl ModuleLoader {
306
281
  let current_module = match global_store.modules.get(path) {
307
282
  Some(module) => module,
308
283
  None => {
309
- eprintln!(
310
- "[warn] Cannot resolve imports: module '{}' not found in store",
311
- path
312
- );
284
+ eprintln!("[warn] Cannot resolve imports: module '{}' not found in store", path);
313
285
  return;
314
286
  }
315
287
  };
316
288
 
317
- current_module
318
- .statements
289
+ current_module.statements
319
290
  .iter()
320
291
  .filter_map(|stmt| {
321
292
  if let StatementKind::Import { source, .. } = &stmt.kind {
@@ -337,13 +308,9 @@ impl ModuleLoader {
337
308
  &self,
338
309
  module: &mut Module,
339
310
  bank_name: &str,
340
- alias_override: Option<String>,
311
+ alias_override: Option<String>
341
312
  ) -> Result<Module, String> {
342
- let default_alias = bank_name
343
- .split('.')
344
- .next_back()
345
- .unwrap_or(bank_name)
346
- .to_string();
313
+ let default_alias = bank_name.split('.').next_back().unwrap_or(bank_name).to_string();
347
314
  let alias_ref = alias_override.as_deref().unwrap_or(&default_alias);
348
315
 
349
316
  let bank_path = match devalang_utils::path::get_deva_dir() {
@@ -356,10 +323,12 @@ impl ModuleLoader {
356
323
  return Ok(module.clone());
357
324
  }
358
325
 
359
- let content = std::fs::read_to_string(&bank_toml_path)
326
+ let content = std::fs
327
+ ::read_to_string(&bank_toml_path)
360
328
  .map_err(|e| format!("Failed to read '{}': {}", bank_toml_path.display(), e))?;
361
329
 
362
- let parsed_bankfile: BankFile = toml::from_str(&content)
330
+ let parsed_bankfile: BankFile = toml
331
+ ::from_str(&content)
363
332
  .map_err(|e| format!("Failed to parse '{}': {}", bank_toml_path.display(), e))?;
364
333
 
365
334
  let mut bank_map = HashMap::new();
@@ -368,38 +337,30 @@ impl ModuleLoader {
368
337
  // Use the configured path from the bank file as the entity reference so
369
338
  // that bank entries can point to files or nested paths. Clean common
370
339
  // local prefixes like "./" to keep the URI tidy.
371
- let entity_ref = bank_trigger
372
- .path
373
- .clone()
374
- .replace("\\", "/")
375
- .replace("./", "");
340
+ let entity_ref = bank_trigger.path.clone().replace("\\", "/").replace("./", "");
376
341
  let bank_trigger_path = format!("devalang://bank/{}/{}", bank_name, entity_ref);
377
342
 
378
343
  // Keep the trigger key as declared (bank_trigger.name) but expose its
379
344
  // value as a devalang://bank URI pointing to the configured path.
380
- bank_map.insert(
381
- bank_trigger.name.clone(),
382
- Value::String(bank_trigger_path.clone()),
383
- );
345
+ bank_map.insert(bank_trigger.name.clone(), Value::String(bank_trigger_path.clone()));
384
346
 
385
347
  if module.variable_table.variables.contains_key(alias_ref) {
386
348
  eprintln!(
387
349
  "⚠️ Trigger '{}' already defined in module '{}', skipping injection.",
388
- alias_ref, module.path
350
+ alias_ref,
351
+ module.path
389
352
  );
390
353
  continue;
391
354
  }
392
355
 
393
356
  module.variable_table.set(
394
357
  format!("{}.{}", alias_ref, bank_trigger.name),
395
- Value::String(bank_trigger_path.clone()),
358
+ Value::String(bank_trigger_path.clone())
396
359
  );
397
360
  }
398
361
 
399
362
  // Inject the map under the bank name
400
- module
401
- .variable_table
402
- .set(alias_ref.to_string(), Value::Map(bank_map));
363
+ module.variable_table.set(alias_ref.to_string(), Value::Map(bank_map));
403
364
 
404
365
  Ok(module.clone())
405
366
  }
@@ -445,7 +406,7 @@ impl ModuleLoader {
445
406
  module: &mut Module,
446
407
  plugin_name: &str,
447
408
  alias: &str,
448
- global_store: &mut GlobalStore,
409
+ global_store: &mut GlobalStore
449
410
  ) {
450
411
  // plugin_name expected format: "author.name"
451
412
  let mut parts = plugin_name.split('.');
@@ -464,10 +425,7 @@ impl ModuleLoader {
464
425
  }
465
426
  };
466
427
  if parts.next().is_some() {
467
- eprintln!(
468
- "Invalid plugin name '{}': expected <author>.<name>",
469
- plugin_name
470
- );
428
+ eprintln!("Invalid plugin name '{}': expected <author>.<name>", plugin_name);
471
429
  return;
472
430
  }
473
431
 
@@ -499,8 +457,7 @@ impl ModuleLoader {
499
457
  // Inject a single, clear error into the module so it is reported once by the error handler
500
458
  module.statements.push(Statement {
501
459
  kind: StatementKind::Error {
502
- message: "plugin present in local files but missing in .devalang config"
503
- .to_string(),
460
+ message: "plugin present in local files but missing in .devalang config".to_string(),
504
461
  },
505
462
  value: Value::Null,
506
463
  indent: 0,
@@ -514,20 +471,16 @@ impl ModuleLoader {
514
471
  match load_plugin(author, name) {
515
472
  Ok((info, wasm)) => {
516
473
  let uri = format!("devalang://plugin/{}.{}", author, name);
517
- global_store
518
- .plugins
519
- .insert(format!("{}:{}", author, name), (info, wasm));
474
+ global_store.plugins.insert(format!("{}:{}", author, name), (info, wasm));
520
475
  // Set alias to URI, and inject exported variables
521
- module
522
- .variable_table
523
- .set(alias.to_string(), Value::String(uri.clone()));
476
+ module.variable_table.set(alias.to_string(), Value::String(uri.clone()));
524
477
  // Also expose alias at global level so runtime can resolve it
525
- global_store
526
- .variables
527
- .set(alias.to_string(), Value::String(uri.clone()));
478
+ global_store.variables.set(alias.to_string(), Value::String(uri.clone()));
528
479
 
529
- if let Some((plugin_info, _)) =
530
- global_store.plugins.get(&format!("{}:{}", author, name))
480
+ if
481
+ let Some((plugin_info, _)) = global_store.plugins.get(
482
+ &format!("{}:{}", author, name)
483
+ )
531
484
  {
532
485
  for exp in &plugin_info.exports {
533
486
  match exp.kind.as_str() {
@@ -536,18 +489,18 @@ impl ModuleLoader {
536
489
  if let Ok(n) = s.parse::<f32>() {
537
490
  module.variable_table.set(
538
491
  format!("{}.{}", alias, exp.name),
539
- Value::Number(n),
492
+ Value::Number(n)
540
493
  );
541
494
  }
542
495
  } else if let Some(toml::Value::Integer(i)) = &exp.default {
543
496
  module.variable_table.set(
544
497
  format!("{}.{}", alias, exp.name),
545
- Value::Number(*i as f32),
498
+ Value::Number(*i as f32)
546
499
  );
547
500
  } else if let Some(toml::Value::Float(f)) = &exp.default {
548
501
  module.variable_table.set(
549
502
  format!("{}.{}", alias, exp.name),
550
- Value::Number(*f as f32),
503
+ Value::Number(*f as f32)
551
504
  );
552
505
  }
553
506
  }
@@ -555,22 +508,23 @@ impl ModuleLoader {
555
508
  if let Some(toml::Value::String(s)) = &exp.default {
556
509
  module.variable_table.set(
557
510
  format!("{}.{}", alias, exp.name),
558
- Value::String(s.clone()),
511
+ Value::String(s.clone())
559
512
  );
560
513
  }
561
514
  }
562
515
  "bool" => {
563
516
  if let Some(toml::Value::Boolean(b)) = &exp.default {
564
- module
565
- .variable_table
566
- .set(format!("{}.{}", alias, exp.name), Value::Boolean(*b));
517
+ module.variable_table.set(
518
+ format!("{}.{}", alias, exp.name),
519
+ Value::Boolean(*b)
520
+ );
567
521
  }
568
522
  }
569
523
  "synth" => {
570
524
  // Provide a discoverable marker: alias.<synthName> resolves to alias.synthName waveform string
571
525
  module.variable_table.set(
572
526
  format!("{}.{}", alias, exp.name),
573
- Value::String(format!("{}.{}", alias, exp.name)),
527
+ Value::String(format!("{}.{}", alias, exp.name))
574
528
  );
575
529
  }
576
530
  _ => {
@@ -581,23 +535,28 @@ impl ModuleLoader {
581
535
  toml::Value::Integer(i) => Value::Number(*i as f32),
582
536
  toml::Value::Float(f) => Value::Number(*f as f32),
583
537
  toml::Value::Boolean(b) => Value::Boolean(*b),
584
- toml::Value::Array(arr) => Value::Array(
585
- arr.iter()
586
- .map(|v| match v {
587
- toml::Value::String(s) => {
588
- Value::String(s.clone())
589
- }
590
- toml::Value::Integer(i) => {
591
- Value::Number(*i as f32)
592
- }
593
- toml::Value::Float(f) => {
594
- Value::Number(*f as f32)
595
- }
596
- toml::Value::Boolean(b) => Value::Boolean(*b),
597
- _ => Value::Null,
598
- })
599
- .collect(),
600
- ),
538
+ toml::Value::Array(arr) =>
539
+ Value::Array(
540
+ arr
541
+ .iter()
542
+ .map(|v| {
543
+ match v {
544
+ toml::Value::String(s) => {
545
+ Value::String(s.clone())
546
+ }
547
+ toml::Value::Integer(i) => {
548
+ Value::Number(*i as f32)
549
+ }
550
+ toml::Value::Float(f) => {
551
+ Value::Number(*f as f32)
552
+ }
553
+ toml::Value::Boolean(b) =>
554
+ Value::Boolean(*b),
555
+ _ => Value::Null,
556
+ }
557
+ })
558
+ .collect()
559
+ ),
601
560
  toml::Value::Table(t) => {
602
561
  let mut m = std::collections::HashMap::new();
603
562
  for (k, v) in t.iter() {
@@ -621,9 +580,10 @@ impl ModuleLoader {
621
580
  _ => Value::Null,
622
581
  };
623
582
  if val != Value::Null {
624
- module
625
- .variable_table
626
- .set(format!("{}.{}", alias, exp.name), val);
583
+ module.variable_table.set(
584
+ format!("{}.{}", alias, exp.name),
585
+ val
586
+ );
627
587
  }
628
588
  }
629
589
  }
@@ -10,11 +10,14 @@ use devalang_types::Value;
10
10
 
11
11
  pub fn process_modules(_module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
12
12
  for module in global_store.modules.values_mut() {
13
+ let logger = devalang_utils::logger::Logger::new();
14
+ use devalang_utils::logger::LogLevel;
15
+
13
16
  for stmt in &module.statements {
14
17
  match &stmt.kind {
15
18
  StatementKind::Let { name } => {
16
19
  if let Value::Null = stmt.value {
17
- eprintln!("Variable '{}' is declared but not initialized.", name);
20
+ logger.log_message(LogLevel::Error, &format!("Variable '{}' is declared but not initialized.", name));
18
21
 
19
22
  module.variable_table.variables.insert(
20
23
  name.clone(),
@@ -25,15 +28,12 @@ pub fn process_modules(_module_loader: &ModuleLoader, global_store: &mut GlobalS
25
28
  }
26
29
 
27
30
  if module.variable_table.get(name).is_some() {
28
- eprintln!("Variable '{}' is already defined in this scope.", name);
31
+ logger.log_message(LogLevel::Error, &format!("Variable '{}' is already defined in this scope.", name));
29
32
  continue;
30
33
  }
31
34
 
32
35
  if let Some(module_variable) = module.variable_table.variables.get(name) {
33
- eprintln!(
34
- "❌ Variable '{}' is already defined globally with value: {:?}",
35
- name, module_variable
36
- );
36
+ logger.log_message(LogLevel::Error, &format!("Variable '{}' is already defined globally with value: {:?}", name, module_variable));
37
37
  continue;
38
38
  }
39
39
 
@@ -87,7 +87,7 @@ pub fn process_modules(_module_loader: &ModuleLoader, global_store: &mut GlobalS
87
87
  .variable_table
88
88
  .set(name.to_string(), Value::Map(stored_map));
89
89
  } else {
90
- eprintln!("Invalid group definition: {:?}", stmt.value);
90
+ logger.log_message(LogLevel::Error, &format!("Invalid group definition: {:?}", stmt.value));
91
91
  }
92
92
  }
93
93
  }
@@ -60,6 +60,34 @@ pub fn resolve_call(
60
60
  }
61
61
  }
62
62
  }
63
+ // Pattern case
64
+ if let StatementKind::Pattern { .. } = stmt_box.kind {
65
+ // pattern value may be a string or a map stored on the statement
66
+ let mut resolved_map = std::collections::HashMap::new();
67
+ resolved_map.insert("identifier".to_string(), Value::String(name.clone()));
68
+ // pattern value
69
+ match &stmt_box.value {
70
+ Value::String(s) => {
71
+ resolved_map.insert("pattern".to_string(), Value::String(s.clone()));
72
+ }
73
+ Value::Map(m) => {
74
+ if let Some(val) = m.get("pattern") {
75
+ resolved_map.insert("pattern".to_string(), val.clone());
76
+ }
77
+ if let Some(val) = m.get("target") {
78
+ resolved_map.insert("target".to_string(), val.clone());
79
+ }
80
+ }
81
+ _ => {}
82
+ }
83
+ resolved_map.insert("args".to_string(), Value::Array(args.clone()));
84
+
85
+ return Statement {
86
+ kind: StatementKind::Call { name, args },
87
+ value: Value::Map(resolved_map),
88
+ ..stmt.clone()
89
+ };
90
+ }
63
91
  }
64
92
 
65
93
  // Otherwise, log an error
@@ -5,7 +5,7 @@ use crate::core::{
5
5
  module::Module,
6
6
  resolver::{
7
7
  bank::resolve_bank, call::resolve_call, condition::resolve_condition,
8
- function::resolve_function, group::resolve_group, let_::resolve_let,
8
+ function::resolve_function, group::resolve_group, pattern::resolve_pattern, let_::resolve_let,
9
9
  loop_::resolve_loop, spawn::resolve_spawn, tempo::resolve_tempo,
10
10
  trigger::resolve_trigger,
11
11
  },
@@ -14,6 +14,7 @@ use crate::core::{
14
14
  };
15
15
  use devalang_types::Value;
16
16
  use devalang_utils::logger::Logger;
17
+ use devalang_utils::logger::LogLevel;
17
18
  use std::collections::HashMap;
18
19
 
19
20
  pub fn resolve_all_modules(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
@@ -66,7 +67,8 @@ pub fn resolve_statement(
66
67
  global_store,
67
68
  ),
68
69
  StatementKind::If => resolve_condition(stmt, module, path, global_store),
69
- StatementKind::Group => resolve_group(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),
70
72
  StatementKind::Call { name, args } => {
71
73
  resolve_call(stmt, name.clone(), args.clone(), module, path, global_store)
72
74
  }
@@ -90,6 +92,7 @@ pub fn resolve_statement(
90
92
  }
91
93
 
92
94
  fn resolve_value(value: &Value, module: &Module, global_store: &mut GlobalStore) -> Value {
95
+ let logger = Logger::new();
93
96
  match value {
94
97
  Value::Identifier(name) => {
95
98
  if let Some(original_val) = module.variable_table.get(name) {
@@ -107,7 +110,7 @@ fn resolve_value(value: &Value, module: &Module, global_store: &mut GlobalStore)
107
110
  Value::String(s) => Value::String(s.clone()),
108
111
 
109
112
  Value::Beat(beat_str) => {
110
- println!("[warn] '{:?}': unresolved beat '{}'", module.path, beat_str);
113
+ logger.log_message(LogLevel::Warning, &format!("[warn] '{:?}': unresolved beat '{}'", module.path, beat_str));
111
114
  Value::Beat(beat_str.clone())
112
115
  }
113
116
 
@@ -141,6 +144,7 @@ fn find_export_value(name: &str, global_store: &GlobalStore) -> Option<Value> {
141
144
  }
142
145
 
143
146
  pub fn resolve_imports(_module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
147
+ let logger = Logger::new();
144
148
  for (module_path, module) in global_store.clone().modules.iter_mut() {
145
149
  for (name, source_path) in &module.import_table.imports {
146
150
  match source_path {
@@ -149,21 +153,14 @@ pub fn resolve_imports(_module_loader: &ModuleLoader, global_store: &mut GlobalS
149
153
  if let Some(value) = source_module.export_table.get_export(name) {
150
154
  module.variable_table.set(name.clone(), value.clone());
151
155
  } else {
152
- println!(
153
- "[warn] '{module_path}': '{name}' not found in exports of '{source_path}'"
154
- );
156
+ logger.log_message(LogLevel::Warning, &format!("[warn] '{module_path}': '{name}' not found in exports of '{source_path}'"));
155
157
  }
156
158
  } else {
157
- println!(
158
- "[warn] '{module_path}': cannot find source module '{source_path}'"
159
- );
159
+ logger.log_message(LogLevel::Warning, &format!("[warn] '{module_path}': cannot find source module '{source_path}'"));
160
160
  }
161
161
  }
162
162
  _ => {
163
- println!(
164
- "[warn] '{module_path}': expected string for import source, found {:?}",
165
- source_path
166
- );
163
+ logger.log_message(LogLevel::Warning, &format!("[warn] '{module_path}': expected string for import source, found {:?}", source_path));
167
164
  }
168
165
  }
169
166
  }
@@ -286,6 +283,11 @@ pub fn resolve_and_flatten_all_modules(
286
283
  resolved.push(resolved_stmt);
287
284
  }
288
285
 
286
+ StatementKind::Pattern { .. } => {
287
+ let resolved_stmt = resolve_pattern(&stmt, &module, &path, global_store);
288
+ resolved.push(resolved_stmt);
289
+ }
290
+
289
291
  StatementKind::Function {
290
292
  name: _,
291
293
  parameters: _,
@@ -7,6 +7,7 @@ pub mod call;
7
7
  pub mod condition;
8
8
  pub mod function;
9
9
  pub mod group;
10
+ pub mod pattern;
10
11
  pub mod let_;
11
12
  pub mod loop_;
12
13
  pub mod spawn;