@devaloop/devalang 0.0.1-alpha.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.
- package/Cargo.toml +45 -0
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/docs/COMMANDS.md +31 -0
- package/docs/ROADMAP.md +27 -0
- package/docs/SYNTAX.md +148 -0
- package/docs/TODO.md +66 -0
- package/examples/exported.deva +7 -0
- package/examples/index.deva +9 -0
- package/examples/samples/kick-808.wav +0 -0
- package/out-tsc/bin/devalang.exe +0 -0
- package/out-tsc/bin/index.js +13 -0
- package/out-tsc/index.js +2 -0
- package/out-tsc/scripts/postbuild.js +11 -0
- package/out-tsc/scripts/version/bump.js +52 -0
- package/out-tsc/scripts/version/fetch.js +34 -0
- package/out-tsc/scripts/version/index.js +32 -0
- package/out-tsc/scripts/version/sync.js +32 -0
- package/package.json +43 -0
- package/project-version.json +6 -0
- package/rust/audio/mod.rs +1 -0
- package/rust/cli/build.rs +51 -0
- package/rust/cli/check.rs +124 -0
- package/rust/cli/mod.rs +3 -0
- package/rust/cli/new.rs +1 -0
- package/rust/core/builder/mod.rs +37 -0
- package/rust/core/debugger/mod.rs +57 -0
- package/rust/core/lexer/mod.rs +333 -0
- package/rust/core/mod.rs +6 -0
- package/rust/core/parser/at.rs +142 -0
- package/rust/core/parser/bank.rs +42 -0
- package/rust/core/parser/dot.rs +107 -0
- package/rust/core/parser/identifer.rs +91 -0
- package/rust/core/parser/loop_.rs +62 -0
- package/rust/core/parser/mod.rs +201 -0
- package/rust/core/parser/tempo.rs +42 -0
- package/rust/core/parser/variable.rs +129 -0
- package/rust/core/preprocessor/dependencies.rs +54 -0
- package/rust/core/preprocessor/mod.rs +26 -0
- package/rust/core/preprocessor/module.rs +70 -0
- package/rust/core/preprocessor/resolver/at.rs +24 -0
- package/rust/core/preprocessor/resolver/bank.rs +59 -0
- package/rust/core/preprocessor/resolver/loop_.rs +82 -0
- package/rust/core/preprocessor/resolver/mod.rs +113 -0
- package/rust/core/preprocessor/resolver/tempo.rs +70 -0
- package/rust/core/preprocessor/resolver/trigger.rs +176 -0
- package/rust/core/types/cli.rs +160 -0
- package/rust/core/types/mod.rs +7 -0
- package/rust/core/types/module.rs +41 -0
- package/rust/core/types/parser.rs +73 -0
- package/rust/core/types/statement.rs +105 -0
- package/rust/core/types/store.rs +116 -0
- package/rust/core/types/token.rs +83 -0
- package/rust/core/types/variable.rs +32 -0
- package/rust/lib.rs +1 -0
- package/rust/main.rs +49 -0
- package/rust/runner/executer.rs +44 -0
- package/rust/runner/mod.rs +1 -0
- package/rust/utils/loader.rs +19 -0
- package/rust/utils/logger.rs +49 -0
- package/rust/utils/mod.rs +5 -0
- package/rust/utils/path.rs +46 -0
- package/rust/utils/signature.rs +17 -0
- package/rust/utils/version.rs +15 -0
- package/tsconfig.json +113 -0
- package/typescript/bin/index.ts +14 -0
- package/typescript/index.ts +1 -0
- package/typescript/scripts/postbuild.ts +8 -0
- package/typescript/scripts/version/bump.ts +45 -0
- package/typescript/scripts/version/fetch.ts +23 -0
- package/typescript/scripts/version/index.ts +26 -0
- package/typescript/scripts/version/sync.ts +24 -0
package/Cargo.toml
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "devalang"
|
|
3
|
+
version = "0.0.1-alpha.1"
|
|
4
|
+
authors = ["Devaloop <contact@devaloop.com>"]
|
|
5
|
+
description = "Write music like code. Devalang is a domain-specific language (DSL) for sound designers and music hackers. Compose, automate, and control sound — in plain text."
|
|
6
|
+
license = "MIT"
|
|
7
|
+
repository = "https://github.com/devaloop-labs/devalang"
|
|
8
|
+
keywords = ["music", "dsl", "audio", "cli"]
|
|
9
|
+
categories = ["command-line-utilities", "audio", "development-tools"]
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
homepage = "https://devaloop.com"
|
|
12
|
+
documentation = "https://docs.rs/devalang"
|
|
13
|
+
edition = "2024"
|
|
14
|
+
|
|
15
|
+
[[bin]]
|
|
16
|
+
name = "devalang"
|
|
17
|
+
path = "rust/main.rs"
|
|
18
|
+
|
|
19
|
+
[lib]
|
|
20
|
+
path = "rust/lib.rs"
|
|
21
|
+
crate-type = ["cdylib"]
|
|
22
|
+
|
|
23
|
+
[profile.release]
|
|
24
|
+
opt-level = "s"
|
|
25
|
+
|
|
26
|
+
[features]
|
|
27
|
+
default = ["cli"]
|
|
28
|
+
cli = ["crossterm"]
|
|
29
|
+
|
|
30
|
+
[dependencies]
|
|
31
|
+
clap = { version = "4.5", features = ["derive"] }
|
|
32
|
+
serde = { version = "1.0", features = ["derive"] }
|
|
33
|
+
serde_json = "1.0"
|
|
34
|
+
rodio = "0.17"
|
|
35
|
+
hound = "3.4.0"
|
|
36
|
+
toml = "0.8"
|
|
37
|
+
notify = "6.1"
|
|
38
|
+
fs_extra = "1.3"
|
|
39
|
+
include_dir = "0.7"
|
|
40
|
+
wasm-bindgen = "0.2"
|
|
41
|
+
serde-wasm-bindgen = "0.4"
|
|
42
|
+
nom_locate = "4.0.0"
|
|
43
|
+
chrono = "0.4"
|
|
44
|
+
crossterm = { version = "0.27", optional = true }
|
|
45
|
+
indicatif = "0.17"
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Devaloop Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://firebasestorage.googleapis.com/v0/b/devaloop-labs.firebasestorage.app/o/devalang-teal-logo.svg?alt=media&token=d2a5705a-1eba-4b49-88e6-895a761fb7f7" alt="Devalang Logo">
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+

