@devaloop/devalang 0.0.1-beta.2 → 0.1.1

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 (329) hide show
  1. package/README.md +177 -146
  2. package/out-tsc/api.d.ts +180 -0
  3. package/out-tsc/api.d.ts.map +1 -0
  4. package/out-tsc/api.js +286 -0
  5. package/out-tsc/api.js.map +1 -0
  6. package/out-tsc/bin/index.d.ts +12 -0
  7. package/out-tsc/bin/index.d.ts.map +1 -0
  8. package/out-tsc/bin/index.js +20 -54
  9. package/out-tsc/bin/index.js.map +1 -0
  10. package/out-tsc/examples/basic-usage.d.ts +8 -0
  11. package/out-tsc/examples/basic-usage.d.ts.map +1 -0
  12. package/out-tsc/examples/basic-usage.js +113 -0
  13. package/out-tsc/examples/basic-usage.js.map +1 -0
  14. package/out-tsc/index.d.ts +19 -5
  15. package/out-tsc/index.d.ts.map +1 -0
  16. package/out-tsc/index.js +24 -6
  17. package/out-tsc/index.js.map +1 -0
  18. package/out-tsc/scripts/copy-wasm-dts.d.ts +7 -0
  19. package/out-tsc/scripts/copy-wasm-dts.d.ts.map +1 -0
  20. package/out-tsc/scripts/copy-wasm-dts.js +36 -32
  21. package/out-tsc/scripts/copy-wasm-dts.js.map +1 -0
  22. package/out-tsc/scripts/postinstall.d.ts +1 -0
  23. package/out-tsc/scripts/postinstall.d.ts.map +1 -0
  24. package/out-tsc/scripts/postinstall.js +4 -1
  25. package/out-tsc/scripts/postinstall.js.map +1 -0
  26. package/out-tsc/scripts/version/bump.d.ts +5 -1
  27. package/out-tsc/scripts/version/bump.d.ts.map +1 -0
  28. package/out-tsc/scripts/version/bump.js +114 -44
  29. package/out-tsc/scripts/version/bump.js.map +1 -0
  30. package/out-tsc/scripts/version/fetch.d.ts +12 -1
  31. package/out-tsc/scripts/version/fetch.d.ts.map +1 -0
  32. package/out-tsc/scripts/version/fetch.js +68 -24
  33. package/out-tsc/scripts/version/fetch.js.map +1 -0
  34. package/out-tsc/scripts/version/index.d.ts +6 -0
  35. package/out-tsc/scripts/version/index.d.ts.map +1 -0
  36. package/out-tsc/scripts/version/index.js +44 -22
  37. package/out-tsc/scripts/version/index.js.map +1 -0
  38. package/out-tsc/scripts/version/sync.d.ts +5 -1
  39. package/out-tsc/scripts/version/sync.d.ts.map +1 -0
  40. package/out-tsc/scripts/version/sync.js +78 -29
  41. package/out-tsc/scripts/version/sync.js.map +1 -0
  42. package/out-tsc/types.d.ts +68 -0
  43. package/out-tsc/types.d.ts.map +1 -0
  44. package/out-tsc/{core/types/value.js → types.js} +4 -0
  45. package/out-tsc/types.js.map +1 -0
  46. package/out-tsc/wasm.d.ts +8 -0
  47. package/out-tsc/wasm.d.ts.map +1 -0
  48. package/out-tsc/{core/index.js → wasm.js} +9 -6
  49. package/out-tsc/wasm.js.map +1 -0
  50. package/package.json +50 -37
  51. package/.cargo/config.toml +0 -2
  52. package/.devalang +0 -9
  53. package/.github/workflows/ci.yml +0 -103
  54. package/Cargo.toml +0 -81
  55. package/docs/CHANGELOG.md +0 -581
  56. package/docs/CONTRIBUTING.md +0 -101
  57. package/docs/ROADMAP.md +0 -38
  58. package/docs/TODO.md +0 -71
  59. package/examples/automation.deva +0 -42
  60. package/examples/bank.deva +0 -7
  61. package/examples/bus.deva +0 -10
  62. package/examples/condition.deva +0 -20
  63. package/examples/duration.deva +0 -9
  64. package/examples/effect.deva +0 -2
  65. package/examples/events.deva +0 -12
  66. package/examples/filter.deva +0 -11
  67. package/examples/function.deva +0 -15
  68. package/examples/group.deva +0 -12
  69. package/examples/index.deva +0 -63
  70. package/examples/lfo.deva +0 -9
  71. package/examples/loop.deva +0 -10
  72. package/examples/pattern.deva +0 -8
  73. package/examples/plugin.deva +0 -16
  74. package/examples/samples/hat-808.wav +0 -0
  75. package/examples/samples/kick-808.wav +0 -0
  76. package/examples/synth.deva +0 -24
  77. package/examples/synth_types.deva +0 -17
  78. package/examples/variables.deva +0 -9
  79. package/out-tsc/core/functions/index.d.ts +0 -42
  80. package/out-tsc/core/functions/index.js +0 -87
  81. package/out-tsc/core/index.d.ts +0 -6
  82. package/out-tsc/core/types/index.d.ts +0 -4
  83. package/out-tsc/core/types/index.js +0 -20
  84. package/out-tsc/core/types/plugin.d.ts +0 -18
  85. package/out-tsc/core/types/plugin.js +0 -2
  86. package/out-tsc/core/types/result.d.ts +0 -27
  87. package/out-tsc/core/types/result.js +0 -2
  88. package/out-tsc/core/types/statement.d.ts +0 -106
  89. package/out-tsc/core/types/statement.js +0 -2
  90. package/out-tsc/core/types/value.d.ts +0 -43
  91. package/out-tsc/pkg/devalang_core.d.ts +0 -15
  92. package/out-tsc/pkg/devalang_core.js +0 -65
  93. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +0 -34
  94. package/project-version.json +0 -6
  95. package/rust/cli/bank/api.rs +0 -122
  96. package/rust/cli/bank/commands.rs +0 -306
  97. package/rust/cli/bank/mod.rs +0 -29
  98. package/rust/cli/build/commands.rs +0 -153
  99. package/rust/cli/build/mod.rs +0 -2
  100. package/rust/cli/build/process.rs +0 -165
  101. package/rust/cli/check/mod.rs +0 -208
  102. package/rust/cli/discover/commands.rs +0 -253
  103. package/rust/cli/discover/config.rs +0 -111
  104. package/rust/cli/discover/fs.rs +0 -19
  105. package/rust/cli/discover/install.rs +0 -103
  106. package/rust/cli/discover/metadata.rs +0 -48
  107. package/rust/cli/discover/mod.rs +0 -5
  108. package/rust/cli/init/commands.rs +0 -88
  109. package/rust/cli/init/mod.rs +0 -1
  110. package/rust/cli/install/addon.rs +0 -118
  111. package/rust/cli/install/bank.rs +0 -72
  112. package/rust/cli/install/commands.rs +0 -35
  113. package/rust/cli/install/mod.rs +0 -4
  114. package/rust/cli/install/plugin.rs +0 -80
  115. package/rust/cli/login/commands.rs +0 -124
  116. package/rust/cli/login/mod.rs +0 -1
  117. package/rust/cli/mod.rs +0 -12
  118. package/rust/cli/parser.rs +0 -359
  119. package/rust/cli/play/commands.rs +0 -375
  120. package/rust/cli/play/io.rs +0 -17
  121. package/rust/cli/play/mod.rs +0 -5
  122. package/rust/cli/play/process.rs +0 -159
  123. package/rust/cli/play/realtime.rs +0 -91
  124. package/rust/cli/play/utils.rs +0 -23
  125. package/rust/cli/telemetry/commands.rs +0 -22
  126. package/rust/cli/telemetry/event_creator.rs +0 -80
  127. package/rust/cli/telemetry/mod.rs +0 -3
  128. package/rust/cli/telemetry/send.rs +0 -51
  129. package/rust/cli/template/commands.rs +0 -69
  130. package/rust/cli/template/mod.rs +0 -1
  131. package/rust/cli/update/commands.rs +0 -6
  132. package/rust/cli/update/mod.rs +0 -1
  133. package/rust/config/driver.rs +0 -112
  134. package/rust/config/mod.rs +0 -3
  135. package/rust/config/ops.rs +0 -26
  136. package/rust/config/settings.rs +0 -101
  137. package/rust/core/audio/engine/driver.rs +0 -220
  138. package/rust/core/audio/engine/export.rs +0 -169
  139. package/rust/core/audio/engine/helpers.rs +0 -178
  140. package/rust/core/audio/engine/mod.rs +0 -56
  141. package/rust/core/audio/engine/notes/dsp.rs +0 -85
  142. package/rust/core/audio/engine/notes/mod.rs +0 -44
  143. package/rust/core/audio/engine/notes/params.rs +0 -294
  144. package/rust/core/audio/engine/sample/insert.rs +0 -199
  145. package/rust/core/audio/engine/sample/mod.rs +0 -40
  146. package/rust/core/audio/engine/sample/padding.rs +0 -170
  147. package/rust/core/audio/evaluator/condition.rs +0 -61
  148. package/rust/core/audio/evaluator/mod.rs +0 -9
  149. package/rust/core/audio/evaluator/numeric.rs +0 -152
  150. package/rust/core/audio/evaluator/rhs.rs +0 -16
  151. package/rust/core/audio/evaluator/string_expr.rs +0 -94
  152. package/rust/core/audio/interpreter/driver.rs +0 -574
  153. package/rust/core/audio/interpreter/mod.rs +0 -2
  154. package/rust/core/audio/interpreter/statements/arrow_call/interprete.rs +0 -175
  155. package/rust/core/audio/interpreter/statements/arrow_call/methods/chord.rs +0 -384
  156. package/rust/core/audio/interpreter/statements/arrow_call/methods/mod.rs +0 -2
  157. package/rust/core/audio/interpreter/statements/arrow_call/methods/note.rs +0 -316
  158. package/rust/core/audio/interpreter/statements/arrow_call/mod.rs +0 -3
  159. package/rust/core/audio/interpreter/statements/arrow_call/types/arp.rs +0 -192
  160. package/rust/core/audio/interpreter/statements/arrow_call/types/mod.rs +0 -24
  161. package/rust/core/audio/interpreter/statements/arrow_call/types/pad.rs +0 -116
  162. package/rust/core/audio/interpreter/statements/arrow_call/types/pluck.rs +0 -97
  163. package/rust/core/audio/interpreter/statements/arrow_call/types/sub.rs +0 -100
  164. package/rust/core/audio/interpreter/statements/automate.rs +0 -16
  165. package/rust/core/audio/interpreter/statements/call.rs +0 -295
  166. package/rust/core/audio/interpreter/statements/condition.rs +0 -72
  167. package/rust/core/audio/interpreter/statements/function.rs +0 -24
  168. package/rust/core/audio/interpreter/statements/let_.rs +0 -36
  169. package/rust/core/audio/interpreter/statements/load.rs +0 -17
  170. package/rust/core/audio/interpreter/statements/loop_.rs +0 -115
  171. package/rust/core/audio/interpreter/statements/mod.rs +0 -12
  172. package/rust/core/audio/interpreter/statements/sleep.rs +0 -28
  173. package/rust/core/audio/interpreter/statements/spawn.rs +0 -253
  174. package/rust/core/audio/interpreter/statements/tempo.rs +0 -40
  175. package/rust/core/audio/interpreter/statements/trigger.rs +0 -239
  176. package/rust/core/audio/loader/mod.rs +0 -1
  177. package/rust/core/audio/loader/trigger.rs +0 -98
  178. package/rust/core/audio/mod.rs +0 -6
  179. package/rust/core/audio/player.rs +0 -70
  180. package/rust/core/audio/special/easing.rs +0 -189
  181. package/rust/core/audio/special/env.rs +0 -45
  182. package/rust/core/audio/special/math.rs +0 -134
  183. package/rust/core/audio/special/mod.rs +0 -9
  184. package/rust/core/audio/special/modulator.rs +0 -143
  185. package/rust/core/builder/mod.rs +0 -129
  186. package/rust/core/debugger/lexer.rs +0 -27
  187. package/rust/core/debugger/logs.rs +0 -52
  188. package/rust/core/debugger/mod.rs +0 -30
  189. package/rust/core/debugger/preprocessor.rs +0 -27
  190. package/rust/core/debugger/store.rs +0 -38
  191. package/rust/core/error/mod.rs +0 -269
  192. package/rust/core/lexer/driver.rs +0 -59
  193. package/rust/core/lexer/handler/arrow.rs +0 -82
  194. package/rust/core/lexer/handler/at.rs +0 -21
  195. package/rust/core/lexer/handler/brace.rs +0 -41
  196. package/rust/core/lexer/handler/colon.rs +0 -21
  197. package/rust/core/lexer/handler/comment.rs +0 -30
  198. package/rust/core/lexer/handler/dot.rs +0 -21
  199. package/rust/core/lexer/handler/driver.rs +0 -337
  200. package/rust/core/lexer/handler/identifier.rs +0 -47
  201. package/rust/core/lexer/handler/indent.rs +0 -66
  202. package/rust/core/lexer/handler/mod.rs +0 -15
  203. package/rust/core/lexer/handler/newline.rs +0 -23
  204. package/rust/core/lexer/handler/number.rs +0 -31
  205. package/rust/core/lexer/handler/operator.rs +0 -46
  206. package/rust/core/lexer/handler/parenthesis.rs +0 -41
  207. package/rust/core/lexer/handler/slash.rs +0 -21
  208. package/rust/core/lexer/handler/string.rs +0 -63
  209. package/rust/core/lexer/mod.rs +0 -3
  210. package/rust/core/lexer/token.rs +0 -91
  211. package/rust/core/mod.rs +0 -9
  212. package/rust/core/parser/driver/block.rs +0 -111
  213. package/rust/core/parser/driver/cursor.rs +0 -82
  214. package/rust/core/parser/driver/driver_impl.rs +0 -139
  215. package/rust/core/parser/driver/mod.rs +0 -6
  216. package/rust/core/parser/driver/parse_array.rs +0 -120
  217. package/rust/core/parser/driver/parse_map.rs +0 -223
  218. package/rust/core/parser/driver/parser.rs +0 -160
  219. package/rust/core/parser/handler/arrow_call.rs +0 -277
  220. package/rust/core/parser/handler/at.rs +0 -279
  221. package/rust/core/parser/handler/bank.rs +0 -104
  222. package/rust/core/parser/handler/condition.rs +0 -83
  223. package/rust/core/parser/handler/dot.rs +0 -148
  224. package/rust/core/parser/handler/identifier/automate.rs +0 -254
  225. package/rust/core/parser/handler/identifier/call.rs +0 -91
  226. package/rust/core/parser/handler/identifier/emit.rs +0 -70
  227. package/rust/core/parser/handler/identifier/function.rs +0 -113
  228. package/rust/core/parser/handler/identifier/group.rs +0 -89
  229. package/rust/core/parser/handler/identifier/let_.rs +0 -173
  230. package/rust/core/parser/handler/identifier/mod.rs +0 -55
  231. package/rust/core/parser/handler/identifier/on.rs +0 -107
  232. package/rust/core/parser/handler/identifier/print.rs +0 -49
  233. package/rust/core/parser/handler/identifier/sleep.rs +0 -96
  234. package/rust/core/parser/handler/identifier/spawn.rs +0 -91
  235. package/rust/core/parser/handler/identifier/synth.rs +0 -135
  236. package/rust/core/parser/handler/loop_.rs +0 -194
  237. package/rust/core/parser/handler/mod.rs +0 -9
  238. package/rust/core/parser/handler/pattern.rs +0 -74
  239. package/rust/core/parser/handler/tempo.rs +0 -105
  240. package/rust/core/parser/mod.rs +0 -3
  241. package/rust/core/parser/statement.rs +0 -10
  242. package/rust/core/plugin/loader.rs +0 -137
  243. package/rust/core/plugin/mod.rs +0 -2
  244. package/rust/core/plugin/runner/mod.rs +0 -11
  245. package/rust/core/plugin/runner/non_wasm.rs +0 -297
  246. package/rust/core/plugin/runner/wasm32.rs +0 -43
  247. package/rust/core/preprocessor/loader/inject.rs +0 -278
  248. package/rust/core/preprocessor/loader/loader_helpers.rs +0 -110
  249. package/rust/core/preprocessor/loader/mod.rs +0 -235
  250. package/rust/core/preprocessor/mod.rs +0 -4
  251. package/rust/core/preprocessor/module.rs +0 -55
  252. package/rust/core/preprocessor/processor/handlers.rs +0 -107
  253. package/rust/core/preprocessor/processor/mod.rs +0 -1
  254. package/rust/core/preprocessor/resolver/bank.rs +0 -49
  255. package/rust/core/preprocessor/resolver/call.rs +0 -124
  256. package/rust/core/preprocessor/resolver/condition.rs +0 -95
  257. package/rust/core/preprocessor/resolver/driver.rs +0 -324
  258. package/rust/core/preprocessor/resolver/function.rs +0 -69
  259. package/rust/core/preprocessor/resolver/group.rs +0 -122
  260. package/rust/core/preprocessor/resolver/let_.rs +0 -32
  261. package/rust/core/preprocessor/resolver/loop_.rs +0 -318
  262. package/rust/core/preprocessor/resolver/mod.rs +0 -16
  263. package/rust/core/preprocessor/resolver/pattern.rs +0 -83
  264. package/rust/core/preprocessor/resolver/spawn.rs +0 -99
  265. package/rust/core/preprocessor/resolver/synth.rs +0 -54
  266. package/rust/core/preprocessor/resolver/tempo.rs +0 -48
  267. package/rust/core/preprocessor/resolver/trigger.rs +0 -116
  268. package/rust/core/preprocessor/resolver/value.rs +0 -176
  269. package/rust/core/store/global.rs +0 -57
  270. package/rust/core/store/mod.rs +0 -1
  271. package/rust/lib.rs +0 -323
  272. package/rust/main.rs +0 -388
  273. package/rust/types/Cargo.toml +0 -11
  274. package/rust/types/src/addons.rs +0 -55
  275. package/rust/types/src/ast.rs +0 -202
  276. package/rust/types/src/config.rs +0 -84
  277. package/rust/types/src/lib.rs +0 -15
  278. package/rust/types/src/plugin.rs +0 -20
  279. package/rust/types/src/store.rs +0 -139
  280. package/rust/types/src/telemetry.rs +0 -85
  281. package/rust/utils/Cargo.toml +0 -26
  282. package/rust/utils/src/error.rs +0 -186
  283. package/rust/utils/src/file.rs +0 -94
  284. package/rust/utils/src/first_usage.rs +0 -97
  285. package/rust/utils/src/lib.rs +0 -9
  286. package/rust/utils/src/logger.rs +0 -200
  287. package/rust/utils/src/path.rs +0 -129
  288. package/rust/utils/src/signature.rs +0 -41
  289. package/rust/utils/src/spinner.rs +0 -20
  290. package/rust/utils/src/version.rs +0 -27
  291. package/rust/utils/src/watcher.rs +0 -46
  292. package/rust/web/api.rs +0 -5
  293. package/rust/web/cdn.rs +0 -34
  294. package/rust/web/mod.rs +0 -3
  295. package/rust/web/sso.rs +0 -5
  296. package/templates/minimal/.devalang +0 -5
  297. package/templates/minimal/README.md +0 -218
  298. package/templates/minimal/src/index.deva +0 -2
  299. package/templates/welcome/.devalang +0 -5
  300. package/templates/welcome/README.md +0 -218
  301. package/templates/welcome/samples/kick-808.wav +0 -0
  302. package/templates/welcome/src/index.deva +0 -61
  303. package/templates/welcome/src/variables.deva +0 -3
  304. package/tests/integration.rs +0 -21
  305. package/tests/rust/cli_check_build.rs +0 -21
  306. package/tests/rust/cli_help.rs +0 -12
  307. package/tests/rust/cli_template_list.rs +0 -10
  308. package/tests/rust/cli_version.rs +0 -11
  309. package/tests/typescript/index.spec.ts +0 -136
  310. package/tests/typescript/playhead.spec.ts +0 -36
  311. package/tests/typescript/render_e2e.spec.ts +0 -77
  312. package/tsconfig.json +0 -115
  313. package/typescript/bin/index.ts +0 -28
  314. package/typescript/core/functions/index.ts +0 -94
  315. package/typescript/core/index.ts +0 -6
  316. package/typescript/core/types/index.ts +0 -4
  317. package/typescript/core/types/plugin.ts +0 -19
  318. package/typescript/core/types/result.ts +0 -29
  319. package/typescript/core/types/statement.ts +0 -47
  320. package/typescript/core/types/value.ts +0 -29
  321. package/typescript/index.ts +0 -8
  322. package/typescript/pkg/devalang_core.d.ts +0 -4
  323. package/typescript/pkg/devalang_core.ts +0 -65
  324. package/typescript/scripts/copy-wasm-dts.ts +0 -41
  325. package/typescript/scripts/postinstall.ts +0 -85
  326. package/typescript/scripts/version/bump.ts +0 -44
  327. package/typescript/scripts/version/fetch.ts +0 -18
  328. package/typescript/scripts/version/index.ts +0 -25
  329. package/typescript/scripts/version/sync.ts +0 -24
