@devaloop/devalang 0.0.1-beta.3 → 0.1.2

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 (346) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +251 -221
  3. package/out-tsc/api.d.ts +180 -0
  4. package/out-tsc/api.d.ts.map +1 -0
  5. package/out-tsc/api.js +286 -0
  6. package/out-tsc/api.js.map +1 -0
  7. package/out-tsc/bin/index.d.ts +12 -0
  8. package/out-tsc/bin/index.d.ts.map +1 -0
  9. package/out-tsc/bin/index.js +20 -54
  10. package/out-tsc/bin/index.js.map +1 -0
  11. package/out-tsc/examples/basic-usage.d.ts +8 -0
  12. package/out-tsc/examples/basic-usage.d.ts.map +1 -0
  13. package/out-tsc/examples/basic-usage.js +113 -0
  14. package/out-tsc/examples/basic-usage.js.map +1 -0
  15. package/out-tsc/index.d.ts +19 -5
  16. package/out-tsc/index.d.ts.map +1 -0
  17. package/out-tsc/index.js +24 -6
  18. package/out-tsc/index.js.map +1 -0
  19. package/out-tsc/scripts/copy-wasm-dts.d.ts +7 -0
  20. package/out-tsc/scripts/copy-wasm-dts.d.ts.map +1 -0
  21. package/out-tsc/scripts/copy-wasm-dts.js +36 -32
  22. package/out-tsc/scripts/copy-wasm-dts.js.map +1 -0
  23. package/out-tsc/scripts/postinstall.d.ts +1 -0
  24. package/out-tsc/scripts/postinstall.d.ts.map +1 -0
  25. package/out-tsc/scripts/postinstall.js +4 -1
  26. package/out-tsc/scripts/postinstall.js.map +1 -0
  27. package/out-tsc/scripts/version/bump.d.ts +5 -1
  28. package/out-tsc/scripts/version/bump.d.ts.map +1 -0
  29. package/out-tsc/scripts/version/bump.js +122 -44
  30. package/out-tsc/scripts/version/bump.js.map +1 -0
  31. package/out-tsc/scripts/version/fetch.d.ts +12 -1
  32. package/out-tsc/scripts/version/fetch.d.ts.map +1 -0
  33. package/out-tsc/scripts/version/fetch.js +68 -24
  34. package/out-tsc/scripts/version/fetch.js.map +1 -0
  35. package/out-tsc/scripts/version/index.d.ts +6 -0
  36. package/out-tsc/scripts/version/index.d.ts.map +1 -0
  37. package/out-tsc/scripts/version/index.js +44 -22
  38. package/out-tsc/scripts/version/index.js.map +1 -0
  39. package/out-tsc/scripts/version/sync.d.ts +5 -1
  40. package/out-tsc/scripts/version/sync.d.ts.map +1 -0
  41. package/out-tsc/scripts/version/sync.js +95 -29
  42. package/out-tsc/scripts/version/sync.js.map +1 -0
  43. package/out-tsc/types.d.ts +68 -0
  44. package/out-tsc/types.d.ts.map +1 -0
  45. package/out-tsc/{core/types/value.js → types.js} +4 -0
  46. package/out-tsc/types.js.map +1 -0
  47. package/out-tsc/wasm.d.ts +8 -0
  48. package/out-tsc/wasm.d.ts.map +1 -0
  49. package/out-tsc/{core/index.js → wasm.js} +9 -6
  50. package/out-tsc/wasm.js.map +1 -0
  51. package/package.json +42 -42
  52. package/.cargo/config.toml +0 -2
  53. package/.devalang +0 -9
  54. package/.github/workflows/ci.yml +0 -103
  55. package/Cargo.toml +0 -84
  56. package/docs/CHANGELOG.md +0 -622
  57. package/docs/CONTRIBUTING.md +0 -101
  58. package/docs/ROADMAP.md +0 -38
  59. package/docs/TODO.md +0 -71
  60. package/examples/automation.deva +0 -42
  61. package/examples/bank.deva +0 -7
  62. package/examples/bus.deva +0 -10
  63. package/examples/chain.deva +0 -19
  64. package/examples/condition.deva +0 -20
  65. package/examples/duration.deva +0 -9
  66. package/examples/effect.deva +0 -2
  67. package/examples/events.deva +0 -12
  68. package/examples/filter.deva +0 -11
  69. package/examples/function.deva +0 -15
  70. package/examples/group.deva +0 -12
  71. package/examples/index.deva +0 -63
  72. package/examples/lfo.deva +0 -9
  73. package/examples/loop.deva +0 -10
  74. package/examples/pattern.deva +0 -8
  75. package/examples/plugin.deva +0 -16
  76. package/examples/routing.deva +0 -23
  77. package/examples/samples/hat-808.wav +0 -0
  78. package/examples/samples/kick-808.wav +0 -0
  79. package/examples/synth.deva +0 -24
  80. package/examples/synth_types.deva +0 -17
  81. package/examples/variables.deva +0 -9
  82. package/out-tsc/bin/project-version.json +0 -6
  83. package/out-tsc/core/functions/index.d.ts +0 -42
  84. package/out-tsc/core/functions/index.js +0 -87
  85. package/out-tsc/core/index.d.ts +0 -6
  86. package/out-tsc/core/types/index.d.ts +0 -4
  87. package/out-tsc/core/types/index.js +0 -20
  88. package/out-tsc/core/types/plugin.d.ts +0 -18
  89. package/out-tsc/core/types/plugin.js +0 -2
  90. package/out-tsc/core/types/result.d.ts +0 -27
  91. package/out-tsc/core/types/result.js +0 -2
  92. package/out-tsc/core/types/statement.d.ts +0 -106
  93. package/out-tsc/core/types/statement.js +0 -2
  94. package/out-tsc/core/types/value.d.ts +0 -43
  95. package/out-tsc/pkg/devalang_core.d.ts +0 -15
  96. package/out-tsc/pkg/devalang_core.js +0 -65
  97. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +0 -34
  98. package/out-tsc/scripts/version/copy-to-binary.d.ts +0 -1
  99. package/out-tsc/scripts/version/copy-to-binary.js +0 -79
  100. package/project-version.json +0 -6
  101. package/rust/bindings/Cargo.toml +0 -9
  102. package/rust/bindings/src/lib.rs +0 -86
  103. package/rust/cli/addon/commands.rs +0 -35
  104. package/rust/cli/addon/download.rs +0 -234
  105. package/rust/cli/addon/install.rs +0 -33
  106. package/rust/cli/addon/list.rs +0 -224
  107. package/rust/cli/addon/metadata.rs +0 -124
  108. package/rust/cli/addon/mod.rs +0 -8
  109. package/rust/cli/addon/remove.rs +0 -271
  110. package/rust/cli/addon/update.rs +0 -305
  111. package/rust/cli/addon/utils.rs +0 -109
  112. package/rust/cli/build/commands.rs +0 -153
  113. package/rust/cli/build/mod.rs +0 -2
  114. package/rust/cli/build/process.rs +0 -165
  115. package/rust/cli/check/mod.rs +0 -208
  116. package/rust/cli/discover/commands.rs +0 -275
  117. package/rust/cli/discover/config.rs +0 -109
  118. package/rust/cli/discover/fs.rs +0 -19
  119. package/rust/cli/discover/install.rs +0 -214
  120. package/rust/cli/discover/metadata.rs +0 -48
  121. package/rust/cli/discover/mod.rs +0 -5
  122. package/rust/cli/init/commands.rs +0 -88
  123. package/rust/cli/init/mod.rs +0 -1
  124. package/rust/cli/login/commands.rs +0 -124
  125. package/rust/cli/login/mod.rs +0 -1
  126. package/rust/cli/me/commands.rs +0 -52
  127. package/rust/cli/me/mod.rs +0 -1
  128. package/rust/cli/mod.rs +0 -12
  129. package/rust/cli/parser.rs +0 -320
  130. package/rust/cli/play/commands.rs +0 -375
  131. package/rust/cli/play/io.rs +0 -17
  132. package/rust/cli/play/mod.rs +0 -5
  133. package/rust/cli/play/process.rs +0 -159
  134. package/rust/cli/play/realtime.rs +0 -91
  135. package/rust/cli/play/utils.rs +0 -23
  136. package/rust/cli/telemetry/commands.rs +0 -22
  137. package/rust/cli/telemetry/event_creator.rs +0 -80
  138. package/rust/cli/telemetry/mod.rs +0 -3
  139. package/rust/cli/telemetry/send.rs +0 -51
  140. package/rust/cli/template/commands.rs +0 -69
  141. package/rust/cli/template/mod.rs +0 -1
  142. package/rust/cli/update/commands.rs +0 -6
  143. package/rust/cli/update/mod.rs +0 -1
  144. package/rust/config/driver.rs +0 -112
  145. package/rust/config/mod.rs +0 -3
  146. package/rust/config/ops.rs +0 -26
  147. package/rust/config/settings.rs +0 -101
  148. package/rust/core/audio/engine/driver.rs +0 -237
  149. package/rust/core/audio/engine/export.rs +0 -169
  150. package/rust/core/audio/engine/helpers.rs +0 -178
  151. package/rust/core/audio/engine/mod.rs +0 -56
  152. package/rust/core/audio/engine/notes/dsp.rs +0 -88
  153. package/rust/core/audio/engine/notes/mod.rs +0 -53
  154. package/rust/core/audio/engine/notes/params.rs +0 -294
  155. package/rust/core/audio/engine/sample/insert.rs +0 -300
  156. package/rust/core/audio/engine/sample/mod.rs +0 -40
  157. package/rust/core/audio/engine/sample/padding.rs +0 -170
  158. package/rust/core/audio/evaluator/condition.rs +0 -61
  159. package/rust/core/audio/evaluator/mod.rs +0 -9
  160. package/rust/core/audio/evaluator/numeric.rs +0 -152
  161. package/rust/core/audio/evaluator/rhs.rs +0 -16
  162. package/rust/core/audio/evaluator/string_expr.rs +0 -94
  163. package/rust/core/audio/interpreter/driver.rs +0 -574
  164. package/rust/core/audio/interpreter/mod.rs +0 -2
  165. package/rust/core/audio/interpreter/statements/arrow_call/interprete.rs +0 -179
  166. package/rust/core/audio/interpreter/statements/arrow_call/methods/chord.rs +0 -398
  167. package/rust/core/audio/interpreter/statements/arrow_call/methods/effects.rs +0 -323
  168. package/rust/core/audio/interpreter/statements/arrow_call/methods/mod.rs +0 -3
  169. package/rust/core/audio/interpreter/statements/arrow_call/methods/note.rs +0 -371
  170. package/rust/core/audio/interpreter/statements/arrow_call/mod.rs +0 -3
  171. package/rust/core/audio/interpreter/statements/arrow_call/types/arp.rs +0 -192
  172. package/rust/core/audio/interpreter/statements/arrow_call/types/mod.rs +0 -24
  173. package/rust/core/audio/interpreter/statements/arrow_call/types/pad.rs +0 -116
  174. package/rust/core/audio/interpreter/statements/arrow_call/types/pluck.rs +0 -97
  175. package/rust/core/audio/interpreter/statements/arrow_call/types/sub.rs +0 -100
  176. package/rust/core/audio/interpreter/statements/automate.rs +0 -16
  177. package/rust/core/audio/interpreter/statements/call.rs +0 -325
  178. package/rust/core/audio/interpreter/statements/condition.rs +0 -72
  179. package/rust/core/audio/interpreter/statements/function.rs +0 -24
  180. package/rust/core/audio/interpreter/statements/let_.rs +0 -36
  181. package/rust/core/audio/interpreter/statements/load.rs +0 -17
  182. package/rust/core/audio/interpreter/statements/loop_.rs +0 -115
  183. package/rust/core/audio/interpreter/statements/mod.rs +0 -12
  184. package/rust/core/audio/interpreter/statements/sleep.rs +0 -28
  185. package/rust/core/audio/interpreter/statements/spawn.rs +0 -302
  186. package/rust/core/audio/interpreter/statements/tempo.rs +0 -40
  187. package/rust/core/audio/interpreter/statements/trigger.rs +0 -242
  188. package/rust/core/audio/loader/mod.rs +0 -1
  189. package/rust/core/audio/loader/trigger.rs +0 -98
  190. package/rust/core/audio/mod.rs +0 -6
  191. package/rust/core/audio/player.rs +0 -70
  192. package/rust/core/audio/special/easing.rs +0 -189
  193. package/rust/core/audio/special/env.rs +0 -45
  194. package/rust/core/audio/special/math.rs +0 -134
  195. package/rust/core/audio/special/mod.rs +0 -9
  196. package/rust/core/audio/special/modulator.rs +0 -143
  197. package/rust/core/builder/mod.rs +0 -129
  198. package/rust/core/debugger/lexer.rs +0 -27
  199. package/rust/core/debugger/logs.rs +0 -52
  200. package/rust/core/debugger/mod.rs +0 -30
  201. package/rust/core/debugger/preprocessor.rs +0 -27
  202. package/rust/core/debugger/store.rs +0 -38
  203. package/rust/core/error/mod.rs +0 -269
  204. package/rust/core/lexer/driver.rs +0 -59
  205. package/rust/core/lexer/handler/arrow.rs +0 -82
  206. package/rust/core/lexer/handler/at.rs +0 -21
  207. package/rust/core/lexer/handler/brace.rs +0 -41
  208. package/rust/core/lexer/handler/colon.rs +0 -21
  209. package/rust/core/lexer/handler/comment.rs +0 -30
  210. package/rust/core/lexer/handler/dot.rs +0 -21
  211. package/rust/core/lexer/handler/driver.rs +0 -337
  212. package/rust/core/lexer/handler/identifier.rs +0 -47
  213. package/rust/core/lexer/handler/indent.rs +0 -66
  214. package/rust/core/lexer/handler/mod.rs +0 -15
  215. package/rust/core/lexer/handler/newline.rs +0 -23
  216. package/rust/core/lexer/handler/number.rs +0 -31
  217. package/rust/core/lexer/handler/operator.rs +0 -46
  218. package/rust/core/lexer/handler/parenthesis.rs +0 -41
  219. package/rust/core/lexer/handler/slash.rs +0 -21
  220. package/rust/core/lexer/handler/string.rs +0 -63
  221. package/rust/core/lexer/mod.rs +0 -3
  222. package/rust/core/lexer/token.rs +0 -91
  223. package/rust/core/mod.rs +0 -9
  224. package/rust/core/parser/driver/block.rs +0 -111
  225. package/rust/core/parser/driver/cursor.rs +0 -82
  226. package/rust/core/parser/driver/driver_impl.rs +0 -159
  227. package/rust/core/parser/driver/mod.rs +0 -6
  228. package/rust/core/parser/driver/parse_array.rs +0 -120
  229. package/rust/core/parser/driver/parse_map.rs +0 -247
  230. package/rust/core/parser/driver/parser.rs +0 -160
  231. package/rust/core/parser/handler/arrow_call.rs +0 -328
  232. package/rust/core/parser/handler/at.rs +0 -279
  233. package/rust/core/parser/handler/bank.rs +0 -104
  234. package/rust/core/parser/handler/condition.rs +0 -83
  235. package/rust/core/parser/handler/dot.rs +0 -148
  236. package/rust/core/parser/handler/identifier/automate.rs +0 -254
  237. package/rust/core/parser/handler/identifier/call.rs +0 -91
  238. package/rust/core/parser/handler/identifier/emit.rs +0 -70
  239. package/rust/core/parser/handler/identifier/function.rs +0 -113
  240. package/rust/core/parser/handler/identifier/group.rs +0 -89
  241. package/rust/core/parser/handler/identifier/let_.rs +0 -173
  242. package/rust/core/parser/handler/identifier/mod.rs +0 -55
  243. package/rust/core/parser/handler/identifier/on.rs +0 -107
  244. package/rust/core/parser/handler/identifier/print.rs +0 -49
  245. package/rust/core/parser/handler/identifier/sleep.rs +0 -96
  246. package/rust/core/parser/handler/identifier/spawn.rs +0 -91
  247. package/rust/core/parser/handler/identifier/synth.rs +0 -171
  248. package/rust/core/parser/handler/loop_.rs +0 -194
  249. package/rust/core/parser/handler/mod.rs +0 -9
  250. package/rust/core/parser/handler/pattern.rs +0 -97
  251. package/rust/core/parser/handler/tempo.rs +0 -105
  252. package/rust/core/parser/mod.rs +0 -3
  253. package/rust/core/parser/statement.rs +0 -10
  254. package/rust/core/plugin/loader.rs +0 -137
  255. package/rust/core/plugin/mod.rs +0 -2
  256. package/rust/core/plugin/runner/mod.rs +0 -11
  257. package/rust/core/plugin/runner/non_wasm.rs +0 -481
  258. package/rust/core/plugin/runner/wasm32.rs +0 -44
  259. package/rust/core/preprocessor/loader/inject.rs +0 -313
  260. package/rust/core/preprocessor/loader/loader_helpers.rs +0 -110
  261. package/rust/core/preprocessor/loader/mod.rs +0 -235
  262. package/rust/core/preprocessor/mod.rs +0 -4
  263. package/rust/core/preprocessor/module.rs +0 -55
  264. package/rust/core/preprocessor/processor/handlers.rs +0 -107
  265. package/rust/core/preprocessor/processor/mod.rs +0 -1
  266. package/rust/core/preprocessor/resolver/bank.rs +0 -49
  267. package/rust/core/preprocessor/resolver/call.rs +0 -124
  268. package/rust/core/preprocessor/resolver/condition.rs +0 -95
  269. package/rust/core/preprocessor/resolver/driver.rs +0 -324
  270. package/rust/core/preprocessor/resolver/function.rs +0 -69
  271. package/rust/core/preprocessor/resolver/group.rs +0 -122
  272. package/rust/core/preprocessor/resolver/let_.rs +0 -32
  273. package/rust/core/preprocessor/resolver/loop_.rs +0 -318
  274. package/rust/core/preprocessor/resolver/mod.rs +0 -16
  275. package/rust/core/preprocessor/resolver/pattern.rs +0 -95
  276. package/rust/core/preprocessor/resolver/spawn.rs +0 -99
  277. package/rust/core/preprocessor/resolver/synth.rs +0 -54
  278. package/rust/core/preprocessor/resolver/tempo.rs +0 -48
  279. package/rust/core/preprocessor/resolver/trigger.rs +0 -116
  280. package/rust/core/preprocessor/resolver/value.rs +0 -176
  281. package/rust/core/store/global.rs +0 -57
  282. package/rust/core/store/mod.rs +0 -1
  283. package/rust/lib.rs +0 -323
  284. package/rust/macros/Cargo.toml +0 -14
  285. package/rust/macros/src/lib.rs +0 -52
  286. package/rust/main.rs +0 -557
  287. package/rust/types/Cargo.toml +0 -11
  288. package/rust/types/src/addons.rs +0 -57
  289. package/rust/types/src/ast.rs +0 -202
  290. package/rust/types/src/config.rs +0 -82
  291. package/rust/types/src/lib.rs +0 -15
  292. package/rust/types/src/plugin.rs +0 -20
  293. package/rust/types/src/store.rs +0 -139
  294. package/rust/types/src/telemetry.rs +0 -85
  295. package/rust/utils/Cargo.toml +0 -29
  296. package/rust/utils/src/error.rs +0 -186
  297. package/rust/utils/src/file.rs +0 -477
  298. package/rust/utils/src/first_usage.rs +0 -97
  299. package/rust/utils/src/lib.rs +0 -9
  300. package/rust/utils/src/logger.rs +0 -200
  301. package/rust/utils/src/path.rs +0 -158
  302. package/rust/utils/src/signature.rs +0 -41
  303. package/rust/utils/src/spinner.rs +0 -20
  304. package/rust/utils/src/version.rs +0 -58
  305. package/rust/utils/src/watcher.rs +0 -46
  306. package/rust/web/api.rs +0 -5
  307. package/rust/web/auth.rs +0 -5
  308. package/rust/web/cdn.rs +0 -34
  309. package/rust/web/forge.rs +0 -5
  310. package/rust/web/mod.rs +0 -5
  311. package/rust/web/sso.rs +0 -5
  312. package/templates/minimal/.devalang +0 -5
  313. package/templates/minimal/README.md +0 -218
  314. package/templates/minimal/src/index.deva +0 -2
  315. package/templates/welcome/.devalang +0 -5
  316. package/templates/welcome/README.md +0 -218
  317. package/templates/welcome/samples/kick-808.wav +0 -0
  318. package/templates/welcome/src/index.deva +0 -61
  319. package/templates/welcome/src/variables.deva +0 -3
  320. package/tests/integration.rs +0 -21
  321. package/tests/rust/cli_check_build.rs +0 -21
  322. package/tests/rust/cli_help.rs +0 -12
  323. package/tests/rust/cli_template_list.rs +0 -10
  324. package/tests/rust/cli_version.rs +0 -11
  325. package/tests/typescript/index.spec.ts +0 -136
  326. package/tests/typescript/playhead.spec.ts +0 -36
  327. package/tests/typescript/render_e2e.spec.ts +0 -77
  328. package/tsconfig.json +0 -115
  329. package/typescript/bin/index.ts +0 -28
  330. package/typescript/core/functions/index.ts +0 -94
  331. package/typescript/core/index.ts +0 -6
  332. package/typescript/core/types/index.ts +0 -4
  333. package/typescript/core/types/plugin.ts +0 -19
  334. package/typescript/core/types/result.ts +0 -29
  335. package/typescript/core/types/statement.ts +0 -47
  336. package/typescript/core/types/value.ts +0 -29
  337. package/typescript/index.ts +0 -8
  338. package/typescript/pkg/devalang_core.d.ts +0 -4
  339. package/typescript/pkg/devalang_core.ts +0 -65
  340. package/typescript/scripts/copy-wasm-dts.ts +0 -41
  341. package/typescript/scripts/postinstall.ts +0 -85
  342. package/typescript/scripts/version/bump.ts +0 -44
  343. package/typescript/scripts/version/copy-to-binary.ts +0 -82
  344. package/typescript/scripts/version/fetch.ts +0 -18
  345. package/typescript/scripts/version/index.ts +0 -25
  346. 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;