@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,574 +0,0 @@
1
- use devalang_types::Value;
2
- use devalang_utils::logger::{LogLevel, Logger};
3
- use rayon::prelude::*;
4
-
5
- use crate::core::{
6
- audio::{
7
- engine::AudioEngine,
8
- interpreter::statements::{
9
- arrow_call::interprete::interprete_arrow_call_statement,
10
- call::interprete_call_statement, function::interprete_function_statement,
11
- let_::interprete_let_statement, load::interprete_load_statement,
12
- loop_::interprete_loop_statement, sleep::interprete_sleep_statement,
13
- spawn::interprete_spawn_statement, tempo::interprete_tempo_statement,
14
- trigger::interprete_trigger_statement,
15
- },
16
- },
17
- parser::statement::{Statement, StatementKind},
18
- store::global::GlobalStore,
19
- };
20
- use devalang_types::{FunctionTable, VariableTable};
21
-
22
- // WASM playhead callback support (only compiled for wasm32 target)
23
- #[cfg(target_arch = "wasm32")]
24
- use serde::Serialize;
25
-
26
- #[cfg(target_arch = "wasm32")]
27
- #[derive(Serialize, Clone)]
28
- pub struct PlayheadEvent {
29
- time: f32,
30
- line: usize,
31
- column: usize,
32
- }
33
-
34
- #[cfg(target_arch = "wasm32")]
35
- use wasm_bindgen::prelude::JsValue;
36
-
37
- #[cfg(target_arch = "wasm32")]
38
- use std::cell::RefCell;
39
-
40
- #[cfg(target_arch = "wasm32")]
41
- thread_local! {
42
- static PLAYHEAD_CB: RefCell<Option<js_sys::Function>> = RefCell::new(None);
43
- static PLAYHEAD_EVENTS: RefCell<Vec<PlayheadEvent>> = RefCell::new(Vec::new());
44
- }
45
-
46
- #[cfg(target_arch = "wasm32")]
47
- pub fn register_playhead_callback(cb: js_sys::Function) {
48
- PLAYHEAD_CB.with(|c| {
49
- *c.borrow_mut() = Some(cb);
50
- });
51
- }
52
-
53
- #[cfg(target_arch = "wasm32")]
54
- pub fn unregister_playhead_callback() {
55
- PLAYHEAD_CB.with(|c| {
56
- *c.borrow_mut() = None;
57
- });
58
- }
59
-
60
- #[cfg(target_arch = "wasm32")]
61
- pub fn collect_playhead_events() -> Vec<PlayheadEvent> {
62
- PLAYHEAD_EVENTS.with(|c| c.borrow().clone())
63
- }
64
-
65
- #[cfg(target_arch = "wasm32")]
66
- fn emit_playhead(time: f32, line: usize, column: usize) {
67
- let ev = PlayheadEvent { time, line, column };
68
- PLAYHEAD_EVENTS.with(|c| c.borrow_mut().push(ev.clone()));
69
-
70
- if let Ok(v) = serde_wasm_bindgen::to_value(&ev) {
71
- PLAYHEAD_CB.with(|c| {
72
- if let Some(f) = c.borrow().as_ref() {
73
- let _ = f.call1(&JsValue::NULL, &v);
74
- }
75
- });
76
- }
77
- }
78
-
79
- pub fn run_audio_program(
80
- statements: &[Statement],
81
- audio_engine: &mut AudioEngine,
82
- _entry: String,
83
- _output: String,
84
- _module_variables: VariableTable,
85
- _module_functions: FunctionTable,
86
- global_store: &mut GlobalStore,
87
- ) -> (f32, f32) {
88
- // Clear any previously collected playhead events for wasm target so each
89
- // run starts with an empty events buffer.
90
- #[cfg(target_arch = "wasm32")]
91
- {
92
- PLAYHEAD_EVENTS.with(|c| c.borrow_mut().clear());
93
- }
94
-
95
- let base_bpm = 120.0;
96
- let base_duration = 60.0 / base_bpm;
97
-
98
- let (max_end_time, cursor_time) = execute_audio_block(
99
- audio_engine,
100
- global_store,
101
- global_store.variables.clone(),
102
- global_store.functions.clone(),
103
- statements,
104
- base_bpm,
105
- base_duration,
106
- 0.0,
107
- 0.0,
108
- );
109
-
110
- (max_end_time, cursor_time)
111
- }
112
-
113
- /// Execute a block of statements and schedule audio into the provided
114
- /// AudioEngine. This function is the core of offline rendering and
115
- /// performs the following responsibilities:
116
- /// - sequential evaluation of statements (load, let, trigger, loop, etc.)
117
- /// - parallel execution of `spawn` blocks (using rayon) and merging results
118
- /// - scheduling of periodic events (beat/bar) once at the root depth
119
- /// - emitting playhead events (when compiled for wasm32) after each sequential statement
120
- pub fn execute_audio_block(
121
- audio_engine: &mut AudioEngine,
122
- global_store: &GlobalStore,
123
- mut variable_table: VariableTable,
124
- mut functions_table: FunctionTable,
125
- statements: &[Statement],
126
- mut base_bpm: f32,
127
- mut base_duration: f32,
128
- mut max_end_time: f32,
129
- mut cursor_time: f32,
130
- ) -> (f32, f32) {
131
- // Track nested depth of execute_audio_block to avoid scheduling periodic events multiple times
132
- let current_depth = match variable_table.get("__depth") {
133
- Some(Value::Number(n)) => *n,
134
- _ => 0.0,
135
- };
136
- variable_table.set("__depth".to_string(), Value::Number(current_depth + 1.0));
137
- let (spawns, others): (Vec<_>, Vec<_>) = statements
138
- .iter()
139
- .partition(|stmt| matches!(stmt.kind, StatementKind::Spawn { .. }));
140
-
141
- // Execute sequential statements first
142
- for stmt in others {
143
- match &stmt.kind {
144
- StatementKind::Load { .. } => {
145
- if let Some(new_table) = interprete_load_statement(stmt, &mut variable_table) {
146
- variable_table = new_table;
147
- }
148
- }
149
- StatementKind::On { .. } => {
150
- // already registered in global store during parsing; nothing to do at runtime
151
- }
152
- StatementKind::Emit { event, payload: _ } => {
153
- if let Some(handlers) = global_store.get_event_handlers(event) {
154
- for h in handlers {
155
- if let StatementKind::On {
156
- event: _,
157
- args,
158
- body,
159
- } = &h.kind
160
- {
161
- // Create a derived variable table with event context
162
- let mut vt = variable_table.clone();
163
- let mut ctx = std::collections::HashMap::new();
164
- ctx.insert("name".to_string(), Value::String(event.clone()));
165
- if let Some(arg_list) = args.clone() {
166
- ctx.insert("args".to_string(), Value::Array(arg_list));
167
- }
168
- // Attach payload if any on the Emit statement value
169
- ctx.insert("payload".to_string(), stmt.value.clone());
170
- vt.set("event".to_string(), Value::Map(ctx));
171
- // Mark we're inside an event handler to avoid re-scheduling periodic events recursively
172
- vt.set("__in_event".to_string(), Value::Boolean(true));
173
-
174
- let (_max, _cursor) = execute_audio_block(
175
- audio_engine,
176
- global_store,
177
- vt,
178
- functions_table.clone(),
179
- body,
180
- base_bpm,
181
- base_duration,
182
- max_end_time,
183
- cursor_time,
184
- );
185
- }
186
- }
187
- }
188
- }
189
- StatementKind::Let { .. } => {
190
- if let Some(new_table) = interprete_let_statement(stmt, &mut variable_table) {
191
- variable_table = new_table;
192
- }
193
- }
194
- StatementKind::Function { .. } => {
195
- if let Some(new_functions) =
196
- interprete_function_statement(stmt, &mut functions_table)
197
- {
198
- functions_table = new_functions;
199
- }
200
- }
201
- StatementKind::Tempo => {
202
- if let Some((new_bpm, new_duration)) = interprete_tempo_statement(stmt) {
203
- base_bpm = new_bpm;
204
- base_duration = new_duration;
205
- }
206
- }
207
- StatementKind::Trigger { .. } => {
208
- if let Some((new_cursor, new_max, _)) = interprete_trigger_statement(
209
- stmt,
210
- audio_engine,
211
- &variable_table,
212
- base_duration,
213
- cursor_time,
214
- max_end_time,
215
- ) {
216
- cursor_time = new_cursor;
217
- max_end_time = new_max;
218
- }
219
- }
220
- StatementKind::Sleep => {
221
- let (new_cursor, new_max) =
222
- interprete_sleep_statement(stmt, cursor_time, max_end_time);
223
- cursor_time = new_cursor;
224
- max_end_time = new_max;
225
- }
226
- StatementKind::Loop => {
227
- let (new_max, new_cursor) = interprete_loop_statement(
228
- stmt,
229
- audio_engine,
230
- global_store,
231
- &variable_table,
232
- &functions_table,
233
- base_bpm,
234
- base_duration,
235
- max_end_time,
236
- cursor_time,
237
- );
238
- cursor_time = new_cursor;
239
- max_end_time = new_max;
240
- }
241
- StatementKind::Call { .. } => {
242
- let (new_max, _) = interprete_call_statement(
243
- stmt,
244
- audio_engine,
245
- &variable_table,
246
- &functions_table,
247
- global_store,
248
- base_bpm,
249
- base_duration,
250
- max_end_time,
251
- cursor_time,
252
- );
253
- cursor_time = new_max;
254
- max_end_time = new_max;
255
- }
256
- StatementKind::ArrowCall { .. } => {
257
- let (new_max, new_cursor) = interprete_arrow_call_statement(
258
- stmt,
259
- audio_engine,
260
- &variable_table,
261
- global_store,
262
- base_bpm,
263
- base_duration,
264
- &mut max_end_time,
265
- Some(&mut cursor_time),
266
- true,
267
- );
268
- cursor_time = new_cursor;
269
-
270
- if new_max > max_end_time {
271
- max_end_time = new_max;
272
- }
273
- }
274
- StatementKind::Automate { .. } => {
275
- if
276
- let Some(new_table) =
277
- crate::core::audio::interpreter::statements::automate::interprete_automate_statement(
278
- stmt,
279
- &mut variable_table
280
- )
281
- {
282
- variable_table = new_table;
283
- }
284
- }
285
- StatementKind::Print => {
286
- // Only print in real-time mode (during playback), not during offline render.
287
- let is_realtime = matches!(variable_table.get("__rt"), Some(Value::Boolean(true)));
288
- if is_realtime {
289
- let logger = Logger::new();
290
- match &stmt.value {
291
- Value::String(s) => {
292
- let bpm = if let Some(Value::Number(n)) = variable_table.get("bpm") {
293
- *n
294
- } else {
295
- 120.0
296
- };
297
- let beat = if let Some(Value::Number(n)) = variable_table.get("beat") {
298
- *n
299
- } else {
300
- 0.0
301
- };
302
- // First try JS-like string concatenation: "str " + var + 1 + $env.*
303
- if let Some(res) =
304
- crate::core::audio::evaluator::evaluate_string_expression(
305
- s,
306
- &variable_table,
307
- bpm,
308
- beat,
309
- )
310
- {
311
- logger.log_message(LogLevel::Print, &res);
312
- } else if let Some(val) = variable_table.get(s) {
313
- logger.log_message(LogLevel::Print, &format!("{:?}", val));
314
- } else if s.contains("$env")
315
- || s.contains("$math")
316
- || s.parse::<f32>().is_ok()
317
- {
318
- let v = crate::core::audio::evaluator::evaluate_rhs_into_value(
319
- s,
320
- &variable_table,
321
- bpm,
322
- beat,
323
- );
324
- match v {
325
- Value::Number(n) => {
326
- logger.log_message(LogLevel::Print, &format!("{}", n));
327
- }
328
- _ => logger.log_message(LogLevel::Print, s),
329
- }
330
- } else {
331
- logger.log_message(LogLevel::Print, s);
332
- }
333
- }
334
- Value::Number(n) => {
335
- logger.log_message(LogLevel::Print, &format!("{}", n));
336
- }
337
- Value::Identifier(name) => {
338
- if let Some(val) = variable_table.get(name) {
339
- match val {
340
- Value::Number(n) => {
341
- logger.log_message(LogLevel::Print, &format!("{}", n));
342
- }
343
- Value::String(s) => logger.log_message(LogLevel::Print, s),
344
- Value::Boolean(b) => {
345
- logger.log_message(LogLevel::Print, &format!("{}", b));
346
- }
347
- other => {
348
- logger
349
- .log_message(LogLevel::Print, &format!("{:?}", other));
350
- }
351
- }
352
- } else {
353
- logger.log_message(LogLevel::Print, name);
354
- }
355
- }
356
- v => logger.log_message(LogLevel::Print, &format!("{:?}", v)),
357
- }
358
- }
359
- }
360
- _ => {}
361
- }
362
-
363
- // Emit playhead event for UI bindings when building real-time playback
364
- // Only emit for statements that are "playable" (i.e., schedule audio)
365
- #[cfg(target_arch = "wasm32")]
366
- {
367
- if matches!(
368
- stmt.kind,
369
- StatementKind::Trigger { .. }
370
- | StatementKind::Call { .. }
371
- | StatementKind::Spawn { .. }
372
- | StatementKind::Loop
373
- ) {
374
- emit_playhead(cursor_time, stmt.line, stmt.column);
375
- }
376
- }
377
- }
378
-
379
- // Execute parallel spawns (collect results)
380
- let spawn_results: Vec<(AudioEngine, f32)> = spawns
381
- .par_iter()
382
- .map(|stmt| {
383
- let mut local_engine = AudioEngine::new(audio_engine.module_name.clone());
384
- let (spawn_max, _) = interprete_spawn_statement(
385
- stmt,
386
- &mut local_engine,
387
- &variable_table,
388
- &functions_table,
389
- global_store,
390
- base_bpm,
391
- base_duration,
392
- 0.0,
393
- 0.0,
394
- );
395
- (local_engine, spawn_max)
396
- })
397
- .collect();
398
-
399
- // Finally, merge results from all spawns
400
- for (local_engine, spawn_max) in spawn_results {
401
- audio_engine.merge_with(local_engine);
402
- if spawn_max > max_end_time {
403
- max_end_time = spawn_max;
404
- }
405
- }
406
-
407
- // Built-in periodic events (e.g., on beat(n), on bar(n))
408
- // Emit handlers across the timeline up to max_end_time.
409
- // If no audio was scheduled (max_end_time == 0.0), skip.
410
- // Don't schedule periodic events if we're already inside an event handler
411
- let in_event = matches!(variable_table.get("__in_event"), Some(Value::Boolean(true)));
412
- let depth_is_root = matches!(variable_table.get("__depth"), Some(Value::Number(n)) if (*n - 1.0).abs() < f32::EPSILON);
413
- if max_end_time > 0.0 && !in_event && depth_is_root && !global_store.events.is_empty() {
414
- // Beat-based handlers (support "beat" and "$beat")
415
- for ev_key in ["beat", "$beat"] {
416
- if let Some(handlers) = global_store.get_event_handlers(ev_key) {
417
- let mut seen: std::collections::HashSet<(usize, usize, usize)> =
418
- std::collections::HashSet::new();
419
- // Default every 1 beat if args missing
420
- for h in handlers {
421
- let key = (h.line, h.column, h.indent);
422
- if !seen.insert(key) {
423
- continue;
424
- }
425
- if let StatementKind::On { event, args, body } = &h.kind {
426
- let every: f32 = args
427
- .as_ref()
428
- .and_then(|v| v.first())
429
- .and_then(|x| {
430
- match x {
431
- Value::Number(n) => Some(*n),
432
- Value::Identifier(s) => {
433
- // Try to resolve from variables first, fallback to parsing the literal
434
- match variable_table.get(s) {
435
- Some(Value::Number(n)) => Some(*n),
436
- _ => s.parse::<f32>().ok(),
437
- }
438
- }
439
- _ => None,
440
- }
441
- })
442
- .unwrap_or(1.0)
443
- .max(0.0001);
444
- let step = base_duration * every;
445
- // Start from first full bar boundary after t=0
446
- let mut t = step;
447
- while t <= max_end_time {
448
- // Prepare event context
449
- let mut vt = variable_table.clone();
450
- let mut ctx = std::collections::HashMap::new();
451
- ctx.insert("name".to_string(), Value::String(event.clone()));
452
- if let Some(a) = args.clone() {
453
- ctx.insert("args".to_string(), Value::Array(a));
454
- }
455
- vt.set("event".to_string(), Value::Map(ctx));
456
- vt.set("beat".to_string(), Value::Number(t / base_duration));
457
- // Prevent nested scheduling
458
- vt.set("__in_event".to_string(), Value::Boolean(true));
459
-
460
- let (_m, _c) = execute_audio_block(
461
- audio_engine,
462
- global_store,
463
- vt,
464
- functions_table.clone(),
465
- body,
466
- base_bpm,
467
- base_duration,
468
- max_end_time,
469
- t,
470
- );
471
-
472
- t += step;
473
- }
474
- }
475
- }
476
- }
477
- }
478
-
479
- // Bar-based handlers (default 4/4 time => 4 beats per bar); support "bar" and "$bar"
480
- for ev_key in ["bar", "$bar"] {
481
- if let Some(handlers) = global_store.get_event_handlers(ev_key) {
482
- let mut seen: std::collections::HashSet<(usize, usize, usize)> =
483
- std::collections::HashSet::new();
484
- for h in handlers {
485
- let key = (h.line, h.column, h.indent);
486
- if !seen.insert(key) {
487
- continue;
488
- }
489
- if let StatementKind::On { event, args, body } = &h.kind {
490
- let bar_beats = 4.0f32; // TODO: time signature support
491
- let first_only = args.as_ref().and_then(|v| v.first()).is_none();
492
-
493
- let every_bar: f32 = if first_only {
494
- 1.0
495
- } else {
496
- args.as_ref()
497
- .and_then(|v| v.first())
498
- .and_then(|x| match x {
499
- Value::Number(n) => Some(*n),
500
- Value::Identifier(s) => match variable_table.get(s) {
501
- Some(Value::Number(n)) => Some(*n),
502
- _ => s.parse::<f32>().ok(),
503
- },
504
- _ => None,
505
- })
506
- .unwrap_or(1.0)
507
- .max(0.0001)
508
- };
509
-
510
- let step = base_duration * bar_beats * every_bar;
511
-
512
- if first_only {
513
- let t = step; // first full bar after t=0
514
- if t <= max_end_time {
515
- let mut vt = variable_table.clone();
516
- let mut ctx = std::collections::HashMap::new();
517
- ctx.insert("name".to_string(), Value::String(event.clone()));
518
- if let Some(a) = args.clone() {
519
- ctx.insert("args".to_string(), Value::Array(a));
520
- }
521
- vt.set("event".to_string(), Value::Map(ctx));
522
- vt.set("beat".to_string(), Value::Number(t / base_duration));
523
- // Prevent nested scheduling
524
- vt.set("__in_event".to_string(), Value::Boolean(true));
525
-
526
- let (_m, _c) = execute_audio_block(
527
- audio_engine,
528
- global_store,
529
- vt,
530
- functions_table.clone(),
531
- body,
532
- base_bpm,
533
- base_duration,
534
- max_end_time,
535
- t,
536
- );
537
- }
538
- } else {
539
- let mut t = step; // start from first full bar after t=0
540
- while t <= max_end_time {
541
- let mut vt = variable_table.clone();
542
- let mut ctx = std::collections::HashMap::new();
543
- ctx.insert("name".to_string(), Value::String(event.clone()));
544
- if let Some(a) = args.clone() {
545
- ctx.insert("args".to_string(), Value::Array(a));
546
- }
547
- vt.set("event".to_string(), Value::Map(ctx));
548
- vt.set("beat".to_string(), Value::Number(t / base_duration));
549
- // Prevent nested scheduling
550
- vt.set("__in_event".to_string(), Value::Boolean(true));
551
-
552
- let (_m, _c) = execute_audio_block(
553
- audio_engine,
554
- global_store,
555
- vt,
556
- functions_table.clone(),
557
- body,
558
- base_bpm,
559
- base_duration,
560
- max_end_time,
561
- t,
562
- );
563
-
564
- t += step;
565
- }
566
- }
567
- }
568
- }
569
- }
570
- }
571
- }
572
-
573
- (max_end_time.max(cursor_time), cursor_time)
574
- }
@@ -1,2 +0,0 @@
1
- pub mod driver;
2
- pub mod statements;