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