@devaloop/devalang 0.0.1-alpha.3 → 0.0.1-alpha.5

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 (52) hide show
  1. package/.devalang +1 -1
  2. package/Cargo.toml +9 -7
  3. package/README.md +49 -25
  4. package/docs/CHANGELOG.md +30 -0
  5. package/docs/COMMANDS.md +31 -0
  6. package/docs/CONFIG.md +6 -4
  7. package/docs/ROADMAP.md +4 -4
  8. package/docs/TODO.md +4 -4
  9. package/examples/index.deva +9 -2
  10. package/examples/samples/hat-808.wav +0 -0
  11. package/out-tsc/bin/devalang.exe +0 -0
  12. package/package.json +44 -42
  13. package/project-version.json +6 -6
  14. package/rust/audio/engine.rs +126 -0
  15. package/rust/audio/interpreter.rs +143 -0
  16. package/rust/audio/loader.rs +46 -0
  17. package/rust/audio/mod.rs +5 -0
  18. package/rust/audio/player.rs +54 -0
  19. package/rust/audio/render.rs +57 -0
  20. package/rust/cli/build.rs +17 -5
  21. package/rust/cli/check.rs +2 -1
  22. package/rust/cli/init.rs +4 -2
  23. package/rust/cli/mod.rs +29 -0
  24. package/rust/cli/play.rs +192 -0
  25. package/rust/cli/template.rs +2 -1
  26. package/rust/config/loader.rs +0 -1
  27. package/rust/config/mod.rs +3 -2
  28. package/rust/core/builder/mod.rs +54 -6
  29. package/rust/core/debugger/lexer.rs +20 -5
  30. package/rust/core/debugger/preprocessor.rs +9 -5
  31. package/rust/core/lexer/handler/mod.rs +2 -2
  32. package/rust/core/lexer/handler/newline.rs +5 -1
  33. package/rust/core/lexer/mod.rs +10 -5
  34. package/rust/core/parser/handler/loop_.rs +11 -0
  35. package/rust/core/parser/mod.rs +0 -1
  36. package/rust/core/preprocessor/loader.rs +89 -16
  37. package/rust/core/preprocessor/module.rs +2 -0
  38. package/rust/core/preprocessor/resolver/bank.rs +46 -0
  39. package/rust/core/preprocessor/resolver/loop_.rs +148 -0
  40. package/rust/core/preprocessor/resolver/mod.rs +151 -0
  41. package/rust/core/preprocessor/resolver/tempo.rs +49 -0
  42. package/rust/core/preprocessor/resolver/trigger.rs +114 -0
  43. package/rust/lib.rs +118 -0
  44. package/rust/main.rs +8 -0
  45. package/rust/utils/logger.rs +45 -6
  46. package/rust/utils/spinner.rs +2 -0
  47. package/rust/utils/watcher.rs +10 -2
  48. package/templates/minimal/.devalang +2 -1
  49. package/templates/minimal/README.md +202 -0
  50. package/templates/welcome/.devalang +2 -1
  51. package/templates/welcome/README.md +48 -31
  52. package/rust/core/preprocessor/resolver.rs +0 -372
