@devaloop/devalang 0.0.1-beta.2 → 0.0.1-beta.3

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 (159) hide show
  1. package/Cargo.toml +84 -81
  2. package/README.md +3 -2
  3. package/docs/CHANGELOG.md +41 -0
  4. package/docs/ROADMAP.md +3 -3
  5. package/examples/chain.deva +19 -0
  6. package/examples/plugin.deva +10 -10
  7. package/examples/routing.deva +23 -0
  8. package/out-tsc/bin/project-version.json +6 -0
  9. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +8 -8
  10. package/out-tsc/scripts/version/copy-to-binary.d.ts +1 -0
  11. package/out-tsc/scripts/version/copy-to-binary.js +79 -0
  12. package/package.json +23 -10
  13. package/project-version.json +3 -3
  14. package/rust/bindings/Cargo.toml +9 -0
  15. package/rust/bindings/src/lib.rs +86 -0
  16. package/rust/cli/addon/commands.rs +35 -0
  17. package/rust/cli/addon/download.rs +234 -0
  18. package/rust/cli/addon/install.rs +33 -0
  19. package/rust/cli/addon/list.rs +224 -0
  20. package/rust/cli/addon/metadata.rs +124 -0
  21. package/rust/cli/addon/mod.rs +8 -0
  22. package/rust/cli/addon/remove.rs +271 -0
  23. package/rust/cli/addon/update.rs +305 -0
  24. package/rust/cli/{install/addon.rs → addon/utils.rs} +109 -118
  25. package/rust/cli/build/commands.rs +153 -153
  26. package/rust/cli/build/process.rs +165 -165
  27. package/rust/cli/check/mod.rs +208 -208
  28. package/rust/cli/discover/commands.rs +275 -253
  29. package/rust/cli/discover/config.rs +109 -111
  30. package/rust/cli/discover/fs.rs +19 -19
  31. package/rust/cli/discover/install.rs +214 -103
  32. package/rust/cli/discover/metadata.rs +48 -48
  33. package/rust/cli/discover/mod.rs +5 -5
  34. package/rust/cli/me/commands.rs +52 -0
  35. package/rust/cli/me/mod.rs +1 -0
  36. package/rust/cli/mod.rs +12 -12
  37. package/rust/cli/parser.rs +30 -69
  38. package/rust/cli/play/commands.rs +375 -375
  39. package/rust/cli/play/process.rs +159 -159
  40. package/rust/core/audio/engine/driver.rs +19 -2
  41. package/rust/core/audio/engine/export.rs +169 -169
  42. package/rust/core/audio/engine/mod.rs +56 -56
  43. package/rust/core/audio/engine/notes/dsp.rs +88 -85
  44. package/rust/core/audio/engine/notes/mod.rs +53 -44
  45. package/rust/core/audio/engine/notes/params.rs +294 -294
  46. package/rust/core/audio/engine/sample/insert.rs +148 -47
  47. package/rust/core/audio/engine/sample/mod.rs +40 -40
  48. package/rust/core/audio/engine/sample/padding.rs +170 -170
  49. package/rust/core/audio/evaluator/condition.rs +61 -61
  50. package/rust/core/audio/evaluator/numeric.rs +152 -152
  51. package/rust/core/audio/evaluator/rhs.rs +16 -16
  52. package/rust/core/audio/evaluator/string_expr.rs +94 -94
  53. package/rust/core/audio/interpreter/driver.rs +574 -574
  54. package/rust/core/audio/interpreter/mod.rs +2 -2
  55. package/rust/core/audio/interpreter/statements/arrow_call/interprete.rs +9 -5
  56. package/rust/core/audio/interpreter/statements/arrow_call/methods/chord.rs +398 -384
  57. package/rust/core/audio/interpreter/statements/arrow_call/methods/effects.rs +323 -0
  58. package/rust/core/audio/interpreter/statements/arrow_call/methods/mod.rs +1 -0
  59. package/rust/core/audio/interpreter/statements/arrow_call/methods/note.rs +66 -11
  60. package/rust/core/audio/interpreter/statements/arrow_call/mod.rs +3 -3
  61. package/rust/core/audio/interpreter/statements/arrow_call/types/arp.rs +192 -192
  62. package/rust/core/audio/interpreter/statements/arrow_call/types/mod.rs +24 -24
  63. package/rust/core/audio/interpreter/statements/arrow_call/types/pad.rs +116 -116
  64. package/rust/core/audio/interpreter/statements/arrow_call/types/pluck.rs +97 -97
  65. package/rust/core/audio/interpreter/statements/arrow_call/types/sub.rs +100 -100
  66. package/rust/core/audio/interpreter/statements/automate.rs +16 -16
  67. package/rust/core/audio/interpreter/statements/call.rs +31 -1
  68. package/rust/core/audio/interpreter/statements/condition.rs +72 -72
  69. package/rust/core/audio/interpreter/statements/function.rs +24 -24
  70. package/rust/core/audio/interpreter/statements/let_.rs +36 -36
  71. package/rust/core/audio/interpreter/statements/load.rs +17 -17
  72. package/rust/core/audio/interpreter/statements/loop_.rs +115 -115
  73. package/rust/core/audio/interpreter/statements/spawn.rs +51 -2
  74. package/rust/core/audio/interpreter/statements/trigger.rs +242 -239
  75. package/rust/core/audio/loader/trigger.rs +98 -98
  76. package/rust/core/audio/player.rs +70 -70
  77. package/rust/core/audio/special/mod.rs +9 -9
  78. package/rust/core/builder/mod.rs +129 -129
  79. package/rust/core/debugger/lexer.rs +27 -27
  80. package/rust/core/debugger/logs.rs +52 -52
  81. package/rust/core/debugger/preprocessor.rs +27 -27
  82. package/rust/core/debugger/store.rs +38 -38
  83. package/rust/core/lexer/driver.rs +59 -59
  84. package/rust/core/lexer/handler/arrow.rs +82 -82
  85. package/rust/core/lexer/handler/at.rs +21 -21
  86. package/rust/core/lexer/handler/brace.rs +41 -41
  87. package/rust/core/lexer/handler/colon.rs +21 -21
  88. package/rust/core/lexer/handler/comment.rs +30 -30
  89. package/rust/core/lexer/handler/dot.rs +21 -21
  90. package/rust/core/lexer/handler/driver.rs +337 -337
  91. package/rust/core/lexer/handler/identifier.rs +47 -47
  92. package/rust/core/lexer/handler/indent.rs +66 -66
  93. package/rust/core/lexer/handler/mod.rs +15 -15
  94. package/rust/core/lexer/handler/newline.rs +23 -23
  95. package/rust/core/lexer/handler/number.rs +31 -31
  96. package/rust/core/lexer/handler/operator.rs +46 -46
  97. package/rust/core/lexer/handler/parenthesis.rs +41 -41
  98. package/rust/core/lexer/handler/slash.rs +21 -21
  99. package/rust/core/lexer/handler/string.rs +63 -63
  100. package/rust/core/lexer/mod.rs +3 -3
  101. package/rust/core/mod.rs +9 -9
  102. package/rust/core/parser/driver/block.rs +111 -111
  103. package/rust/core/parser/driver/cursor.rs +82 -82
  104. package/rust/core/parser/driver/driver_impl.rs +21 -1
  105. package/rust/core/parser/driver/mod.rs +6 -6
  106. package/rust/core/parser/driver/parse_array.rs +120 -120
  107. package/rust/core/parser/driver/parse_map.rs +247 -223
  108. package/rust/core/parser/driver/parser.rs +160 -160
  109. package/rust/core/parser/handler/arrow_call.rs +65 -14
  110. package/rust/core/parser/handler/identifier/synth.rs +171 -135
  111. package/rust/core/parser/handler/mod.rs +9 -9
  112. package/rust/core/parser/handler/pattern.rs +24 -1
  113. package/rust/core/plugin/loader.rs +137 -137
  114. package/rust/core/plugin/mod.rs +2 -2
  115. package/rust/core/plugin/runner/non_wasm.rs +481 -297
  116. package/rust/core/plugin/runner/wasm32.rs +1 -0
  117. package/rust/core/preprocessor/loader/inject.rs +313 -278
  118. package/rust/core/preprocessor/loader/loader_helpers.rs +110 -110
  119. package/rust/core/preprocessor/loader/mod.rs +235 -235
  120. package/rust/core/preprocessor/module.rs +55 -55
  121. package/rust/core/preprocessor/processor/handlers.rs +107 -107
  122. package/rust/core/preprocessor/resolver/bank.rs +49 -49
  123. package/rust/core/preprocessor/resolver/call.rs +124 -124
  124. package/rust/core/preprocessor/resolver/condition.rs +95 -95
  125. package/rust/core/preprocessor/resolver/driver.rs +324 -324
  126. package/rust/core/preprocessor/resolver/function.rs +69 -69
  127. package/rust/core/preprocessor/resolver/group.rs +122 -122
  128. package/rust/core/preprocessor/resolver/let_.rs +32 -32
  129. package/rust/core/preprocessor/resolver/loop_.rs +318 -318
  130. package/rust/core/preprocessor/resolver/mod.rs +16 -16
  131. package/rust/core/preprocessor/resolver/pattern.rs +95 -83
  132. package/rust/core/preprocessor/resolver/spawn.rs +99 -99
  133. package/rust/core/preprocessor/resolver/synth.rs +54 -54
  134. package/rust/core/preprocessor/resolver/tempo.rs +48 -48
  135. package/rust/core/preprocessor/resolver/trigger.rs +116 -116
  136. package/rust/core/preprocessor/resolver/value.rs +176 -176
  137. package/rust/core/store/global.rs +57 -57
  138. package/rust/lib.rs +323 -323
  139. package/rust/macros/Cargo.toml +14 -0
  140. package/rust/macros/src/lib.rs +52 -0
  141. package/rust/main.rs +311 -142
  142. package/rust/types/Cargo.toml +1 -1
  143. package/rust/types/src/addons.rs +3 -1
  144. package/rust/types/src/config.rs +1 -3
  145. package/rust/utils/Cargo.toml +5 -2
  146. package/rust/utils/src/file.rs +397 -14
  147. package/rust/utils/src/path.rs +31 -2
  148. package/rust/utils/src/version.rs +38 -7
  149. package/rust/web/auth.rs +5 -0
  150. package/rust/web/forge.rs +5 -0
  151. package/rust/web/mod.rs +5 -3
  152. package/typescript/scripts/version/copy-to-binary.ts +82 -0
  153. package/rust/cli/bank/api.rs +0 -122
  154. package/rust/cli/bank/commands.rs +0 -306
  155. package/rust/cli/bank/mod.rs +0 -29
  156. package/rust/cli/install/bank.rs +0 -72
  157. package/rust/cli/install/commands.rs +0 -35
  158. package/rust/cli/install/mod.rs +0 -4
  159. package/rust/cli/install/plugin.rs +0 -80