@@ -1,115 +0,0 @@
1
- use devalang_types::Value;
2
-
3
- use crate::core::{
4
- audio::{engine::AudioEngine, interpreter::driver::execute_audio_block},
5
- parser::statement::Statement,
6
- store::global::GlobalStore,
7
- };
8
- use devalang_types::store::{FunctionTable, VariableTable};
9
-
10
- pub fn interprete_loop_statement(
11
- stmt: &Statement,
12
- audio_engine: &mut AudioEngine,
13
- global_store: &GlobalStore,
14
- variable_table: &VariableTable,
15
- functions_table: &FunctionTable,
16
- base_bpm: f32,
17
- base_duration: f32,
18
- max_end_time: f32,
19
- cursor_time: f32,
20
- ) -> (f32, f32) {
21
- if let Value::Map(loop_value) = &stmt.value {
22
- // Foreach form: { foreach: Identifier(name), array: Array([...]), body: Block }
23
- if let (
24
- Some(Value::Identifier(var_name)),
25
- Some(Value::Array(items)),
26
- Some(Value::Block(loop_body)),
27
- ) = (
28
- loop_value.get("foreach"),
29
- loop_value.get("array"),
30
- loop_value.get("body"),
31
- ) {
32
- let engine = audio_engine;
33
- let mut cur_time = cursor_time;
34
- let mut max_time = max_end_time;
35
-
36
- for item in items {
37
- let mut scoped_vars = variable_table.clone();
38
- scoped_vars.set(var_name.clone(), item.clone());
39
-
40
- let (block_end_time, new_cursor) = execute_audio_block(
41
- engine,
42
- global_store,
43
- scoped_vars,
44
- functions_table.clone(),
45
- loop_body,
46
- base_bpm,
47
- base_duration,
48
- max_time,
49
- cur_time,
50
- );
51
-
52
- cur_time = new_cursor.max(block_end_time);
53
- max_time = max_time.max(cur_time);
54
- }
55
-
56
- return (max_time, cur_time);
57
- }
58
-
59
- let loop_count = match loop_value.get("iterator") {
60
- Some(Value::Number(n)) => *n as usize,
61
- Some(Value::Identifier(ident)) => {
62
- if let Some(Value::Number(n)) = variable_table.get(ident) {
63
- *n as usize
64
- } else {
65
- eprintln!("❌ Loop iterator must be a number, found: {:?}", ident);
66
- return (max_end_time, cursor_time);
67
- }
68
- }
69
- _ => {
70
- eprintln!(
71
- "❌ Loop iterator must be a number, found: {:?}",
72
- loop_value.get("iterator")
73
- );
74
- return (max_end_time, cursor_time);
75
- }
76
- };
77
-
78
- let loop_body = match loop_value.get("body") {
79
- Some(Value::Block(body)) => body.clone(),
80
- _ => {
81
- eprintln!(
82
- "❌ Loop body must be a block, found: {:?}",
83
- loop_value.get("body")
84
- );
85
- return (max_end_time, cursor_time);
86
- }
87
- };
88
-
89
- let engine = audio_engine;
90
- let mut cur_time = cursor_time;
91
- let mut max_time = max_end_time;
92
-
93
- for _ in 0..loop_count {
94
- let (block_end_time, new_cursor) = execute_audio_block(
95
- engine,
96
- global_store,
97
- variable_table.clone(),
98
- functions_table.clone(),
99
- &loop_body,
100
- base_bpm,
101
- base_duration,
102
- max_time,
103
- cur_time,
104
- );
105
-
106
- cur_time = new_cursor.max(block_end_time);
107
- max_time = max_time.max(cur_time);
108
- }
109
-
110
- return (max_time, cur_time);
111
- }
112
-
113
- eprintln!("❌ Loop statement value is not a map");
114
- (max_end_time, cursor_time)
115
- }
@@ -1,12 +0,0 @@
1
- pub mod arrow_call;
2
- pub mod automate;
3
- pub mod call;
4
- pub mod condition;
5
- pub mod function;
6
- pub mod let_;
7
- pub mod load;
8
- pub mod loop_;
9
- pub mod sleep;
10
- pub mod spawn;
11
- pub mod tempo;
12
- pub mod trigger;
@@ -1,28 +0,0 @@
1
- use crate::core::parser::statement::Statement;
2
- use devalang_types::Value;
3
-
4
- pub fn interprete_sleep_statement(
5
- stmt: &Statement,
6
- cursor_time: f32,
7
- max_end_time: f32,
8
- ) -> (f32, f32) {
9
- let duration_secs = match &stmt.value {
10
- Value::Number(ms) => *ms / 1000.0,
11
- Value::String(s) if s.ends_with("ms") => s
12
- .trim_end_matches("ms")
13
- .parse::<f32>()
14
- .map(|ms| ms / 1000.0)
15
- .unwrap_or_else(|_| {
16
- eprintln!("❌ Invalid sleep value (ms): {}", s);
17
- 0.0
18
- }),
19
- other => {
20
- eprintln!("❌ Invalid sleep value: {:?}", other);
21
- 0.0
22
- }
23
- };
24
-
25
- let new_cursor = cursor_time + duration_secs;
26
- let new_max = max_end_time.max(new_cursor);
27
- (new_cursor, new_max)
28
- }
@@ -1,253 +0,0 @@
1
- use devalang_types::{Duration, Value};
2
-
3
- use crate::core::{
4
- audio::{engine::AudioEngine, interpreter::driver::execute_audio_block},
5
- parser::statement::{Statement, StatementKind},
6
- store::global::GlobalStore,
7
- };
8
- use devalang_types::store::{FunctionTable, VariableTable};
9
-
10
- pub fn interprete_spawn_statement(
11
- stmt: &Statement,
12
- audio_engine: &mut AudioEngine,
13
- variable_table: &VariableTable,
14
- functions: &FunctionTable,
15
- global_store: &GlobalStore,
16
- base_bpm: f32,
17
- base_duration: f32,
18
- max_end_time: f32,
19
- cursor_time: f32,
20
- ) -> (f32, f32) {
21
- if let StatementKind::Spawn { name, args } = &stmt.kind {
22
- let mut local_engine = AudioEngine::new(audio_engine.module_name.clone());
23
-
24
- // Function case
25
- if let Some(func) = functions.functions.get(name) {
26
- if func.parameters.len() != args.len() {
27
- return (max_end_time, cursor_time);
28
- }
29
-
30
- let mut local_vars = VariableTable::with_parent(variable_table.clone());
31
- for (param, arg) in func.parameters.iter().zip(args) {
32
- local_vars.set(param.clone(), arg.clone());
33
- }
34
-
35
- let (spawn_max, _) = execute_audio_block(
36
- &mut local_engine,
37
- global_store,
38
- local_vars,
39
- functions.clone(),
40
- &func.body,
41
- base_bpm,
42
- base_duration,
43
- 0.0,
44
- 0.0,
45
- );
46
-
47
- audio_engine.merge_with(local_engine);
48
- return (spawn_max.max(max_end_time), cursor_time);
49
- }
50
-
51
- // Group case
52
- if let Some(group_stmt) = find_group(name, variable_table, global_store) {
53
- if let Value::Map(map) = &group_stmt.value {
54
- if let Some(Value::Block(body)) = map.get("body") {
55
- let (spawn_max, _) = execute_audio_block(
56
- &mut local_engine,
57
- global_store,
58
- variable_table.clone(),
59
- functions.clone(),
60
- body,
61
- base_bpm,
62
- base_duration,
63
- 0.0,
64
- 0.0,
65
- );
66
- audio_engine.merge_with(local_engine);
67
- return (spawn_max.max(max_end_time), cursor_time);
68
- }
69
- }
70
- }
71
-
72
- // Pattern case: allow spawning a pattern similar to call
73
- if let Some(pattern_stmt) = find_pattern(name, variable_table, global_store) {
74
- if let Value::String(pat) = &pattern_stmt.value {
75
- let mut target_entity = name.clone();
76
- if let StatementKind::Pattern { name: _n, target } = &pattern_stmt.kind {
77
- if let Some(t) = target {
78
- target_entity = t.clone();
79
- }
80
- }
81
-
82
- let final_variable_table = if let Some(parent) = &variable_table.parent {
83
- devalang_types::VariableTable {
84
- variables: parent.variables.clone(),
85
- parent: None,
86
- }
87
- } else {
88
- variable_table.clone()
89
- };
90
-
91
- let pattern_str: String = pat.chars().filter(|c| !c.is_whitespace()).collect();
92
- if pattern_str.is_empty() {
93
- return (max_end_time, cursor_time);
94
- }
95
-
96
- let step_count = pattern_str.len() as f32;
97
- let total_bar = 4.0 * base_duration;
98
- let step_duration = total_bar / step_count;
99
-
100
- let mut updated_max = max_end_time;
101
-
102
- for (i, ch) in pattern_str.chars().enumerate() {
103
- if ch == '-' {
104
- continue;
105
- }
106
-
107
- let event_time = cursor_time + (i as f32) * step_duration;
108
-
109
- let mut trigger_val = Value::String(target_entity.clone());
110
- if let Some(val) = variable_table.variables.get(&target_entity) {
111
- match val {
112
- Value::Identifier(id) => {
113
- if let Some(parent) = &variable_table.parent {
114
- if let Some(v) = parent.get(id) {
115
- trigger_val = v.clone();
116
- }
117
- } else if let Some(v) = variable_table.get(id) {
118
- trigger_val = v.clone();
119
- }
120
- }
121
- Value::Map(map) => {
122
- if let Some(Value::String(src)) = map.get("entity") {
123
- trigger_val = Value::String(src.clone());
124
- } else if let Some(Value::Identifier(src)) = map.get("entity") {
125
- trigger_val = Value::Identifier(src.clone());
126
- }
127
- }
128
- Value::Sample(sample_src) => {
129
- trigger_val = Value::Sample(sample_src.clone());
130
- }
131
- _ => {}
132
- }
133
- }
134
-
135
- let (src, sample_length) = crate::core::audio::loader::trigger::load_trigger(
136
- &trigger_val,
137
- &Duration::Number(step_duration),
138
- &None,
139
- base_duration,
140
- final_variable_table.clone(),
141
- );
142
-
143
- let play_length = step_duration.min(sample_length);
144
-
145
- let trigger_src = match trigger_val.get("entity") {
146
- Some(Value::String(s)) => s.clone(),
147
- Some(Value::Identifier(id)) => id.clone(),
148
- Some(Value::Statement(stmt)) => {
149
- if let StatementKind::Trigger { entity, .. } = &stmt.kind {
150
- entity.clone()
151
- } else {
152
- src.clone()
153
- }
154
- }
155
- _ => src.clone(),
156
- };
157
-
158
- audio_engine.insert_sample(
159
- &trigger_src,
160
- event_time,
161
- play_length,
162
- None,
163
- &final_variable_table,
164
- );
165
-
166
- let end_time = event_time + play_length;
167
- if end_time > updated_max {
168
- updated_max = end_time;
169
- }
170
- }
171
-
172
- audio_engine.merge_with(local_engine);
173
- return (updated_max.max(max_end_time), cursor_time);
174
- }
175
- }
176
-
177
- // Function or group not found
178
- }
179
-
180
- (max_end_time, cursor_time)
181
- }
182
-
183
- fn find_group<'a>(
184
- name: &str,
185
- variable_table: &'a VariableTable,
186
- global_store: &'a GlobalStore,
187
- ) -> Option<&'a Statement> {
188
- if let Some(Value::Statement(stmt_box)) = variable_table.get(name) {
189
- if let StatementKind::Group = stmt_box.kind {
190
- return Some(stmt_box);
191
- }
192
- }
193
- if let Some(Value::Statement(stmt_box)) = global_store.variables.variables.get(name) {
194
- if let StatementKind::Group = stmt_box.kind {
195
- return Some(stmt_box);
196
- }
197
- }
198
- None
199
- }
200
-
201
- fn find_pattern(
202
- name: &str,
203
- variable_table: &VariableTable,
204
- global_store: &GlobalStore,
205
- ) -> Option<Statement> {
206
- use crate::core::parser::statement::Statement;
207
- use crate::core::parser::statement::StatementKind;
208
-
209
- if let Some(Value::Statement(stmt_box)) = variable_table.get(name) {
210
- if let StatementKind::Pattern { .. } = stmt_box.kind {
211
- return Some(*stmt_box.clone());
212
- }
213
- }
214
-
215
- if let Some(val) = global_store.variables.variables.get(name) {
216
- match val {
217
- Value::Statement(stmt_box) => {
218
- if let StatementKind::Pattern { .. } = stmt_box.kind {
219
- return Some(*stmt_box.clone());
220
- }
221
- }
222
- Value::Map(map) => {
223
- if let Some(Value::String(_pat)) = map.get("pattern") {
224
- // Rebuild a Pattern statement from stored map if possible
225
- let stmt = Statement {
226
- kind: StatementKind::Pattern {
227
- name: name.to_string(),
228
- target: map.get("target").and_then(|v| match v {
229
- Value::String(s) => Some(s.clone()),
230
- _ => None,
231
- }),
232
- },
233
- value: Value::String(
234
- map.get("pattern")
235
- .and_then(|v| match v {
236
- Value::String(s) => Some(s.clone()),
237
- _ => None,
238
- })
239
- .unwrap_or_default(),
240
- ),
241
- indent: 0,
242
- line: 0,
243
- column: 0,
244
- };
245
- return Some(stmt);
246
- }
247
- }
248
- _ => {}
249
- }
250
- }
251
-
252
- None
253
- }
@@ -1,40 +0,0 @@
1
- use crate::core::parser::statement::{Statement, StatementKind};
2
- use devalang_types::Value;
3
- use devalang_utils::logger::{LogLevel, Logger};
4
-
5
- pub fn interprete_tempo_statement(stmt: &Statement) -> Option<(f32, f32)> {
6
- if let StatementKind::Tempo = &stmt.kind {
7
- match &stmt.value {
8
- Value::Number(bpm) => {
9
- let bpm = { *bpm };
10
- let duration = 60.0 / bpm;
11
-
12
- return Some((bpm, duration));
13
- }
14
-
15
- Value::String(bpm_str) => {
16
- if let Ok(bpm) = bpm_str.parse::<f32>() {
17
- let duration = 60.0 / bpm;
18
- return Some((bpm, duration));
19
- }
20
- }
21
-
22
- Value::Identifier(bpm_ident) => {
23
- if let Ok(bpm) = bpm_ident.parse::<f32>() {
24
- let duration = 60.0 / bpm;
25
- return Some((bpm, duration));
26
- }
27
- }
28
-
29
- _ => {
30
- let logger = Logger::new();
31
- logger.log_message(
32
- LogLevel::Warning,
33
- format!("Invalid tempo value: {:?}", stmt.value).as_str(),
34
- );
35
- }
36
- }
37
- }
38
-
39
- None
40
- }
@@ -1,239 +0,0 @@
1
- use std::collections::HashMap;
2
-
3
- use crate::core::{
4
- audio::{engine::AudioEngine, loader::trigger::load_trigger},
5
- parser::statement::{Statement, StatementKind},
6
- };
7
- use devalang_types::store::VariableTable;
8
- use devalang_types::{Duration, Value};
9
- use devalang_utils::logger::Logger;
10
-
11
- pub fn interprete_trigger_statement(
12
- stmt: &Statement,
13
- audio_engine: &mut AudioEngine,
14
- variable_table: &VariableTable,
15
- base_duration: f32,
16
- cursor_time: f32,
17
- max_end_time: f32,
18
- ) -> Option<(f32, f32, AudioEngine)> {
19
- if let StatementKind::Trigger {
20
- entity,
21
- duration,
22
- effects,
23
- } = &stmt.kind
24
- {
25
- let mut trigger_val = Value::String(entity.clone());
26
- let mut trigger_src = String::new();
27
-
28
- match variable_table.variables.get(entity) {
29
- Some(Value::Identifier(id)) => {
30
- // Get real value from global variable table
31
- if let Some(global_table) = &variable_table.parent {
32
- if let Some(val) = global_table.get(id) {
33
- trigger_val = val.clone();
34
- } else {
35
- eprintln!(
36
- "❌ Trigger entity '{}' not found in global variable table",
37
- id
38
- );
39
- return None;
40
- }
41
- } else if let Some(val) = variable_table.get(id) {
42
- trigger_val = val.clone();
43
- } else {
44
- eprintln!("❌ Trigger entity '{}' not found in variable table", id);
45
- return None;
46
- }
47
- }
48
- Some(Value::Sample(sample_src)) => {
49
- // If the entity is a sample, we use its path directly
50
- trigger_src = sample_src.clone();
51
- }
52
- Some(Value::Map(map)) => {
53
- // If the entity is a map, we assume it contains an "entity" key
54
- if let Some(Value::String(src)) = map.get("entity") {
55
- trigger_val = Value::String(src.clone());
56
- } else if let Some(Value::Identifier(src)) = map.get("entity") {
57
- trigger_val = Value::Identifier(src.clone());
58
- } else {
59
- eprintln!(
60
- "❌ Trigger map must contain an 'entity' key with a string or identifier value."
61
- );
62
- return None;
63
- }
64
- }
65
- _ => {
66
- trigger_val = Value::String(entity.clone());
67
- }
68
- }
69
-
70
- // If trigger could not be resolved to a known mapping or explicit path, abort early
71
- if let Value::String(s) = &trigger_val {
72
- let is_protocol = s.starts_with("devalang://");
73
- let is_var = variable_table.get(s).is_some()
74
- || variable_table
75
- .parent
76
- .as_ref()
77
- .and_then(|p| p.get(s))
78
- .is_some();
79
- let looks_like_path = s.contains('/')
80
- || s.ends_with(".wav")
81
- || s.ends_with(".mp3")
82
- || s.ends_with(".ogg");
83
- if !is_protocol && !is_var && !looks_like_path {
84
- let logger = Logger::new();
85
- logger.log_error_with_stacktrace(
86
- &format!("unknown trigger: {}", s),
87
- &format!("{}:{}:{}", audio_engine.module_name, stmt.line, stmt.column),
88
- );
89
- return None;
90
- }
91
- }
92
-
93
- let duration_secs = match duration {
94
- Duration::Number(n) => *n,
95
-
96
- Duration::Identifier(id) => {
97
- if id == "auto" {
98
- 1.0
99
- } else {
100
- match variable_table.get(id) {
101
- Some(Value::Number(n)) => *n,
102
- Some(Value::Identifier(other)) if other == "auto" => 1.0,
103
- Some(other) => {
104
- eprintln!(
105
- "❌ Invalid duration reference '{}': expected number, got {:?}",
106
- id, other
107
- );
108
- return None;
109
- }
110
- None => {
111
- eprintln!("❌ Duration identifier '{}' not found", id);
112
- return None;
113
- }
114
- }
115
- }
116
- }
117
-
118
- Duration::Beat(beat_str) => {
119
- let parts: Vec<&str> = beat_str.split('/').collect();
120
- if parts.len() != 2 {
121
- eprintln!("❌ Invalid beat duration format: {}", beat_str);
122
- return None;
123
- }
124
-
125
- let numerator: f32 = parts[0].parse().unwrap_or(1.0);
126
- let denominator: f32 = parts[1].parse().unwrap_or(4.0);
127
-
128
- let beats = (numerator / denominator) * 4.0;
129
-
130
- beats * base_duration
131
- }
132
-
133
- Duration::Auto => base_duration,
134
- };
135
-
136
- let final_variable_table = if let Some(parent) = &variable_table.parent {
137
- VariableTable {
138
- variables: parent.variables.clone(),
139
- parent: None,
140
- }
141
- } else {
142
- variable_table.clone()
143
- };
144
-
145
- let (src, sample_length) = load_trigger(
146
- &trigger_val,
147
- duration,
148
- effects,
149
- base_duration,
150
- final_variable_table.clone(),
151
- );
152
-
153
- if trigger_src.is_empty() {
154
- trigger_src = src;
155
- }
156
-
157
- let effects = extract_effects(stmt.value.clone());
158
- let one_shot = effects
159
- .as_ref()
160
- .and_then(|map| map.get("one_shot"))
161
- .and_then(|v| match v {
162
- Value::Identifier(id) if id == "true" => Some(true),
163
- Value::String(s) if s == "true" => Some(true),
164
- _ => None,
165
- })
166
- .unwrap_or(false);
167
-
168
- let play_length = if one_shot {
169
- sample_length // play entire sample
170
- } else {
171
- duration_secs.min(sample_length)
172
- };
173
-
174
- let trigger_src = match trigger_val.get("entity") {
175
- Some(Value::String(src)) => src.clone(),
176
- Some(Value::Identifier(id)) => id.clone(),
177
- Some(Value::Statement(stmt)) => {
178
- if let StatementKind::Trigger { entity, .. } = &stmt.kind {
179
- entity.clone()
180
- } else {
181
- eprintln!("❌ Invalid trigger statement in map: expected 'Trigger' kind");
182
- return None;
183
- }
184
- }
185
- _ => trigger_src,
186
- };
187
-
188
- if let Some(effects_map) = effects {
189
- audio_engine.insert_sample(
190
- &trigger_src,
191
- cursor_time,
192
- play_length,
193
- Some(effects_map),
194
- &final_variable_table,
195
- );
196
- } else {
197
- audio_engine.insert_sample(
198
- &trigger_src,
199
- cursor_time,
200
- play_length,
201
- None,
202
- &final_variable_table,
203
- );
204
- }
205
-
206
- let new_cursor_time = cursor_time + duration_secs; // advance by beat duration
207
- let new_max_end_time = (cursor_time + play_length).max(max_end_time);
208
-
209
- let updated_engine = audio_engine.clone();
210
-
211
- return Some((new_cursor_time, new_max_end_time, updated_engine));
212
- }
213
-
214
- None
215
- }
216
-
217
- fn extract_effects(value: Value) -> Option<HashMap<String, Value>> {
218
- if let Value::Map(map) = value {
219
- let mut effects = HashMap::new();
220
-
221
- for (key, val) in map {
222
- if key == "effects" {
223
- if let Value::Map(effect_map) = val {
224
- for (effect_key, effect_val) in effect_map {
225
- effects.insert(effect_key, effect_val);
226
- }
227
- } else {
228
- return None; // effects must be a map
229
- }
230
- } else {
231
- return Some(effects);
232
- }
233
- }
234
-
235
- Some(effects)
236
- } else {
237
- None
238
- }
239
- }
@@ -1 +0,0 @@
1
- pub mod trigger;