|
|
10
|
+

|
|
11
|
+

|
|
12
|
+

|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
## 🎼 Devalang, by **Devaloop Labs**
|
|
17
|
+
|
|
18
|
+
🎶 Compose music with code — simple, structured, sonic.
|
|
19
|
+
|
|
20
|
+
Devalang is a tiny domain-specific language (DSL) for music makers, sound designers, and audio hackers.
|
|
21
|
+
Compose loops, control samples, and automate parameters — all in clean, readable text.
|
|
22
|
+
|
|
23
|
+
🦊 Whether you're building a track, shaping textures, or performing live, Devalang helps you think in rhythms. It’s designed to be simple, expressive, and fast — because your ideas shouldn’t wait.
|
|
24
|
+
|
|
25
|
+
From studio sketches to live sets, Devalang gives you rhythmic control — with the elegance of code.
|
|
26
|
+
|
|
27
|
+
> 🚧 **v0.0.1-alpha.1 Notice** 🚧
|
|
28
|
+
>
|
|
29
|
+
> Devalang is still in early development. This version does not yet include **sound rendering**.
|
|
30
|
+
>
|
|
31
|
+
> You can parse code, generate the AST, and validate syntax — all essential building blocks for the upcoming audio engine.
|
|
32
|
+
>
|
|
33
|
+
> Currently, only `.kick` is included as a built-in trigger.
|
|
34
|
+
> Custom instruments can be defined with `@load`, allowing any sound sample to be triggered with the same syntax.
|
|
35
|
+
>
|
|
36
|
+
> Currently, Devalang CLI is only available for **Windows**.
|
|
37
|
+
> Linux and macOS binaries will be added in future releases via cross-platform builds.
|
|
38
|
+
|
|
39
|
+
## 🚀 Features
|
|
40
|
+
|
|
41
|
+
- 🧩 Module system for importing and exporting variables between files (`@import`, `@export`)
|
|
42
|
+
- 📜 Structured AST generation for debugging and future compilation
|
|
43
|
+
- 🔢 Basic data types: strings, numbers, booleans, maps, arrays
|
|
44
|
+
- ⏱️ `bpm` assignment for setting tempo
|
|
45
|
+
- 🧱 `bank` declaration to define the instrument set
|
|
46
|
+
- 🔁 Looping system with fixed repetitions (`loop 4:`)
|
|
47
|
+
- 🧪 Instruction calls with parameters (e.g. `.kick auto {reverb:10, decay:20}`) for testing pattern syntax
|
|
48
|
+
- 📄 `let` assignments for storing reusable values
|
|
49
|
+
- 🔄 `@load` assignment to load a sample (.mp3, .wav) to use it as a value
|
|
50
|
+
- 🛠️ CLI tools for syntax checking (`check`), AST output (`build`)
|
|
51
|
+
|
|
52
|
+
## 📆 Installation
|
|
53
|
+
|
|
54
|
+
### For users
|
|
55
|
+
|
|
56
|
+
> - ⚠️ Requires [Node.js 18+](https://nodejs.org/en/download)
|
|
57
|
+
|
|
58
|
+
Install the package globally (NPM)
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm install -g @devaloop/devalang
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Usage without install (NPX)
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npx @devaloop/devalang <command>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### For contributors
|
|
71
|
+
|
|
72
|
+
> - ⚠️ Requires [Node.js 18+](https://nodejs.org/en/download)
|
|
73
|
+
> - ⚠️ Requires [Rust 1.70+](https://www.rust-lang.org/learn/get-started#installing-rust)
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
> git clone https://github.com/devaloop-labs/devalang.git
|
|
77
|
+
> cd devalang
|
|
78
|
+
> npm install
|
|
79
|
+
> cargo install --path .
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Usage for development (feel free to change arguments in package.json)
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# For syntax checking test
|
|
86
|
+
npm run rust:dev <command>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## ❔ Usage
|
|
90
|
+
|
|
91
|
+
For more examples, see [docs/COMMANDS.md](./docs/COMMANDS.md)
|
|
92
|
+
|
|
93
|
+
Checking syntax only and output debug files
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
devalang check --entry <entry-directory> --output <output-directory>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Building output file(s) (AST generation for the moment)
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
devalang build --entry <entry-directory> --output <output-directory>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## 📄 Syntax example
|
|
106
|
+
|
|
107
|
+
For more examples, see [docs/SYNTAX.md](./docs/SYNTAX.md)
|
|
108
|
+
|
|
109
|
+
```deva
|
|
110
|
+
# index.deva
|
|
111
|
+
|
|
112
|
+
@import { globalBpm, globalBank, kickDuration } from "global.deva"
|
|
113
|
+
|
|
114
|
+
bpm globalBpm
|
|
115
|
+
# Will declare the tempo at the globalBpm variable beats per minute
|
|
116
|
+
|
|
117
|
+
bank globalBank
|
|
118
|
+
# Will declare a custom instrument bank using the globalBank variable
|
|
119
|
+
|
|
120
|
+
loop 5:
|
|
121
|
+
.kick kickDuration {reverb=50, drive=25}
|
|
122
|
+
# Will play 5 times a kick for the duration of the kickDuration variable with reverb and drive effects
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```deva
|
|
126
|
+
# global.deva
|
|
127
|
+
|
|
128
|
+
let globalBpm = 120
|
|
129
|
+
let globalBank = 808
|
|
130
|
+
let kickDuration = 500
|
|
131
|
+
|
|
132
|
+
@export { globalBpm, globalBank, kickDuration }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## 🧯 Known issues
|
|
136
|
+
|
|
137
|
+
- No support yet for Audio Engine
|
|
138
|
+
- No support yet for `if`, `else`, `else if` statements
|
|
139
|
+
- No support yet for `@group`, `@pattern`, `@function` statements
|
|
140
|
+
- Nested loops and conditions may not be fully tested
|
|
141
|
+
|
|
142
|
+
## 🧪 Roadmap Highlights
|
|
143
|
+
|
|
144
|
+
For more info, see [docs/ROADMAP.md](./docs/ROADMAP.md)
|
|
145
|
+
|
|
146
|
+
- ⏳ Audio engine integration
|
|
147
|
+
- ⏳ Other statements (e.g `if`, `@group`, ...)
|
|
148
|
+
- ⏳ Watch mode for automatic rebuilds
|
|
149
|
+
|
|
150
|
+
## 🛡️ License
|
|
151
|
+
|
|
152
|
+
MIT — see [LICENSE](./LICENSE)
|
|
153
|
+
|
|
154
|
+
## 🤝 Contributing
|
|
155
|
+
|
|
156
|
+
Contributions, bug reports and suggestions are welcome !
|
|
157
|
+
Feel free to open an issue or submit a pull request.
|
|
158
|
+
|
|
159
|
+
## 📢 Contact
|
|
160
|
+
|
|
161
|
+
📧 [contact@devaloop.com](mailto:contact@devaloop.com)
|
package/docs/COMMANDS.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://firebasestorage.googleapis.com/v0/b/devaloop-labs.firebasestorage.app/o/devalang-teal-logo.svg?alt=media&token=d2a5705a-1eba-4b49-88e6-895a761fb7f7" alt="Devalang Logo">
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
# Devalang Commands Guide
|
|
6
|
+
|
|
7
|
+
## Checking
|
|
8
|
+
|
|
9
|
+
Checking syntax of .deva file(s)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
devalang check --entry ./examples --output ./output
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Available arguments :
|
|
16
|
+
|
|
17
|
+
- `entry`: The input folder (default to `./src`)
|
|
18
|
+
- `output`: The output folder (default to `./output`)
|
|
19
|
+
|
|
20
|
+
## Building
|
|
21
|
+
|
|
22
|
+
Building AST of .deva file(s)
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
devalang build --entry ./examples --output ./output
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Available arguments :
|
|
29
|
+
|
|
30
|
+
- `entry`: The input folder (default to `./src`)
|
|
31
|
+
- `output`: The output folder (default to `./output`)
|
package/docs/ROADMAP.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://firebasestorage.googleapis.com/v0/b/devaloop-labs.firebasestorage.app/o/devalang-teal-logo.svg?alt=media&token=d2a5705a-1eba-4b49-88e6-895a761fb7f7" alt="Devalang Logo">
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
# Roadmap
|
|
6
|
+
|
|
7
|
+
Devalang is a work in progress. Here’s what we’re planning next:
|
|
8
|
+
|
|
9
|
+
- ✅ **Basic syntax**: Implement the core syntax for Devalang, including data types and basic statements.
|
|
10
|
+
- ✅ **Module system**: Add support for importing and exporting variables between files using `@import` and `@export`.
|
|
11
|
+
- ✅ **AST generation**: Implement the Abstract Syntax Tree (AST) generation for debugging and future compilation.
|
|
12
|
+
- ✅ **Basic data types**: Support strings, numbers, booleans, maps, and arrays.
|
|
13
|
+
- ✅ **BPM assignment**: Implement `bpm` assignment to set the tempo.
|
|
14
|
+
- ✅ **Bank declaration**: Add `bank` declaration to define the instrument set.
|
|
15
|
+
- ✅ **Looping system**: Implement a looping system with fixed repetitions using `loop 4:`.
|
|
16
|
+
- ✅ **Instruction calls**: Add support for instruction calls with parameters (e.g. `.kick auto {reverb:10, decay:20}`).
|
|
17
|
+
- ✅ **Let assignments**: Implement `let` assignments for storing reusable values.
|
|
18
|
+
- ✅ **Sample loading**: Add `@load` assignment to load samples (.mp3, .wav) for use as values.
|
|
19
|
+
|
|
20
|
+
- ⏳ **VSCode extension**: Create a VSCode extension for syntax highlighting and code completion.
|
|
21
|
+
- ⏳ **WASM support**: Compile Devalang to WebAssembly for use in web applications.
|
|
22
|
+
- ⏳ **Other statements**: Implement `if`, `else`, and other control structures.
|
|
23
|
+
- ⏳ **Pattern and group statements**: Add support for `@pattern` and `@group` to organize code.
|
|
24
|
+
- ⏳ **Watch mode**: Add a watch mode to automatically rebuild on file changes.
|
|
25
|
+
- ⏳ **Functions**: Add support for defining and calling functions.
|
|
26
|
+
- ⏳ **Audio engine**: Integrate the audio engine for sound playback.
|
|
27
|
+
- ⏳ **Testing**: Expand test coverage for all features.
|
package/docs/SYNTAX.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://firebasestorage.googleapis.com/v0/b/devaloop-labs.firebasestorage.app/o/devalang-teal-logo.svg?alt=media&token=d2a5705a-1eba-4b49-88e6-895a761fb7f7" alt="Devalang Logo">
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
# Devalang Syntax Guide
|
|
6
|
+
|
|
7
|
+
Devalang supports a simple and intuitive syntax for composing music and sound design. Below is a guide to the basic syntax elements, types, and usage examples.
|
|
8
|
+
|
|
9
|
+
The engine is designed to be easy to read and write, allowing you to focus on your music rather than the code.
|
|
10
|
+
|
|
11
|
+
The engine uses indentation to define blocks, similar to Python. Each block must be indented consistently.
|
|
12
|
+
|
|
13
|
+
➡️ For full examples, check the `examples/` folder of the repository.
|
|
14
|
+
|
|
15
|
+
## Types
|
|
16
|
+
|
|
17
|
+
<details>
|
|
18
|
+
<summary>Show available types</summary>
|
|
19
|
+
|
|
20
|
+
### String
|
|
21
|
+
|
|
22
|
+
Strings are defined using double quotes.
|
|
23
|
+
|
|
24
|
+
```deva
|
|
25
|
+
let string = "myValue"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Number
|
|
29
|
+
|
|
30
|
+
Numbers can be integers or floating-point values. They do not require quotes.
|
|
31
|
+
|
|
32
|
+
```deva
|
|
33
|
+
let number = 99
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Boolean
|
|
37
|
+
|
|
38
|
+
Booleans can be either `true` or `false` without quotes.
|
|
39
|
+
|
|
40
|
+
```deva
|
|
41
|
+
let boolean = false
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Map
|
|
45
|
+
|
|
46
|
+
Maps are key-value pairs defined using curly braces. Keys are strings, and values can be of any type (string, number, boolean, map, or array).
|
|
47
|
+
|
|
48
|
+
```deva
|
|
49
|
+
let map = {myKey: 99}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Array
|
|
53
|
+
|
|
54
|
+
Arrays are ordered lists of values defined using square brackets. Values can be of any type (string, number, boolean, map, or array).
|
|
55
|
+
|
|
56
|
+
```deva
|
|
57
|
+
let array = [3, 4]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
</details>
|
|
61
|
+
|
|
62
|
+
## Syntax usage
|
|
63
|
+
|
|
64
|
+
### Beats Per Minute
|
|
65
|
+
|
|
66
|
+
BPM is used to set the global tempo of the music.
|
|
67
|
+
|
|
68
|
+
```deva
|
|
69
|
+
bpm 125
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Sound Bank
|
|
73
|
+
|
|
74
|
+
Bank is used to select a sound bank for the audio engine.
|
|
75
|
+
|
|
76
|
+
```deva
|
|
77
|
+
bank 808
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Importing / Exporting Modules
|
|
81
|
+
|
|
82
|
+
Modules can be imported and exported to share variables between different files.
|
|
83
|
+
|
|
84
|
+
Exporting variables from a module :
|
|
85
|
+
|
|
86
|
+
```deva
|
|
87
|
+
# exported.deva
|
|
88
|
+
|
|
89
|
+
let exportedIterator = 10
|
|
90
|
+
let exportedParams = {drive: 50, decay: 30}
|
|
91
|
+
|
|
92
|
+
@export { exportedIterator, exportedParams }
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Importing and using the exported variables in another module :
|
|
96
|
+
|
|
97
|
+
```deva
|
|
98
|
+
# index.deva
|
|
99
|
+
|
|
100
|
+
@import { exportedIterator, exportedParams } "./exported.deva"
|
|
101
|
+
|
|
102
|
+
loop exportedIterator:
|
|
103
|
+
.kick auto exportedParams
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Built-in triggers
|
|
107
|
+
|
|
108
|
+
Usage : `.<trigger-name> <duration> <effects-map>`
|
|
109
|
+
|
|
110
|
+
Other triggers will be added in future releases (e.g. `.snare`, `.hihat`, `.tom`, `.clap`, `.crash`, `.ride`, `.synth`, `.bass`, `.pad`).
|
|
111
|
+
You can also create custom triggers using the `@load` directive.
|
|
112
|
+
|
|
113
|
+
```deva
|
|
114
|
+
.kick
|
|
115
|
+
.kick 1/4
|
|
116
|
+
.kick auto {reverb: 50, decay: 30}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Custom triggers
|
|
120
|
+
|
|
121
|
+
Same usage as built-in triggers, but with custom audio files or effects.
|
|
122
|
+
|
|
123
|
+
```deva
|
|
124
|
+
@load "./path/to/instrument.mp3" as mySample
|
|
125
|
+
|
|
126
|
+
.mySample auto {reverb: 50, drive: 25}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Let variables
|
|
130
|
+
|
|
131
|
+
Variables are defined using the `let` keyword, followed by the variable name and its value. The value can be of any type (string, number, boolean, map, or array).
|
|
132
|
+
|
|
133
|
+
```deva
|
|
134
|
+
let number = 0
|
|
135
|
+
let boolean = true
|
|
136
|
+
let string = "string"
|
|
137
|
+
let map = {myKey: 200}
|
|
138
|
+
let array = [0, 1, 2]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Basic loops
|
|
142
|
+
|
|
143
|
+
Loops are defined using the `loop` keyword, followed by the number of iterations. The body of the loop is indented.
|
|
144
|
+
|
|
145
|
+
```deva
|
|
146
|
+
loop 10:
|
|
147
|
+
# ...
|
|
148
|
+
```
|
package/docs/TODO.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://firebasestorage.googleapis.com/v0/b/devaloop-labs.firebasestorage.app/o/devalang-teal-logo.svg?alt=media&token=d2a5705a-1eba-4b49-88e6-895a761fb7f7" alt="Devalang Logo">
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
# TODOs list
|
|
6
|
+
|
|
7
|
+
This is a list of tasks and features to be implemented in Devalang. Note that this is not an exhaustive list, and some items may be added or removed over time.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
- [ ] New project
|
|
12
|
+
- [ ] Template
|
|
13
|
+
- [ ] Implement template list
|
|
14
|
+
- [ ] Implement template info
|
|
15
|
+
- [x] Checking
|
|
16
|
+
- [ ] Implement watch mode
|
|
17
|
+
- [ ] Implement debug mode
|
|
18
|
+
- [ ] Implement compilation mode
|
|
19
|
+
- [x] Building
|
|
20
|
+
- [ ] Implement watch mode
|
|
21
|
+
- [ ] Implement debug mode
|
|
22
|
+
- [ ] Implement compilation mode
|
|
23
|
+
- [ ] Implement compression mode
|
|
24
|
+
- [ ] Play
|
|
25
|
+
- [ ] Implement Audio Engine
|
|
26
|
+
- [ ] Implement loop mode
|
|
27
|
+
|
|
28
|
+
## Core components
|
|
29
|
+
|
|
30
|
+
- [ ] Audio Engine
|
|
31
|
+
- [x] Lexer
|
|
32
|
+
- [x] Parser
|
|
33
|
+
- [x] Preprocessor
|
|
34
|
+
- [x] Debugger
|
|
35
|
+
- [x] Builder
|
|
36
|
+
|
|
37
|
+
## Syntax elements
|
|
38
|
+
|
|
39
|
+
- [ ] #
|
|
40
|
+
- [x] @import
|
|
41
|
+
- [x] @export
|
|
42
|
+
- [ ] @group
|
|
43
|
+
- [ ] @pattern
|
|
44
|
+
- [ ] @function
|
|
45
|
+
- [x] @load
|
|
46
|
+
- [ ] @include
|
|
47
|
+
- [x] bpm
|
|
48
|
+
- [x] bank
|
|
49
|
+
- [x] loop
|
|
50
|
+
- [x] let
|
|
51
|
+
- [ ] if
|
|
52
|
+
- [ ] else
|
|
53
|
+
- [ ] else if
|
|
54
|
+
|
|
55
|
+
## Built-in triggers
|
|
56
|
+
|
|
57
|
+
- [x] .kick
|
|
58
|
+
- [ ] .snare
|
|
59
|
+
- [ ] .hihat
|
|
60
|
+
- [ ] .tom
|
|
61
|
+
- [ ] .clap
|
|
62
|
+
- [ ] .crash
|
|
63
|
+
- [ ] .ride
|
|
64
|
+
- [ ] .synth
|
|
65
|
+
- [ ] .bass
|
|
66
|
+
- [ ] .pad
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const binaryPath = path_1.default.join(__dirname, "devalang.exe");
|
|
10
|
+
const subCommand = process.argv[2] || "help";
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
const child = (0, child_process_1.spawn)(binaryPath, args, { stdio: "inherit" });
|
|
13
|
+
child.on("exit", (code) => process.exit(code));
|
package/out-tsc/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const source = path_1.default.join(__dirname, "..", "..", "target", "release", "devalang.exe");
|
|
9
|
+
const destination = path_1.default.join(__dirname, "..", "bin", "devalang.exe");
|
|
10
|
+
fs_1.default.copyFileSync(source, destination);
|
|
11
|
+
fs_1.default.chmodSync(destination, 0o755);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.bumpVersion = void 0;
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const bumpVersion = (bumpType, projectVersionPath) => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
const versionData = JSON.parse(fs_1.default.readFileSync(projectVersionPath, "utf-8"));
|
|
19
|
+
const versionRegex = /^(\d+)\.(\d+)\.(\d+)(?:-([\w.]+))?$/;
|
|
20
|
+
const match = versionData.version.match(versionRegex);
|
|
21
|
+
if (!match) {
|
|
22
|
+
throw new Error("Invalid version format in project-version.json");
|
|
23
|
+
}
|
|
24
|
+
if (!bumpType) {
|
|
25
|
+
console.error("❌ Please specify a version type (major, minor, patch, pre)");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
let [_, major, minor, patch, pre] = match;
|
|
29
|
+
let nextVersion = "";
|
|
30
|
+
switch (bumpType) {
|
|
31
|
+
case "major":
|
|
32
|
+
nextVersion = `${+major + 1}.0.0`;
|
|
33
|
+
break;
|
|
34
|
+
case "minor":
|
|
35
|
+
nextVersion = `${major}.${+minor + 1}.0`;
|
|
36
|
+
break;
|
|
37
|
+
case "patch":
|
|
38
|
+
nextVersion = `${major}.${minor}.${+patch + 1}`;
|
|
39
|
+
break;
|
|
40
|
+
case "pre":
|
|
41
|
+
const [preid, prenumber] = (pre || "alpha.0").split(".");
|
|
42
|
+
nextVersion = `${major}.${minor}.${patch}-${preid}.${+prenumber + 1}`;
|
|
43
|
+
break;
|
|
44
|
+
default:
|
|
45
|
+
console.error("❌ Version type non-recognized (major, minor, patch, pre)");
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
versionData.version = nextVersion;
|
|
49
|
+
fs_1.default.writeFileSync(projectVersionPath, JSON.stringify(versionData, null, 2));
|
|
50
|
+
return nextVersion;
|
|
51
|
+
});
|
|
52
|
+
exports.bumpVersion = bumpVersion;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.fetchVersion = void 0;
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const child_process_1 = require("child_process");
|
|
18
|
+
const fetchVersion = (projectVersionPath) => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
// Lire le fichier
|
|
20
|
+
const data = JSON.parse(fs_1.default.readFileSync(projectVersionPath, "utf-8"));
|
|
21
|
+
// Incrémenter le numéro de build
|
|
22
|
+
data.build = (data.build || 0) + 1;
|
|
23
|
+
// Récupérer le dernier hash git
|
|
24
|
+
try {
|
|
25
|
+
const commit = (0, child_process_1.execSync)("git rev-parse HEAD").toString().trim();
|
|
26
|
+
data.lastCommit = commit;
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
console.warn("⚠️ Impossible de récupérer le hash git.");
|
|
30
|
+
}
|
|
31
|
+
// Écrire la mise à jour
|
|
32
|
+
fs_1.default.writeFileSync(projectVersionPath, JSON.stringify(data, null, 2));
|
|
33
|
+
});
|
|
34
|
+
exports.fetchVersion = fetchVersion;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const bump_1 = require("./bump");
|
|
17
|
+
const sync_1 = require("./sync");
|
|
18
|
+
const fetch_1 = require("./fetch");
|
|
19
|
+
const bumpType = process.argv[2] || "patch";
|
|
20
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
+
const projectVersionPath = path_1.default.join(__dirname, "../../../project-version.json");
|
|
22
|
+
try {
|
|
23
|
+
const newVersion = yield (0, bump_1.bumpVersion)(bumpType, projectVersionPath);
|
|
24
|
+
yield (0, fetch_1.fetchVersion)(projectVersionPath);
|
|
25
|
+
yield (0, sync_1.syncVersion)(projectVersionPath);
|
|
26
|
+
console.log(`✅ Project version updated to : ${newVersion}`);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
console.error(`❌ Error updating project version: ${error}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
}))();
|