@@ -1,159 +1,159 @@
1
- use crate::{
2
- config::driver::ProjectConfig,
3
- core::{
4
- builder::Builder,
5
- debugger::{
6
- lexer::write_lexer_log_file,
7
- logs::{write_module_function_log_file, write_module_variable_log_file},
8
- preprocessor::write_preprocessor_log_file,
9
- store::{write_function_log_file, write_variables_log_file},
10
- },
11
- preprocessor::loader::ModuleLoader,
12
- store::global::GlobalStore,
13
- },
14
- };
15
- use devalang_utils::path::normalize_path;
16
- use devalang_utils::{
17
- logger::{LogLevel, Logger},
18
- spinner::start_spinner,
19
- };
20
-
21
- pub fn process_play(
22
- _config: &Option<ProjectConfig>,
23
- entry_file: &str,
24
- output: &str,
25
- audio_format: crate::cli::parser::AudioFormat,
26
- sample_rate: u32,
27
- debug: bool,
28
- ) -> Result<
29
- (
30
- f32,
31
- Vec<crate::core::parser::statement::Statement>,
32
- devalang_types::VariableTable,
33
- devalang_types::FunctionTable,
34
- crate::core::store::global::GlobalStore,
35
- ),
36
- String,
37
- > {
38
- let spinner = start_spinner("Building...");
39
-
40
- let normalized_entry = normalize_path(entry_file);
41
- let normalized_output_dir = normalize_path(output);
42
-
43
- let duration = std::time::Instant::now();
44
- let mut global_store = GlobalStore::new();
45
- let loader = ModuleLoader::new(&normalized_entry, &normalized_output_dir);
46
- let (modules_tokens, modules_statements) = loader.load_all_modules(&mut global_store);
47
-
48
- // Try to detect initial BPM from statements (fallback to 120.0)
49
- let mut detected_bpm: f32 = 120.0;
50
- let mut entry_statements: Vec<crate::core::parser::statement::Statement> = Vec::new();
51
- // Prefer the entry module if present
52
- if let Some(entry_stmts) = modules_statements.get(&normalized_entry) {
53
- entry_statements = entry_stmts.clone();
54
- for stmt in entry_stmts {
55
- if let crate::core::parser::statement::StatementKind::Tempo = &stmt.kind {
56
- use devalang_types::Value;
57
- if let Value::Number(n) = &stmt.value {
58
- detected_bpm = *n;
59
- break;
60
- }
61
- }
62
- }
63
- }
64
- // If still default, scan other modules for a tempo directive
65
- if (detected_bpm - 120.0).abs() < f32::EPSILON {
66
- 'outer: for (_name, stmts) in modules_statements.iter() {
67
- for stmt in stmts {
68
- if let crate::core::parser::statement::StatementKind::Tempo = &stmt.kind {
69
- use devalang_types::Value;
70
- if let Value::Number(n) = &stmt.value {
71
- detected_bpm = *n;
72
- break 'outer;
73
- }
74
- }
75
- }
76
- }
77
- }
78
-
79
- // SECTION Write logs
80
- if debug {
81
- for (module_path, module) in global_store.modules.clone() {
82
- write_module_variable_log_file(
83
- &normalized_output_dir,
84
- &module_path,
85
- &module.variable_table,
86
- );
87
- write_module_function_log_file(
88
- &normalized_output_dir,
89
- &module_path,
90
- &module.function_table,
91
- );
92
- }
93
-
94
- write_lexer_log_file(
95
- &normalized_output_dir,
96
- "lexer_tokens.log",
97
- modules_tokens.clone(),
98
- );
99
- write_preprocessor_log_file(
100
- &normalized_output_dir,
101
- "resolved_statements.log",
102
- modules_statements.clone(),
103
- );
104
- write_variables_log_file(
105
- &normalized_output_dir,
106
- "global_variables.log",
107
- global_store.variables.clone(),
108
- );
109
- write_function_log_file(
110
- &normalized_output_dir,
111
- "global_functions.log",
112
- global_store.functions.clone(),
113
- );
114
- }
115
-
116
- // SECTION Detect errors before building (like build.rs)
117
- let all_errors = crate::core::error::collect_all_errors_with_modules(&modules_statements);
118
- let (warnings, criticals) = crate::core::error::partition_errors(all_errors);
119
- crate::core::error::log_errors_with_stack("Play", &warnings, &criticals);
120
- if !criticals.is_empty() {
121
- spinner.finish_and_clear();
122
- return Err(format!(
123
- "play failed with {} critical error(s): {}",
124
- criticals.len(),
125
- criticals[0].message
126
- ));
127
- }
128
-
129
- // SECTION Building AST and Audio
130
- let builder = Builder::new();
131
- builder.build_ast(&modules_statements, output, false);
132
- let audio_format_str = format!("{:?}", audio_format);
133
- builder.build_audio(
134
- &modules_statements,
135
- output,
136
- &mut global_store,
137
- Some(audio_format_str),
138
- Some(sample_rate),
139
- );
140
-
141
- // SECTION Logging
142
- let logger = Logger::new();
143
- let success_message = format!(
144
- "Build completed successfully in {:.2?}. Output files written to: '{}'",
145
- duration.elapsed(),
146
- normalized_output_dir
147
- );
148
-
149
- spinner.finish_and_clear();
150
- logger.log_message(LogLevel::Success, &success_message);
151
-
152
- Ok((
153
- detected_bpm,
154
- entry_statements,
155
- global_store.variables.clone(),
156
- global_store.functions.clone(),
157
- global_store,
158
- ))
159
- }
1
+ use crate::{
2
+ config::driver::ProjectConfig,
3
+ core::{
4
+ builder::Builder,
5
+ debugger::{
6
+ lexer::write_lexer_log_file,
7
+ logs::{write_module_function_log_file, write_module_variable_log_file},
8
+ preprocessor::write_preprocessor_log_file,
9
+ store::{write_function_log_file, write_variables_log_file},
10
+ },
11
+ preprocessor::loader::ModuleLoader,
12
+ store::global::GlobalStore,
13
+ },
14
+ };
15
+ use devalang_utils::path::normalize_path;
16
+ use devalang_utils::{
17
+ logger::{LogLevel, Logger},
18
+ spinner::start_spinner,
19
+ };
20
+
21
+ pub fn process_play(
22
+ _config: &Option<ProjectConfig>,
23
+ entry_file: &str,
24
+ output: &str,
25
+ audio_format: crate::cli::parser::AudioFormat,
26
+ sample_rate: u32,
27
+ debug: bool,
28
+ ) -> Result<
29
+ (
30
+ f32,
31
+ Vec<crate::core::parser::statement::Statement>,
32
+ devalang_types::VariableTable,
33
+ devalang_types::FunctionTable,
34
+ crate::core::store::global::GlobalStore,
35
+ ),
36
+ String,
37
+ > {
38
+ let spinner = start_spinner("Building...");
39
+
40
+ let normalized_entry = normalize_path(entry_file);
41
+ let normalized_output_dir = normalize_path(output);
42
+
43
+ let duration = std::time::Instant::now();
44
+ let mut global_store = GlobalStore::new();
45
+ let loader = ModuleLoader::new(&normalized_entry, &normalized_output_dir);
46
+ let (modules_tokens, modules_statements) = loader.load_all_modules(&mut global_store);
47
+
48
+ // Try to detect initial BPM from statements (fallback to 120.0)
49
+ let mut detected_bpm: f32 = 120.0;
50
+ let mut entry_statements: Vec<crate::core::parser::statement::Statement> = Vec::new();
51
+ // Prefer the entry module if present
52
+ if let Some(entry_stmts) = modules_statements.get(&normalized_entry) {
53
+ entry_statements = entry_stmts.clone();
54
+ for stmt in entry_stmts {
55
+ if let crate::core::parser::statement::StatementKind::Tempo = &stmt.kind {
56
+ use devalang_types::Value;
57
+ if let Value::Number(n) = &stmt.value {
58
+ detected_bpm = *n;
59
+ break;
60
+ }
61
+ }
62
+ }
63
+ }
64
+ // If still default, scan other modules for a tempo directive
65
+ if (detected_bpm - 120.0).abs() < f32::EPSILON {
66
+ 'outer: for (_name, stmts) in modules_statements.iter() {
67
+ for stmt in stmts {
68
+ if let crate::core::parser::statement::StatementKind::Tempo = &stmt.kind {
69
+ use devalang_types::Value;
70
+ if let Value::Number(n) = &stmt.value {
71
+ detected_bpm = *n;
72
+ break 'outer;
73
+ }
74
+ }
75
+ }
76
+ }
77
+ }
78
+
79
+ // SECTION Write logs
80
+ if debug {
81
+ for (module_path, module) in global_store.modules.clone() {
82
+ write_module_variable_log_file(
83
+ &normalized_output_dir,
84
+ &module_path,
85
+ &module.variable_table,
86
+ );
87
+ write_module_function_log_file(
88
+ &normalized_output_dir,
89
+ &module_path,
90
+ &module.function_table,
91
+ );
92
+ }
93
+
94
+ write_lexer_log_file(
95
+ &normalized_output_dir,
96
+ "lexer_tokens.log",
97
+ modules_tokens.clone(),
98
+ );
99
+ write_preprocessor_log_file(
100
+ &normalized_output_dir,
101
+ "resolved_statements.log",
102
+ modules_statements.clone(),
103
+ );
104
+ write_variables_log_file(
105
+ &normalized_output_dir,
106
+ "global_variables.log",
107
+ global_store.variables.clone(),
108
+ );
109
+ write_function_log_file(
110
+ &normalized_output_dir,
111
+ "global_functions.log",
112
+ global_store.functions.clone(),
113
+ );
114
+ }
115
+
116
+ // SECTION Detect errors before building (like build.rs)
117
+ let all_errors = crate::core::error::collect_all_errors_with_modules(&modules_statements);
118
+ let (warnings, criticals) = crate::core::error::partition_errors(all_errors);
119
+ crate::core::error::log_errors_with_stack("Play", &warnings, &criticals);
120
+ if !criticals.is_empty() {
121
+ spinner.finish_and_clear();
122
+ return Err(format!(
123
+ "play failed with {} critical error(s): {}",
124
+ criticals.len(),
125
+ criticals[0].message
126
+ ));
127
+ }
128
+
129
+ // SECTION Building AST and Audio
130
+ let builder = Builder::new();
131
+ builder.build_ast(&modules_statements, output, false);
132
+ let audio_format_str = format!("{:?}", audio_format);
133
+ builder.build_audio(
134
+ &modules_statements,
135
+ output,
136
+ &mut global_store,
137
+ Some(audio_format_str),
138
+ Some(sample_rate),
139
+ );
140
+
141
+ // SECTION Logging
142
+ let logger = Logger::new();
143
+ let success_message = format!(
144
+ "Build completed successfully in {:.2?}. Output files written to: '{}'",
145
+ duration.elapsed(),
146
+ normalized_output_dir
147
+ );
148
+
149
+ spinner.finish_and_clear();
150
+ logger.log_message(LogLevel::Success, &success_message);
151
+
152
+ Ok((
153
+ detected_bpm,
154
+ entry_statements,
155
+ global_store.variables.clone(),
156
+ global_store.functions.clone(),
157
+ global_store,
158
+ ))
159
+ }
@@ -35,6 +35,8 @@ pub struct AudioEngine {
35
35
  pub buffer: Vec<i16>,
36
36
  /// Collected MIDI note events for export (non-audio representation).
37
37
  pub midi_events: Vec<MidiNoteEvent>,
38
+ /// Map target synth -> last inserted note sample ranges (start_sample, total_samples)
39
+ pub last_notes: std::collections::HashMap<String, Vec<(usize, usize)>>,
38
40
  /// Logical module name used for error traces/diagnostics.
39
41
  pub module_name: String,
40
42
  /// Simple diagnostic counter for inserted notes.
@@ -55,6 +57,7 @@ impl AudioEngine {
55
57
  note_count: 0,
56
58
  sample_rate: SAMPLE_RATE,
57
59
  channels: CHANNELS,
60
+ last_notes: std::collections::HashMap::new(),
58
61
  }
59
62
  }