@@ -1,372 +0,0 @@
1
- use std::collections::HashMap;
2
-
3
- use crate::{
4
- core::{
5
- parser::statement::{ self, Statement, StatementKind },
6
- preprocessor::loader::ModuleLoader,
7
- shared::{ duration::Duration, value::Value },
8
- store::global::GlobalStore,
9
- utils::validation::{ is_valid_entity, is_valid_identifier },
10
- },
11
- utils::logger::Logger,
12
- };
13
-
14
- pub fn resolve_all_modules(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
15
- for module in global_store.clone().modules.values_mut() {
16
- resolve_imports(module_loader, global_store);
17
- }
18
- }
19
-
20
- pub fn resolve_imports(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
21
- for (module_path, module) in global_store.clone().modules.iter_mut() {
22
- for (name, source_path) in &module.import_table.imports {
23
- match source_path {
24
- Value::String(source_path) => {
25
- if let Some(source_module) = global_store.modules.get(source_path) {
26
- if let Some(value) = source_module.export_table.get_export(name) {
27
- module.variable_table.set(name.clone(), value.clone());
28
- } else {
29
- println!(
30
- "[warn] '{module_path}': '{name}' not found in exports of '{source_path}'"
31
- );
32
- }
33
- } else {
34
- println!(
35
- "[warn] '{module_path}': cannot find source module '{source_path}'"
36
- );
37
- }
38
- }
39
- _ => {
40
- println!(
41
- "[warn] '{module_path}': expected string for import source, found {:?}",
42
- source_path
43
- );
44
- }
45
- }
46
- }
47
- }
48
- }
49
-
50
- pub fn resolve_and_flatten_all_modules(
51
- global_store: &mut GlobalStore
52
- ) -> HashMap<String, Vec<Statement>> {
53
- let logger = Logger::new();
54
-
55
- // 1. Imports resolving
56
- let global_store_clone = global_store.clone();
57
- for (module_path, module) in global_store.modules.iter_mut() {
58
- for (name, source_path) in &module.import_table.imports {
59
- match source_path {
60
- Value::String(source_path) => {
61
- if let Some(source_module) = global_store_clone.modules.get(source_path) {
62
- if let Some(value) = source_module.export_table.get_export(name) {
63
- module.variable_table.set(name.clone(), value.clone());
64
- } else {
65
- let message = format!(
66
- "'{name}' not found in exports of '{source_path}'"
67
- );
68
- logger.log_error_with_stacktrace(&message, module_path);
69
- }
70
- } else {
71
- let message = format!("cannot find source module '{source_path}'");
72
- logger.log_error_with_stacktrace(&message, module_path);
73
- }
74
- }
75
- _ => {
76
- let message = format!(
77
- "expected string for import source, found {:?}",
78
- source_path
79
- );
80
- logger.log_error_with_stacktrace(&message, module_path);
81
- }
82
- }
83
- }
84
- }
85
-
86
- // 2. Full statement resolution
87
- let mut resolved_map = HashMap::new();
88
-
89
- for (path, module) in &global_store.modules {
90
- let mut resolved = Vec::new();
91
-
92
- for mut stmt in module.statements.clone() {
93
- match &mut stmt.kind {
94
- StatementKind::Bank => {
95
- if let Value::Identifier(ident) = &stmt.value {
96
- if let Some(val) = module.variable_table.get(ident) {
97
- stmt.value = val.clone();
98
- } else {
99
- let message = format!(
100
- "Bank identifier '{ident}' not found in variable table"
101
- );
102
-
103
- logger.log_error_with_stacktrace(&message, &module.path);
104
-
105
- stmt.kind = StatementKind::Error {
106
- message: format!(
107
- "Bank identifier '{ident}' not found in variable table"
108
- ),
109
- };
110
- stmt.value = Value::Null;
111
- }
112
- } else if let Value::String(_) = &stmt.value {
113
- // Value is already a string, no need to modify
114
- } else {
115
- let message = format!(
116
- "Expected a string or identifier for bank, found {:?}",
117
- stmt.value
118
- );
119
-
120
- logger.log_error_with_stacktrace(&message, &module.path);
121
-
122
- stmt.kind = StatementKind::Error {
123
- message: "Expected a string or identifier for bank".to_string(),
124
- };
125
- stmt.value = Value::Null;
126
- }
127
- }
128
-
129
- StatementKind::Tempo => {
130
- if let Value::Identifier(ident) = &stmt.value {
131
- if let Some(val) = module.variable_table.get(ident) {
132
- stmt.value = val.clone();
133
- } else {
134
- let message = format!(
135
- "Tempo identifier '{ident}' not found in variable table"
136
- );
137
-
138
- logger.log_error_with_stacktrace(&message, &module.path);
139
-
140
- stmt.kind = StatementKind::Error {
141
- message: format!(
142
- "Tempo identifier '{ident}' not found in variable table"
143
- ),
144
- };
145
- stmt.value = Value::Null;
146
- }
147
- } else if let Value::Number(_) = &stmt.value {
148
- // Value is already a number, no need to modify
149
- } else {
150
- let message = format!(
151
- "Expected a number or identifier for tempo, found {:?}",
152
- stmt.value
153
- );
154
-
155
- logger.log_error_with_stacktrace(&message, &module.path);
156
-
157
- stmt.kind = StatementKind::Error {
158
- message: "Expected a number or identifier for tempo".to_string(),
159
- };
160
- stmt.value = Value::Null;
161
- }
162
- }
163
-
164
- StatementKind::Trigger { entity, duration } => {
165
- if !is_valid_entity(entity, module, global_store) {
166
- let message =
167
- format!("Invalid entity '{}', expected a valid identifier", entity);
168
-
169
- let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
170
- logger.log_error_with_stacktrace(&message, &stacktrace);
171
-
172
- stmt.kind = StatementKind::Error {
173
- message: format!("Invalid entity '{}'", entity),
174
- };
175
- stmt.value = Value::Null;
176
-
177
- resolved.push(stmt);
178
- continue;
179
- }
180
-
181
- // Duration resolution
182
- if let Duration::Identifier(ident) = duration {
183
- if let Some(val) = module.variable_table.get(ident) {
184
- match val {
185
- Value::Number(num) => {
186
- *duration = Duration::Number(*num);
187
- }
188
- Value::String(s) => {
189
- *duration = Duration::Identifier(s.clone());
190
- }
191
- Value::Identifier(id) if id == "auto" => {
192
- *duration = Duration::Auto;
193
- }
194
- _ => {}
195
- }
196
- }
197
- }
198
-
199
- // Associated value resolution
200
- if let Value::Identifier(ident) = &stmt.value {
201
- if let Some(val) = module.variable_table.get(ident) {
202
- stmt.value = val.clone();
203
- } else {
204
- let stacktrace = format!(
205
- "{}:{}:{}",
206
- module.path,
207
- stmt.line,
208
- stmt.column
209
- );
210
- let message = format!(
211
- "'{path}': value identifier '{ident}' not found in variable table"
212
- );
213
-
214
- logger.log_error_with_stacktrace(&message, &stacktrace);
215
-
216
- stmt.kind = StatementKind::Error {
217
- message: format!(
218
- "Value identifier '{ident}' not found in variable table"
219
- ),
220
- };
221
- stmt.value = Value::Null;
222
- }
223
- }
224
- }
225
-
226
- StatementKind::Let { .. } => {
227
- if let Value::Identifier(ident) = &stmt.value {
228
- if let Some(val) = module.variable_table.get(ident) {
229
- stmt.value = val.clone();
230
- } else {
231
- if !is_valid_identifier(ident, module) {
232
- let message = format!(
233
- "'{path}': value identifier '{ident}' not found in variable table"
234
- );
235
-
236
- logger.log_error_with_stacktrace(&message, &module.path);
237
-
238
- stmt.kind = StatementKind::Error {
239
- message: format!(
240
- "Value identifier '{ident}' not found in variable table"
241
- ),
242
- };
243
- stmt.value = Value::Null;
244
- } else {
245
- stmt.value = Value::Identifier(ident.clone());
246
- }
247
- }
248
- }
249
- }
250
-
251
- StatementKind::Loop => {
252
- if let Value::Map(value_map) = &stmt.value {
253
- let iterator_value = match value_map.get("iterator") {
254
- Some(Value::Identifier(ident)) => {
255
- if let Some(val) = module.variable_table.get(ident) {
256
- match val {
257
- Value::Number(n) => Value::Number(*n),
258
- _ => {
259
- let message = format!(
260
- "Loop iterator '{ident}' must resolve to a number"
261
- );
262
- let stacktrace = format!(
263
- "{}:{}:{}",
264
- module.path,
265
- stmt.line,
266
- stmt.column
267
- );
268
- logger.log_error_with_stacktrace(&message, &stacktrace);
269
-
270
- stmt.kind = StatementKind::Error {
271
- message,
272
- };
273
- Value::Null
274
- }
275
- }
276
- } else {
277
- let message = format!(
278
- "'{path}': loop iterator '{ident}' not found in variable table"
279
- );
280
- let stacktrace = format!(
281
- "{}:{}:{}",
282
- module.path,
283
- stmt.line,
284
- stmt.column
285
- );
286
- logger.log_error_with_stacktrace(&message, &stacktrace);
287
-
288
- stmt.kind = StatementKind::Error {
289
- message: format!("Loop iterator '{ident}' not found"),
290
- };
291
- Value::Null
292
- }
293
- }
294
-
295
- Some(Value::Number(n)) => Value::Number(*n),
296
-
297
- Some(v) => {
298
- let message = format!(
299
- "Unexpected value for loop iterator: {:?}, expected number or identifier",
300
- v
301
- );
302
- let stacktrace = format!(
303
- "{}:{}:{}",
304
- module.path,
305
- stmt.line,
306
- stmt.column
307
- );
308
- logger.log_error_with_stacktrace(&message, &stacktrace);
309
-
310
- stmt.kind = StatementKind::Error {
311
- message,
312
- };
313
- Value::Null
314
- }
315
-
316
- None => {
317
- let message = format!(
318
- "Missing 'iterator' key in loop statement map"
319
- );
320
- let stacktrace = format!(
321
- "{}:{}:{}",
322
- module.path,
323
- stmt.line,
324
- stmt.column
325
- );
326
- logger.log_error_with_stacktrace(&message, &stacktrace);
327
-
328
- stmt.kind = StatementKind::Error {
329
- message,
330
- };
331
- Value::Null
332
- }
333
- };
334
-
335
- let body_value = value_map.get("body").cloned().unwrap_or(Value::Null);
336
-
337
- let mut loop_map = std::collections::HashMap::new();
338
- loop_map.insert("iterator".to_string(), iterator_value);
339
- loop_map.insert("body".to_string(), body_value);
340
-
341
- stmt.value = Value::Map(loop_map);
342
- } else {
343
- let message = format!(
344
- "'{path}': expected a map for loop value, found {:?}",
345
- stmt.value
346
- );
347
- let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
348
-
349
- logger.log_error_with_stacktrace(&message, &stacktrace);
350
-
351
- stmt.kind = StatementKind::Error {
352
- message: "Expected a map for loop value".to_string(),
353
- };
354
- stmt.value = Value::Null;
355
- }
356
- }
357
-
358
- StatementKind::Import { names, source } => {}
359
-
360
- StatementKind::Export { names, source } => {}
361
-
362
- _ => {}
363
- }
364
-
365
- resolved.push(stmt);
366
- }
367
-
368
- resolved_map.insert(path.clone(), resolved);
369
- }
370
-
371
- resolved_map
372
- }