@devaloop/devalang 0.0.1-alpha.1 → 0.0.1-alpha.3
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/.devalang +4 -0
- package/Cargo.toml +46 -45
- package/README.md +35 -10
- package/docs/CHANGELOG.md +58 -0
- package/docs/COMMANDS.md +29 -6
- package/docs/CONFIG.md +28 -0
- package/docs/ROADMAP.md +6 -2
- package/docs/TODO.md +21 -18
- package/examples/exported.deva +1 -1
- package/examples/index.deva +2 -1
- package/out-tsc/bin/devalang.exe +0 -0
- package/package.json +2 -3
- package/project-version.json +4 -4
- package/rust/cli/build.rs +99 -29
- package/rust/cli/check.rs +95 -103
- package/rust/cli/init.rs +77 -0
- package/rust/cli/mod.rs +174 -1
- package/rust/cli/template.rs +56 -0
- package/rust/config/loader.rs +14 -0
- package/rust/config/mod.rs +15 -0
- package/rust/core/builder/mod.rs +21 -27
- package/rust/core/debugger/lexer.rs +12 -0
- package/rust/core/debugger/mod.rs +12 -49
- package/rust/core/debugger/preprocessor.rs +23 -0
- package/rust/core/error/mod.rs +60 -0
- package/rust/core/lexer/handler/at.rs +21 -0
- package/rust/core/lexer/handler/brace.rs +41 -0
- package/rust/core/lexer/handler/colon.rs +21 -0
- package/rust/core/lexer/handler/comment.rs +30 -0
- package/rust/core/lexer/handler/dot.rs +21 -0
- package/rust/core/lexer/handler/equal.rs +32 -0
- package/rust/core/lexer/handler/identifier.rs +38 -0
- package/rust/core/lexer/handler/indent.rs +52 -0
- package/rust/core/lexer/handler/mod.rs +238 -0
- package/rust/core/lexer/handler/newline.rs +19 -0
- package/rust/core/lexer/handler/number.rs +31 -0
- package/rust/core/lexer/handler/string.rs +66 -0
- package/rust/core/lexer/mod.rs +16 -324
- package/rust/core/lexer/token.rs +55 -0
- package/rust/core/mod.rs +5 -2
- package/rust/core/parser/handler/at.rs +166 -0
- package/rust/core/parser/handler/bank.rs +38 -0
- package/rust/core/parser/handler/dot.rs +112 -0
- package/rust/core/parser/handler/identifier.rs +134 -0
- package/rust/core/parser/handler/loop_.rs +55 -0
- package/rust/core/parser/handler/mod.rs +6 -0
- package/rust/core/parser/handler/tempo.rs +47 -0
- package/rust/core/parser/mod.rs +204 -166
- package/rust/core/parser/statement.rs +91 -0
- package/rust/core/preprocessor/loader.rs +105 -0
- package/rust/core/preprocessor/mod.rs +2 -24
- package/rust/core/preprocessor/module.rs +37 -56
- package/rust/core/preprocessor/processor.rs +41 -0
- package/rust/core/preprocessor/resolver.rs +372 -0
- package/rust/core/shared/duration.rs +8 -0
- package/rust/core/shared/mod.rs +2 -0
- package/rust/core/shared/value.rs +18 -0
- package/rust/core/store/export.rs +28 -0
- package/rust/core/store/global.rs +39 -0
- package/rust/core/store/import.rs +28 -0
- package/rust/core/store/mod.rs +4 -0
- package/rust/core/store/variable.rs +28 -0
- package/rust/core/utils/mod.rs +2 -0
- package/rust/core/utils/validation.rs +35 -0
- package/rust/lib.rs +0 -1
- package/rust/main.rs +39 -30
- package/rust/utils/file.rs +35 -0
- package/rust/utils/logger.rs +69 -34
- package/rust/utils/mod.rs +3 -2
- package/rust/utils/watcher.rs +25 -0
- package/templates/minimal/.devalang +4 -0
- package/templates/minimal/src/index.deva +2 -0
- package/templates/welcome/.devalang +4 -0
- package/templates/welcome/README.md +185 -0
- package/templates/welcome/samples/kick-808.wav +0 -0
- package/templates/welcome/src/index.deva +13 -0
- package/templates/welcome/src/variables.deva +5 -0
- package/rust/audio/mod.rs +0 -1
- package/rust/cli/new.rs +0 -1
- package/rust/core/parser/at.rs +0 -142
- package/rust/core/parser/bank.rs +0 -42
- package/rust/core/parser/dot.rs +0 -107
- package/rust/core/parser/identifer.rs +0 -91
- package/rust/core/parser/loop_.rs +0 -62
- package/rust/core/parser/tempo.rs +0 -42
- package/rust/core/parser/variable.rs +0 -129
- package/rust/core/preprocessor/dependencies.rs +0 -54
- package/rust/core/preprocessor/resolver/at.rs +0 -24
- package/rust/core/preprocessor/resolver/bank.rs +0 -59
- package/rust/core/preprocessor/resolver/loop_.rs +0 -82
- package/rust/core/preprocessor/resolver/mod.rs +0 -113
- package/rust/core/preprocessor/resolver/tempo.rs +0 -70
- package/rust/core/preprocessor/resolver/trigger.rs +0 -176
- package/rust/core/types/cli.rs +0 -160
- package/rust/core/types/mod.rs +0 -7
- package/rust/core/types/module.rs +0 -41
- package/rust/core/types/parser.rs +0 -73
- package/rust/core/types/statement.rs +0 -105
- package/rust/core/types/store.rs +0 -116
- package/rust/core/types/token.rs +0 -83
- package/rust/core/types/variable.rs +0 -32
- package/rust/runner/executer.rs +0 -44
- package/rust/runner/mod.rs +0 -1
- /package/rust/{utils → core/utils}/path.rs +0 -0
- /package/rust/utils/{loader.rs → spinner.rs} +0 -0
package/.devalang
ADDED
package/Cargo.toml
CHANGED
|
@@ -1,45 +1,46 @@
|
|
|
1
|
-
[package]
|
|
2
|
-
name = "devalang"
|
|
3
|
-
version = "0.0.1-alpha.
|
|
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"
|
|
1
|
+
[package]
|
|
2
|
+
name = "devalang"
|
|
3
|
+
version = "0.0.1-alpha.3"
|
|
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"
|
|
46
|
+
inquire = "0.7.5"
|
package/README.md
CHANGED
|
@@ -30,7 +30,6 @@ From studio sketches to live sets, Devalang gives you rhythmic control — with
|
|
|
30
30
|
>
|
|
31
31
|
> You can parse code, generate the AST, and validate syntax — all essential building blocks for the upcoming audio engine.
|
|
32
32
|
>
|
|
33
|
-
> Currently, only `.kick` is included as a built-in trigger.
|
|
34
33
|
> Custom instruments can be defined with `@load`, allowing any sound sample to be triggered with the same syntax.
|
|
35
34
|
>
|
|
36
35
|
> Currently, Devalang CLI is only available for **Windows**.
|
|
@@ -41,6 +40,7 @@ From studio sketches to live sets, Devalang gives you rhythmic control — with
|
|
|
41
40
|
- 🧩 Module system for importing and exporting variables between files (`@import`, `@export`)
|
|
42
41
|
- 📜 Structured AST generation for debugging and future compilation
|
|
43
42
|
- 🔢 Basic data types: strings, numbers, booleans, maps, arrays
|
|
43
|
+
- 👁️ Watch mode for `build` and `check` commands
|
|
44
44
|
- ⏱️ `bpm` assignment for setting tempo
|
|
45
45
|
- 🧱 `bank` declaration to define the instrument set
|
|
46
46
|
- 🔁 Looping system with fixed repetitions (`loop 4:`)
|
|
@@ -83,25 +83,49 @@ Usage for development (feel free to change arguments in package.json)
|
|
|
83
83
|
|
|
84
84
|
```bash
|
|
85
85
|
# For syntax checking test
|
|
86
|
-
npm run rust:dev
|
|
86
|
+
npm run rust:dev:check
|
|
87
|
+
# For building test
|
|
88
|
+
npm run rust:dev:build
|
|
87
89
|
```
|
|
88
90
|
|
|
89
91
|
## ❔ Usage
|
|
90
92
|
|
|
91
93
|
For more examples, see [docs/COMMANDS.md](./docs/COMMANDS.md)
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
### Initialize a new project
|
|
96
|
+
|
|
97
|
+
In the current directory
|
|
94
98
|
|
|
95
99
|
```bash
|
|
96
|
-
devalang
|
|
100
|
+
devalang init
|
|
97
101
|
```
|
|
98
102
|
|
|
99
|
-
|
|
103
|
+
Or use optional arguments to specify a directory name and a template
|
|
100
104
|
|
|
101
105
|
```bash
|
|
102
|
-
devalang
|
|
106
|
+
devalang init --name <project-name> --template <template-name>
|
|
103
107
|
```
|
|
104
108
|
|
|
109
|
+
### Checking syntax only
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
devalang check --entry <entry-directory> --output <output-directory> --watch
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Building output files
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
devalang build --entry <entry-directory> --output <output-directory> --watch
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## ⚙️ Configuration
|
|
122
|
+
|
|
123
|
+
You can use a configuration file to set default values for various settings, making it easier to manage your Devalang project.
|
|
124
|
+
|
|
125
|
+
To do this, create a `.devalang` file in the root of your project directory.
|
|
126
|
+
|
|
127
|
+
See [docs/CONFIG.md](./docs/CONFIG.md) for more information.
|
|
128
|
+
|
|
105
129
|
## 📄 Syntax example
|
|
106
130
|
|
|
107
131
|
For more examples, see [docs/SYNTAX.md](./docs/SYNTAX.md)
|
|
@@ -127,7 +151,7 @@ loop 5:
|
|
|
127
151
|
|
|
128
152
|
let globalBpm = 120
|
|
129
153
|
let globalBank = 808
|
|
130
|
-
let kickDuration = 500
|
|
154
|
+
let kickDuration = 500
|
|
131
155
|
|
|
132
156
|
@export { globalBpm, globalBank, kickDuration }
|
|
133
157
|
```
|
|
@@ -137,15 +161,16 @@ let kickDuration = 500
|
|
|
137
161
|
- No support yet for Audio Engine
|
|
138
162
|
- No support yet for `if`, `else`, `else if` statements
|
|
139
163
|
- No support yet for `@group`, `@pattern`, `@function` statements
|
|
140
|
-
-
|
|
164
|
+
- No support yet for cross-platform builds (Linux, macOS)
|
|
141
165
|
|
|
142
166
|
## 🧪 Roadmap Highlights
|
|
143
167
|
|
|
144
168
|
For more info, see [docs/ROADMAP.md](./docs/ROADMAP.md)
|
|
145
169
|
|
|
146
|
-
- ⏳ Audio engine integration
|
|
170
|
+
- ⏳ Audio engine integration (priority for alpha.4)
|
|
147
171
|
- ⏳ Other statements (e.g `if`, `@group`, ...)
|
|
148
|
-
- ⏳
|
|
172
|
+
- ⏳ Cross-platform support (Linux, macOS)
|
|
173
|
+
- ⏳ More built-in instruments (e.g. snare, hi-hat, etc.)
|
|
149
174
|
|
|
150
175
|
## 🛡️ License
|
|
151
176
|
|
|
@@ -0,0 +1,58 @@
|
|
|
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
|
+
# Changelog
|
|
6
|
+
|
|
7
|
+
## Version 0.0.1-alpha.3 (2025-07-01)
|
|
8
|
+
|
|
9
|
+
- /!\ Major refactor of the project structure and module system /!\
|
|
10
|
+
- Refactored module system to support multiple modules and submodules.
|
|
11
|
+
- Patched all directives to be compatible with the new project structure.
|
|
12
|
+
- Prepared for the upcoming audio engine integration and sound rendering capabilities.
|
|
13
|
+
- Updated documentation to reflect the new project structure and features.
|
|
14
|
+
|
|
15
|
+
## Version 0.0.1-alpha.2 (2025-06-26)
|
|
16
|
+
|
|
17
|
+
### Commands
|
|
18
|
+
|
|
19
|
+
- Implemented `init` command to initialize a new Devalang project.
|
|
20
|
+
- Implemented `template` command to manage templates.
|
|
21
|
+
- Added `list` subcommand to list available templates.
|
|
22
|
+
- Added `info` subcommand to show information about a specific template.
|
|
23
|
+
- Implemented `watch` subcommand for the `build` and `check` command to watch for changes in files and automatically rebuild or check them.
|
|
24
|
+
|
|
25
|
+
### Core Components
|
|
26
|
+
|
|
27
|
+
- Implemented Config manager to handle configuration files.
|
|
28
|
+
- Added support for `.devalang` configuration file as a TOML file.
|
|
29
|
+
- Implemented File System watcher to monitor file changes.
|
|
30
|
+
- Implemented Template manager to handle templates and their metadata.
|
|
31
|
+
|
|
32
|
+
### Syntax
|
|
33
|
+
|
|
34
|
+
- Added support for built-in triggers for `.snare`, `.hihat`, `.clap`, `.tom`, `.crash`, `.ride`, `.synth`, `.bass`, and `.pad`.
|
|
35
|
+
|
|
36
|
+
## Version 0.0.1-alpha.1 (2025-06-25)
|
|
37
|
+
|
|
38
|
+
### Syntax
|
|
39
|
+
|
|
40
|
+
- Added support for `@import` directive to import other Devalang files.
|
|
41
|
+
- Added support for `@export` directive to export variables and functions.
|
|
42
|
+
- Added support for `@load` directive to load external resources.
|
|
43
|
+
- Added support for `bpm` directive to set the beats per minute.
|
|
44
|
+
- Added support for `bank` directive to define a bank of sounds.
|
|
45
|
+
- Added support for `loop` directive to define loops in the code.
|
|
46
|
+
|
|
47
|
+
### Commands
|
|
48
|
+
|
|
49
|
+
- Implemented `check` command to check the syntax of Devalang files.
|
|
50
|
+
- Implemented `build` command to build the Abstract Syntax Tree (AST) of Devalang files.
|
|
51
|
+
|
|
52
|
+
### Core Components
|
|
53
|
+
|
|
54
|
+
- Implemented Lexer to tokenize Devalang source code.
|
|
55
|
+
- Implemented Parser to parse the tokens and build the AST.
|
|
56
|
+
- Implemented Preprocessor to handle directives and preprocess the source code.
|
|
57
|
+
- Implemented Debugger to debug Devalang code.
|
|
58
|
+
- Implemented Builder to build the final output from the AST.
|
package/docs/COMMANDS.md
CHANGED
|
@@ -4,28 +4,51 @@
|
|
|
4
4
|
|
|
5
5
|
# Devalang Commands Guide
|
|
6
6
|
|
|
7
|
+
## Initialization
|
|
8
|
+
|
|
9
|
+
Initialize a new Devalang project (current folder)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
devalang init
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Initialize a new Devalang project (new folder)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
devalang init --name <project-name> --template <template-name>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Available arguments:
|
|
22
|
+
|
|
23
|
+
- `--name`: The name of the project (cannot be empty)
|
|
24
|
+
- `--template`: The template to use for the project (default to `welcome`)
|
|
25
|
+
|
|
7
26
|
## Checking
|
|
8
27
|
|
|
9
28
|
Checking syntax of .deva file(s)
|
|
10
29
|
|
|
11
30
|
```bash
|
|
12
|
-
devalang check --entry ./examples --output ./output
|
|
31
|
+
devalang check --entry ./examples --output ./output --watch
|
|
13
32
|
```
|
|
14
33
|
|
|
15
34
|
Available arguments :
|
|
16
35
|
|
|
17
|
-
-
|
|
18
|
-
-
|
|
36
|
+
- `--no-config`: Whether to ignore the configuration file (default to `false`)
|
|
37
|
+
- `--entry`: The input folder (default to `./src`)
|
|
38
|
+
- `--output`: The output folder (default to `./output`)
|
|
39
|
+
- `--watch`: Whether to watch for changes and re-analyze (default to `false`)
|
|
19
40
|
|
|
20
41
|
## Building
|
|
21
42
|
|
|
22
43
|
Building AST of .deva file(s)
|
|
23
44
|
|
|
24
45
|
```bash
|
|
25
|
-
devalang build --entry ./examples --output ./output
|
|
46
|
+
devalang build --entry ./examples --output ./output --watch
|
|
26
47
|
```
|
|
27
48
|
|
|
28
49
|
Available arguments :
|
|
29
50
|
|
|
30
|
-
-
|
|
31
|
-
-
|
|
51
|
+
- `--no-config`: Whether to ignore the configuration file (default to `false`)
|
|
52
|
+
- `--entry`: The input folder (default to `./src`)
|
|
53
|
+
- `--output`: The output folder (default to `./output`)
|
|
54
|
+
- `--watch`: Whether to watch for changes and rebuild (default to `false`)
|
package/docs/CONFIG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
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 Configuration File
|
|
6
|
+
|
|
7
|
+
Use a configuration file if you don't want to pass command-line arguments every time you run a command. The configuration file allows you to set default values for various settings, making it easier to manage your Devalang project.
|
|
8
|
+
|
|
9
|
+
## Ignoring the Configuration File
|
|
10
|
+
|
|
11
|
+
If you prefer not to use a configuration file, you can ignore it by passing the `--no-config` flag when running Devalang commands. This will bypass any settings defined in the configuration file and use only the command-line arguments you provide.
|
|
12
|
+
|
|
13
|
+
## Structure of the Configuration File
|
|
14
|
+
|
|
15
|
+
The configuration file is a TOML (Tom's Obvious, Minimal Language) file that contains key-value pairs to define various settings for your Devalang project. Below is a sample configuration file:
|
|
16
|
+
|
|
17
|
+
```toml
|
|
18
|
+
[defaults]
|
|
19
|
+
entry = "./src"
|
|
20
|
+
output = "./output"
|
|
21
|
+
watch = true
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Available Settings
|
|
25
|
+
|
|
26
|
+
- `entry`: (String) The entry point for your Devalang project
|
|
27
|
+
- `output`: (String) The output directory for generated files
|
|
28
|
+
- `watch`: (Boolean) Whether to watch for changes in files and automatically rebuild or check them
|
package/docs/ROADMAP.md
CHANGED
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
Devalang is a work in progress. Here’s what we’re planning next:
|
|
8
8
|
|
|
9
|
+
### Stable
|
|
10
|
+
|
|
9
11
|
- ✅ **Basic syntax**: Implement the core syntax for Devalang, including data types and basic statements.
|
|
12
|
+
- ✅ **Watch mode**: Add a watch mode to automatically rebuild on file changes.
|
|
10
13
|
- ✅ **Module system**: Add support for importing and exporting variables between files using `@import` and `@export`.
|
|
11
14
|
- ✅ **AST generation**: Implement the Abstract Syntax Tree (AST) generation for debugging and future compilation.
|
|
12
15
|
- ✅ **Basic data types**: Support strings, numbers, booleans, maps, and arrays.
|
|
@@ -17,11 +20,12 @@ Devalang is a work in progress. Here’s what we’re planning next:
|
|
|
17
20
|
- ✅ **Let assignments**: Implement `let` assignments for storing reusable values.
|
|
18
21
|
- ✅ **Sample loading**: Add `@load` assignment to load samples (.mp3, .wav) for use as values.
|
|
19
22
|
|
|
23
|
+
### Upcoming
|
|
24
|
+
|
|
25
|
+
- ⏳ **Audio engine**: Integrate the audio engine for sound playback.
|
|
20
26
|
- ⏳ **VSCode extension**: Create a VSCode extension for syntax highlighting and code completion.
|
|
21
27
|
- ⏳ **WASM support**: Compile Devalang to WebAssembly for use in web applications.
|
|
22
28
|
- ⏳ **Other statements**: Implement `if`, `else`, and other control structures.
|
|
23
29
|
- ⏳ **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
30
|
- ⏳ **Functions**: Add support for defining and calling functions.
|
|
26
|
-
- ⏳ **Audio engine**: Integrate the audio engine for sound playback.
|
|
27
31
|
- ⏳ **Testing**: Expand test coverage for all features.
|
package/docs/TODO.md
CHANGED
|
@@ -8,16 +8,19 @@ This is a list of tasks and features to be implemented in Devalang. Note that th
|
|
|
8
8
|
|
|
9
9
|
## Commands
|
|
10
10
|
|
|
11
|
-
- [
|
|
12
|
-
- [
|
|
13
|
-
- [
|
|
14
|
-
- [ ] Implement
|
|
11
|
+
- [x] Init project
|
|
12
|
+
- [x] Implement init command
|
|
13
|
+
- [x] Implement template selector
|
|
14
|
+
- [ ] Implement project name validation
|
|
15
|
+
- [x] Template
|
|
16
|
+
- [x] Implement template list
|
|
17
|
+
- [x] Implement template info
|
|
15
18
|
- [x] Checking
|
|
16
|
-
- [
|
|
19
|
+
- [x] Implement watch mode
|
|
17
20
|
- [ ] Implement debug mode
|
|
18
21
|
- [ ] Implement compilation mode
|
|
19
22
|
- [x] Building
|
|
20
|
-
- [
|
|
23
|
+
- [x] Implement watch mode
|
|
21
24
|
- [ ] Implement debug mode
|
|
22
25
|
- [ ] Implement compilation mode
|
|
23
26
|
- [ ] Implement compression mode
|
|
@@ -36,7 +39,7 @@ This is a list of tasks and features to be implemented in Devalang. Note that th
|
|
|
36
39
|
|
|
37
40
|
## Syntax elements
|
|
38
41
|
|
|
39
|
-
- [
|
|
42
|
+
- [x] #
|
|
40
43
|
- [x] @import
|
|
41
44
|
- [x] @export
|
|
42
45
|
- [ ] @group
|
|
@@ -52,15 +55,15 @@ This is a list of tasks and features to be implemented in Devalang. Note that th
|
|
|
52
55
|
- [ ] else
|
|
53
56
|
- [ ] else if
|
|
54
57
|
|
|
55
|
-
##
|
|
58
|
+
## Triggers
|
|
56
59
|
|
|
57
|
-
- [x]
|
|
58
|
-
- [
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
- [
|
|
63
|
-
- [
|
|
64
|
-
- [
|
|
65
|
-
- [ ]
|
|
66
|
-
- [ ]
|
|
60
|
+
- [x] Built-in triggers
|
|
61
|
+
- [x] Custom triggers
|
|
62
|
+
|
|
63
|
+
## Other TODOs
|
|
64
|
+
|
|
65
|
+
- [x] Implement a more robust error handling system
|
|
66
|
+
- [x] Replace eprintln & println with `log_message` function
|
|
67
|
+
- [x] Implement a more comprehensive logging system
|
|
68
|
+
- [ ] Add unit tests for all core components
|
|
69
|
+
- [ ] Comment all core components
|
package/examples/exported.deva
CHANGED
package/examples/index.deva
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
@import { duration, default_bank, params, loopCount, tempo } from "./examples/exported.deva"
|
|
2
|
+
|
|
2
3
|
@load "./examples/samples/kick-808.wav" as sample
|
|
3
4
|
|
|
4
5
|
bpm tempo
|
|
@@ -6,4 +7,4 @@ bpm tempo
|
|
|
6
7
|
bank default_bank
|
|
7
8
|
|
|
8
9
|
loop loopCount:
|
|
9
|
-
.sample duration params
|
|
10
|
+
.sample duration params
|
package/out-tsc/bin/devalang.exe
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devaloop/devalang",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.1-alpha.
|
|
4
|
+
"version": "0.0.1-alpha.3",
|
|
5
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
6
|
"main": "out-tsc/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"prepublish": "cargo build --release && npm run script:postbuild",
|
|
12
|
-
"rust:dev": "cargo run",
|
|
13
12
|
"rust:dev:build": "cargo run build --entry examples --output output",
|
|
14
13
|
"rust:dev:check": "cargo run check --entry examples --output output",
|
|
15
14
|
"script:postbuild": "tsc && node out-tsc/scripts/postbuild.js",
|
|
@@ -40,4 +39,4 @@
|
|
|
40
39
|
"dependencies": {
|
|
41
40
|
"@types/node": "^24.0.3"
|
|
42
41
|
}
|
|
43
|
-
}
|
|
42
|
+
}
|
package/project-version.json
CHANGED
package/rust/cli/build.rs
CHANGED
|
@@ -1,51 +1,121 @@
|
|
|
1
|
-
use std::{ thread, time::Duration };
|
|
2
|
-
|
|
3
1
|
use crate::{
|
|
2
|
+
config::Config,
|
|
4
3
|
core::{
|
|
5
|
-
builder::
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
builder::Builder,
|
|
5
|
+
preprocessor::loader::ModuleLoader,
|
|
6
|
+
store::global::GlobalStore,
|
|
7
|
+
utils::path::{ find_entry_file, normalize_path },
|
|
8
8
|
},
|
|
9
|
-
|
|
10
|
-
utils::{ loader::with_spinner, logger::log_message, path::{ find_entry_file, normalize_path } },
|
|
9
|
+
utils::{ logger::{ LogLevel, Logger }, spinner::with_spinner, watcher::watch_directory },
|
|
11
10
|
};
|
|
11
|
+
use std::{ thread, time::Duration };
|
|
12
|
+
|
|
13
|
+
pub fn handle_build_command(
|
|
14
|
+
config: Option<Config>,
|
|
15
|
+
entry: Option<String>,
|
|
16
|
+
output: Option<String>,
|
|
17
|
+
watch: bool
|
|
18
|
+
) {
|
|
19
|
+
let fetched_entry = if entry.is_none() {
|
|
20
|
+
config
|
|
21
|
+
.as_ref()
|
|
22
|
+
.and_then(|c| c.defaults.entry.clone())
|
|
23
|
+
.unwrap_or_else(|| "".to_string())
|
|
24
|
+
} else {
|
|
25
|
+
entry.clone().unwrap_or_else(|| "".to_string())
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
let fetched_output = if output.is_none() {
|
|
29
|
+
config
|
|
30
|
+
.as_ref()
|
|
31
|
+
.and_then(|c| c.defaults.output.clone())
|
|
32
|
+
.unwrap_or_else(|| "".to_string())
|
|
33
|
+
} else {
|
|
34
|
+
output.clone().unwrap_or_else(|| "".to_string())
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
let fetched_watch = if watch {
|
|
38
|
+
watch
|
|
39
|
+
} else {
|
|
40
|
+
config
|
|
41
|
+
.as_ref()
|
|
42
|
+
.and_then(|c| c.defaults.watch)
|
|
43
|
+
.unwrap_or(false)
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
let logger = Logger::new();
|
|
12
47
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
48
|
+
if fetched_entry.is_empty() {
|
|
49
|
+
logger.log_message(
|
|
50
|
+
LogLevel::Error,
|
|
51
|
+
"Entry path is not specified. Please provide a valid entry path."
|
|
52
|
+
);
|
|
53
|
+
std::process::exit(1);
|
|
54
|
+
}
|
|
55
|
+
if fetched_output.is_empty() {
|
|
56
|
+
logger.log_message(
|
|
57
|
+
LogLevel::Error,
|
|
58
|
+
"Output directory is not specified. Please provide a valid output directory."
|
|
59
|
+
);
|
|
60
|
+
std::process::exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let entry_file = find_entry_file(&fetched_entry).unwrap_or_else(|| {
|
|
64
|
+
logger.log_message(
|
|
65
|
+
LogLevel::Error,
|
|
66
|
+
&format!("❌ index.deva not found in directory: {}", fetched_entry)
|
|
67
|
+
);
|
|
16
68
|
std::process::exit(1);
|
|
17
69
|
});
|
|
18
70
|
|
|
71
|
+
// SECTION Begin build
|
|
72
|
+
if fetched_watch {
|
|
73
|
+
begin_build(entry_file.clone(), fetched_output.clone());
|
|
74
|
+
|
|
75
|
+
logger.log_message(
|
|
76
|
+
LogLevel::Watcher,
|
|
77
|
+
&format!("Watching for changes in '{}'...", fetched_entry)
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
watch_directory(entry_file.clone(), move || {
|
|
81
|
+
logger.log_message(LogLevel::Watcher, "Detected changes, re-building...");
|
|
82
|
+
|
|
83
|
+
begin_build(entry_file.clone(), fetched_output.clone());
|
|
84
|
+
}).unwrap();
|
|
85
|
+
} else {
|
|
86
|
+
begin_build(entry_file.clone(), fetched_output.clone());
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
fn begin_build(entry: String, output: String) {
|
|
19
91
|
let spinner = with_spinner("Building...", || {
|
|
20
92
|
thread::sleep(Duration::from_millis(800));
|
|
21
93
|
});
|
|
22
94
|
|
|
23
95
|
let duration = std::time::Instant::now();
|
|
24
96
|
|
|
25
|
-
let normalized_entry_file = normalize_path(&
|
|
97
|
+
let normalized_entry_file = normalize_path(&entry);
|
|
26
98
|
let normalized_output_dir = normalize_path(&output);
|
|
27
99
|
|
|
28
|
-
let global_store =
|
|
100
|
+
let mut global_store = GlobalStore::new();
|
|
101
|
+
let module_loader = ModuleLoader::new(&normalized_entry_file, &normalized_output_dir);
|
|
29
102
|
|
|
30
|
-
|
|
31
|
-
|
|
103
|
+
// SECTION Load
|
|
104
|
+
// NOTE: We use modules in the build command, so we need to load them
|
|
105
|
+
let modules = module_loader.load_all(&mut global_store);
|
|
32
106
|
|
|
33
|
-
|
|
107
|
+
// SECTION Build
|
|
108
|
+
let builder = Builder::new();
|
|
109
|
+
builder.build_ast(&modules);
|
|
34
110
|
|
|
35
|
-
|
|
111
|
+
// TODO: Implement debugging
|
|
36
112
|
|
|
37
|
-
|
|
38
|
-
|
|
113
|
+
let success_message = format!(
|
|
114
|
+
"Build completed successfully in {:.2?}. Output files written to: '{}'",
|
|
115
|
+
duration.elapsed(),
|
|
116
|
+
normalized_output_dir
|
|
117
|
+
);
|
|
39
118
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
debugger.write_files(debug_dir.as_str(), resolved_statements);
|
|
43
|
-
|
|
44
|
-
let success_message = format!(
|
|
45
|
-
"Build completed successfully in {:.2?}. Output files written to: '{}'",
|
|
46
|
-
duration.elapsed(),
|
|
47
|
-
normalized_output_dir
|
|
48
|
-
);
|
|
49
|
-
log_message(&success_message, "SUCCESS");
|
|
50
|
-
}
|
|
119
|
+
let logger = Logger::new();
|
|
120
|
+
logger.log_message(LogLevel::Success, &success_message);
|
|
51
121
|
}
|