60
63
 
@@ -134,6 +137,7 @@ impl AudioEngine {
134
137
 
135
138
  pub fn insert_note(
136
139
  &mut self,
140
+ owner: Option<String>,
137
141
  waveform: String,
138
142
  freq: f32,
139
143
  amp: f32,
@@ -142,10 +146,11 @@ impl AudioEngine {
142
146
  synth_params: HashMap<String, Value>,
143
147
  note_params: HashMap<String, Value>,
144
148
  automation: Option<HashMap<String, Value>>,
145
- ) {
149
+ ) -> Vec<(usize, usize)> {
146
150
  // Delegated implementation lives in notes.rs
147
151
  crate::core::audio::engine::notes::insert_note_impl(
148
152
  self,
153
+ owner,
149
154
  waveform,
150
155
  freq,
151
156
  amp,
@@ -154,7 +159,19 @@ impl AudioEngine {
154
159
  synth_params,
155
160
  note_params,
156
161
  automation,
157
- );
162
+ )
163
+ }
164
+
165
+ pub fn record_last_note_range(
166
+ &mut self,
167
+ owner: &str,
168
+ start_sample: usize,
169
+ total_samples: usize,
170
+ ) {
171
+ self.last_notes
172
+ .entry(owner.to_string())
173
+ .or_default()
174
+ .push((start_sample, total_samples));
158
175
  }
159
176
 
160
177
  // helper extraction functions left in this struct for now