@devaloop/devalang 0.0.1-alpha.1 โ 0.0.1-alpha.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.
- package/.devalang +4 -0
- package/Cargo.toml +3 -2
- package/README.md +30 -6
- package/docs/CHANGELOG.md +53 -0
- package/docs/COMMANDS.md +29 -6
- package/docs/CONFIG.md +28 -0
- package/docs/ROADMAP.md +1 -1
- package/docs/TODO.md +43 -15
- package/examples/index.deva +1 -1
- package/out-tsc/bin/devalang.exe +0 -0
- package/package.json +2 -2
- package/project-version.json +3 -3
- package/rust/cli/build.rs +58 -5
- package/rust/cli/check.rs +73 -17
- package/rust/cli/init.rs +77 -0
- package/rust/cli/mod.rs +2 -1
- package/rust/cli/template.rs +56 -0
- package/rust/core/lexer/at.rs +21 -0
- package/rust/core/lexer/brace.rs +41 -0
- package/rust/core/lexer/bracket.rs +41 -0
- package/rust/core/lexer/colon.rs +21 -0
- package/rust/core/lexer/comment.rs +30 -0
- package/rust/core/lexer/dot.rs +21 -0
- package/rust/core/lexer/driver.rs +286 -0
- package/rust/core/lexer/equal.rs +32 -0
- package/rust/core/lexer/identifier.rs +38 -0
- package/rust/core/lexer/indent.rs +47 -0
- package/rust/core/lexer/mod.rs +14 -333
- package/rust/core/lexer/newline.rs +23 -0
- package/rust/core/lexer/number.rs +31 -0
- package/rust/core/lexer/quote.rs +61 -0
- package/rust/core/parser/dot.rs +48 -18
- package/rust/core/preprocessor/module.rs +1 -1
- package/rust/core/types/cli.rs +53 -31
- package/rust/core/types/config.rs +15 -0
- package/rust/core/types/mod.rs +2 -1
- package/rust/main.rs +30 -19
- package/rust/utils/config.rs +13 -0
- package/rust/utils/file.rs +35 -0
- package/rust/utils/mod.rs +4 -1
- 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/cli/new.rs +0 -1
package/rust/core/types/cli.rs
CHANGED
|
@@ -7,6 +7,10 @@ use crate::utils::version::get_version;
|
|
|
7
7
|
#[command(version = get_version())]
|
|
8
8
|
#[command(about = "๐ฆ Devalang โ A programming language for music and sound.")]
|
|
9
9
|
pub struct Cli {
|
|
10
|
+
#[arg(long, global = true)]
|
|
11
|
+
/// Skips loading the configuration file.
|
|
12
|
+
pub no_config: bool,
|
|
13
|
+
|
|
10
14
|
#[command(subcommand)]
|
|
11
15
|
pub command: CliCommands,
|
|
12
16
|
}
|
|
@@ -34,6 +38,36 @@ pub enum CompilationMode {
|
|
|
34
38
|
|
|
35
39
|
#[derive(Subcommand)]
|
|
36
40
|
pub enum CliCommands {
|
|
41
|
+
/// Create a new Devalang project.
|
|
42
|
+
///
|
|
43
|
+
/// ### Arguments
|
|
44
|
+
/// - `name` - The name of the project to create.
|
|
45
|
+
/// - `template` - The template to use for the project. Defaults to "default".
|
|
46
|
+
///
|
|
47
|
+
/// ### Example
|
|
48
|
+
/// ```bash
|
|
49
|
+
/// devalang init --name my_project --template default
|
|
50
|
+
///
|
|
51
|
+
Init {
|
|
52
|
+
#[arg(short, long)]
|
|
53
|
+
/// The optional name (directory) of the project to create.
|
|
54
|
+
name: Option<String>,
|
|
55
|
+
|
|
56
|
+
#[arg(short, long)]
|
|
57
|
+
/// The template to use for the project.
|
|
58
|
+
///
|
|
59
|
+
/// ### Default value
|
|
60
|
+
/// - `default`
|
|
61
|
+
///
|
|
62
|
+
template: Option<String>,
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
Template {
|
|
66
|
+
#[command(subcommand)]
|
|
67
|
+
/// The template command to execute.
|
|
68
|
+
command: CliTemplateCommand,
|
|
69
|
+
},
|
|
70
|
+
|
|
37
71
|
/// Build the program and generate output files.
|
|
38
72
|
///
|
|
39
73
|
/// ### Arguments
|
|
@@ -47,29 +81,23 @@ pub enum CliCommands {
|
|
|
47
81
|
/// ```
|
|
48
82
|
///
|
|
49
83
|
Build {
|
|
50
|
-
#[arg(short, long
|
|
84
|
+
#[arg(short, long)]
|
|
51
85
|
/// The entry point of the program to build.
|
|
52
86
|
///
|
|
53
|
-
|
|
54
|
-
/// - `./src`
|
|
55
|
-
///
|
|
56
|
-
entry: String,
|
|
87
|
+
entry: Option<String>,
|
|
57
88
|
|
|
58
|
-
#[arg(short, long
|
|
89
|
+
#[arg(short, long)]
|
|
59
90
|
/// The directory where the output files will be generated.
|
|
60
91
|
///
|
|
61
|
-
|
|
62
|
-
/// - `./output`
|
|
63
|
-
///
|
|
64
|
-
output: String,
|
|
92
|
+
output: Option<String>,
|
|
65
93
|
|
|
66
|
-
#[arg(
|
|
94
|
+
#[arg(long, default_value_t = false)]
|
|
67
95
|
/// Whether to watch for changes and rebuild.
|
|
68
96
|
///
|
|
69
97
|
/// ### Default value
|
|
70
|
-
/// - `
|
|
98
|
+
/// - `false`
|
|
71
99
|
///
|
|
72
|
-
watch:
|
|
100
|
+
watch: bool,
|
|
73
101
|
|
|
74
102
|
#[arg(long, default_value = "real-time")]
|
|
75
103
|
/// The mode of compilation.
|
|
@@ -84,21 +112,21 @@ pub enum CliCommands {
|
|
|
84
112
|
///
|
|
85
113
|
compilation_mode: String,
|
|
86
114
|
|
|
87
|
-
#[arg(short, long,
|
|
115
|
+
#[arg(short, long, default_value_t = false)]
|
|
88
116
|
/// Whether to print debug information.
|
|
89
117
|
///
|
|
90
118
|
/// ### Default value
|
|
91
119
|
/// - `false`
|
|
92
120
|
///
|
|
93
|
-
debug:
|
|
121
|
+
debug: bool,
|
|
94
122
|
|
|
95
|
-
#[arg(short, long,
|
|
123
|
+
#[arg(short, long, default_value_t = false)]
|
|
96
124
|
/// Whether to compress the output files.
|
|
97
125
|
///
|
|
98
126
|
/// ### Default value
|
|
99
127
|
/// - `false`
|
|
100
128
|
///
|
|
101
|
-
compress:
|
|
129
|
+
compress: bool,
|
|
102
130
|
},
|
|
103
131
|
|
|
104
132
|
/// Analyze the program for errors and warnings.
|
|
@@ -112,29 +140,23 @@ pub enum CliCommands {
|
|
|
112
140
|
/// devalang check --entry ./src --watch true --compilation-mode real-time
|
|
113
141
|
/// ```
|
|
114
142
|
Check {
|
|
115
|
-
#[arg(short, long
|
|
143
|
+
#[arg(short, long)]
|
|
116
144
|
/// The entry point of the program to analyze.
|
|
117
145
|
///
|
|
118
|
-
|
|
119
|
-
/// - `./src`
|
|
120
|
-
///
|
|
121
|
-
entry: String,
|
|
146
|
+
entry: Option<String>,
|
|
122
147
|
|
|
123
|
-
#[arg(short, long
|
|
148
|
+
#[arg(short, long)]
|
|
124
149
|
/// The directory where the output files will be generated.
|
|
125
150
|
///
|
|
126
|
-
|
|
127
|
-
/// - `./output`
|
|
128
|
-
///
|
|
129
|
-
output: String,
|
|
151
|
+
output: Option<String>,
|
|
130
152
|
|
|
131
|
-
#[arg(
|
|
153
|
+
#[arg(long, default_value_t = false)]
|
|
132
154
|
/// Whether to watch for changes and re-analyze.
|
|
133
155
|
///
|
|
134
156
|
/// ### Default value
|
|
135
157
|
/// - `false`
|
|
136
158
|
///
|
|
137
|
-
watch:
|
|
159
|
+
watch: bool,
|
|
138
160
|
|
|
139
161
|
#[arg(short, long, default_value = "real-time")]
|
|
140
162
|
/// The mode of compilation.
|
|
@@ -149,12 +171,12 @@ pub enum CliCommands {
|
|
|
149
171
|
///
|
|
150
172
|
compilation_mode: String,
|
|
151
173
|
|
|
152
|
-
#[arg(short, long,
|
|
174
|
+
#[arg(short, long, default_value_t = false)]
|
|
153
175
|
/// Whether to print debug information.
|
|
154
176
|
///
|
|
155
177
|
/// ### Default value
|
|
156
178
|
/// - `false`
|
|
157
179
|
///
|
|
158
|
-
debug:
|
|
180
|
+
debug: bool,
|
|
159
181
|
},
|
|
160
182
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
use serde::Deserialize;
|
|
2
|
+
|
|
3
|
+
#[derive(Debug, Deserialize)]
|
|
4
|
+
pub struct DevalangConfig {
|
|
5
|
+
pub defaults: Defaults,
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
#[derive(Debug, Deserialize)]
|
|
9
|
+
pub struct Defaults {
|
|
10
|
+
pub entry: Option<String>,
|
|
11
|
+
|
|
12
|
+
pub output: Option<String>,
|
|
13
|
+
|
|
14
|
+
pub watch: Option<bool>,
|
|
15
|
+
}
|
package/rust/core/types/mod.rs
CHANGED
package/rust/main.rs
CHANGED
|
@@ -7,36 +7,47 @@ pub mod utils;
|
|
|
7
7
|
use std::{ io };
|
|
8
8
|
use clap::Parser;
|
|
9
9
|
use crate::{
|
|
10
|
-
cli::{
|
|
11
|
-
|
|
10
|
+
cli::{
|
|
11
|
+
build::handle_build_command,
|
|
12
|
+
check::handle_check_command,
|
|
13
|
+
init::handle_init_command,
|
|
14
|
+
template::{ handle_template_info_command, handle_template_list_command },
|
|
15
|
+
},
|
|
16
|
+
core::types::{ cli::{ Cli, CliCommands, CliTemplateCommand }, config::DevalangConfig },
|
|
17
|
+
utils::{ config::load_config, logger::log_message },
|
|
12
18
|
};
|
|
13
19
|
|
|
14
20
|
fn main() -> io::Result<()> {
|
|
15
|
-
let cli = Cli::parse();
|
|
21
|
+
let cli: Cli = Cli::parse();
|
|
22
|
+
let mut config: Option<DevalangConfig> = None;
|
|
23
|
+
|
|
24
|
+
if !cli.no_config {
|
|
25
|
+
config = load_config(None);
|
|
26
|
+
} else {
|
|
27
|
+
log_message("Configuration file loading is skipped.", "WARNING");
|
|
28
|
+
}
|
|
16
29
|
|
|
17
30
|
match cli.command {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// }
|
|
31
|
+
CliCommands::Init { name, template } => {
|
|
32
|
+
handle_init_command(name, template);
|
|
33
|
+
}
|
|
22
34
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// }
|
|
35
|
+
CliCommands::Template { command } =>
|
|
36
|
+
match command {
|
|
37
|
+
CliTemplateCommand::List => {
|
|
38
|
+
handle_template_list_command();
|
|
39
|
+
}
|
|
40
|
+
CliTemplateCommand::Info { name } => {
|
|
41
|
+
handle_template_info_command(name);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
33
44
|
|
|
34
45
|
CliCommands::Build { entry, output, watch, compilation_mode, debug, compress } => {
|
|
35
|
-
handle_build_command(entry, output);
|
|
46
|
+
handle_build_command(config, entry, output, watch);
|
|
36
47
|
}
|
|
37
48
|
|
|
38
49
|
CliCommands::Check { entry, output, watch, compilation_mode, debug } => {
|
|
39
|
-
handle_check_command(entry, output);
|
|
50
|
+
handle_check_command(config, entry, output, watch);
|
|
40
51
|
}
|
|
41
52
|
|
|
42
53
|
// TODO - Implement the play command
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
use std::{ fs, path::Path };
|
|
2
|
+
use crate::core::types::config::DevalangConfig;
|
|
3
|
+
|
|
4
|
+
pub fn load_config(path: Option<&Path>) -> Option<DevalangConfig> {
|
|
5
|
+
let config_path = path.unwrap_or_else(|| Path::new(".devalang"));
|
|
6
|
+
|
|
7
|
+
if config_path.exists() {
|
|
8
|
+
let content = fs::read_to_string(config_path).ok()?;
|
|
9
|
+
toml::from_str(&content).ok()
|
|
10
|
+
} else {
|
|
11
|
+
None
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
use std::{ fs::{ self }, path::Path };
|
|
2
|
+
use include_dir::{ Dir, DirEntry };
|
|
3
|
+
|
|
4
|
+
pub fn copy_dir_recursive(dir: &Dir, target_root: &Path, base_path: &Path) {
|
|
5
|
+
for entry in dir.entries() {
|
|
6
|
+
match entry {
|
|
7
|
+
DirEntry::Dir(subdir) => {
|
|
8
|
+
copy_dir_recursive(subdir, target_root, base_path);
|
|
9
|
+
}
|
|
10
|
+
DirEntry::File(file) => {
|
|
11
|
+
let rel_path = file.path().strip_prefix(base_path).unwrap();
|
|
12
|
+
let dest_path = target_root.join(rel_path);
|
|
13
|
+
|
|
14
|
+
if let Some(parent) = dest_path.parent() {
|
|
15
|
+
fs::create_dir_all(parent).unwrap();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
fs::write(&dest_path, file.contents()).expect("Error writing file");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
pub fn format_file_size(bytes: u64) -> String {
|
|
25
|
+
const KB: u64 = 1024;
|
|
26
|
+
const MB: u64 = 1024 * 1024;
|
|
27
|
+
|
|
28
|
+
if bytes >= MB {
|
|
29
|
+
format!("{:.2} Mb", (bytes as f64) / (MB as f64))
|
|
30
|
+
} else if bytes >= KB {
|
|
31
|
+
format!("{:.2} Kb", (bytes as f64) / (KB as f64))
|
|
32
|
+
} else {
|
|
33
|
+
format!("{} bytes", bytes)
|
|
34
|
+
}
|
|
35
|
+
}
|
package/rust/utils/mod.rs
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
use notify::{ Watcher, RecursiveMode, Config, RecommendedWatcher };
|
|
2
|
+
use std::sync::mpsc::channel;
|
|
3
|
+
|
|
4
|
+
pub fn watch_directory<F>(entry: String, callback: F) -> notify::Result<()>
|
|
5
|
+
where F: Fn() + Send + 'static
|
|
6
|
+
{
|
|
7
|
+
let (tx, rx) = channel();
|
|
8
|
+
|
|
9
|
+
let mut watcher: RecommendedWatcher = Watcher::new(tx, Config::default())?;
|
|
10
|
+
watcher.watch(&entry.as_ref(), RecursiveMode::Recursive)?;
|
|
11
|
+
|
|
12
|
+
loop {
|
|
13
|
+
match rx.recv() {
|
|
14
|
+
Ok(_) => {
|
|
15
|
+
callback();
|
|
16
|
+
}
|
|
17
|
+
Err(e) => {
|
|
18
|
+
eprintln!("Channel error : {:?}", e);
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
Ok(())
|
|
25
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
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
|
+
- ๐๏ธ Watch mode for `build` and `check` commands
|
|
45
|
+
- โฑ๏ธ `bpm` assignment for setting tempo
|
|
46
|
+
- ๐งฑ `bank` declaration to define the instrument set
|
|
47
|
+
- ๐ Looping system with fixed repetitions (`loop 4:`)
|
|
48
|
+
- ๐งช Instruction calls with parameters (e.g. `.kick auto {reverb:10, decay:20}`) for testing pattern syntax
|
|
49
|
+
- ๐ `let` assignments for storing reusable values
|
|
50
|
+
- ๐ `@load` assignment to load a sample (.mp3, .wav) to use it as a value
|
|
51
|
+
- ๐ ๏ธ CLI tools for syntax checking (`check`), AST output (`build`)
|
|
52
|
+
|
|
53
|
+
## ๐ Installation
|
|
54
|
+
|
|
55
|
+
### For users
|
|
56
|
+
|
|
57
|
+
> - โ ๏ธ Requires [Node.js 18+](https://nodejs.org/en/download)
|
|
58
|
+
|
|
59
|
+
Install the package globally (NPM)
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install -g @devaloop/devalang
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Usage without install (NPX)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx @devaloop/devalang <command>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### For contributors
|
|
72
|
+
|
|
73
|
+
> - โ ๏ธ Requires [Node.js 18+](https://nodejs.org/en/download)
|
|
74
|
+
> - โ ๏ธ Requires [Rust 1.70+](https://www.rust-lang.org/learn/get-started#installing-rust)
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
> git clone https://github.com/devaloop-labs/devalang.git
|
|
78
|
+
> cd devalang
|
|
79
|
+
> npm install
|
|
80
|
+
> cargo install --path .
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Usage for development (feel free to change arguments in package.json)
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# For syntax checking test
|
|
87
|
+
npm run rust:dev <command>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## โ Usage
|
|
91
|
+
|
|
92
|
+
For more examples, see [docs/COMMANDS.md](./docs/COMMANDS.md)
|
|
93
|
+
|
|
94
|
+
### Initialize a new project
|
|
95
|
+
|
|
96
|
+
In the current directory
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
devalang init
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Or use optional arguments to specify a directory name and a template
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
devalang init --name <project-name> --template <template-name>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Checking syntax only and output debug files
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
devalang check --entry <entry-directory> --output <output-directory> --watch
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Building output file(s) (AST generation for the moment)
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
devalang build --entry <entry-directory> --output <output-directory> --watch
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## โ๏ธ Configuration
|
|
121
|
+
|
|
122
|
+
You can use a configuration file to set default values for various settings, making it easier to manage your Devalang project.
|
|
123
|
+
|
|
124
|
+
To do this, create a `.devalang` file in the root of your project directory.
|
|
125
|
+
|
|
126
|
+
See [docs/CONFIG.md](./docs/CONFIG.md) for more information.
|
|
127
|
+
|
|
128
|
+
## ๐ Syntax example
|
|
129
|
+
|
|
130
|
+
For more examples, see [docs/SYNTAX.md](./docs/SYNTAX.md)
|
|
131
|
+
|
|
132
|
+
```deva
|
|
133
|
+
# index.deva
|
|
134
|
+
|
|
135
|
+
@import { globalBpm, globalBank, kickDuration } from "global.deva"
|
|
136
|
+
|
|
137
|
+
bpm globalBpm
|
|
138
|
+
# Will declare the tempo at the globalBpm variable beats per minute
|
|
139
|
+
|
|
140
|
+
bank globalBank
|
|
141
|
+
# Will declare a custom instrument bank using the globalBank variable
|
|
142
|
+
|
|
143
|
+
loop 5:
|
|
144
|
+
.kick kickDuration {reverb=50, drive=25}
|
|
145
|
+
# Will play 5 times a kick for the duration of the kickDuration variable with reverb and drive effects
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```deva
|
|
149
|
+
# global.deva
|
|
150
|
+
|
|
151
|
+
let globalBpm = 120
|
|
152
|
+
let globalBank = 808
|
|
153
|
+
let kickDuration = 500
|
|
154
|
+
|
|
155
|
+
@export { globalBpm, globalBank, kickDuration }
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## ๐งฏ Known issues
|
|
159
|
+
|
|
160
|
+
- No support yet for Audio Engine
|
|
161
|
+
- No support yet for `if`, `else`, `else if` statements
|
|
162
|
+
- No support yet for `@group`, `@pattern`, `@function` statements
|
|
163
|
+
- Nested loops and conditions may not be fully tested
|
|
164
|
+
|
|
165
|
+
## ๐งช Roadmap Highlights
|
|
166
|
+
|
|
167
|
+
For more info, see [docs/ROADMAP.md](./docs/ROADMAP.md)
|
|
168
|
+
|
|
169
|
+
- โณ Audio engine integration
|
|
170
|
+
- โณ Other statements (e.g `if`, `@group`, ...)
|
|
171
|
+
- โณ Cross-platform support (Linux, macOS)
|
|
172
|
+
- โณ More built-in instruments (e.g. snare, hi-hat, etc.)
|
|
173
|
+
|
|
174
|
+
## ๐ก๏ธ License
|
|
175
|
+
|
|
176
|
+
MIT โ see [LICENSE](./LICENSE)
|
|
177
|
+
|
|
178
|
+
## ๐ค Contributing
|
|
179
|
+
|
|
180
|
+
Contributions, bug reports and suggestions are welcome !
|
|
181
|
+
Feel free to open an issue or submit a pull request.
|
|
182
|
+
|
|
183
|
+
## ๐ข Contact
|
|
184
|
+
|
|
185
|
+
๐ง [contact@devaloop.com](mailto:contact@devaloop.com)
|
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# ๐ฆ Welcome to Devalang !
|
|
2
|
+
# This is your first Devalang program ?
|
|
3
|
+
# Let's start with a simple example that plays a sample in a loop.
|
|
4
|
+
|
|
5
|
+
@import { bpmVar, bankVar, loopVar } from './variables.deva'
|
|
6
|
+
@load "../samples/kick-808.wav" as sample
|
|
7
|
+
|
|
8
|
+
bpm bpmVar
|
|
9
|
+
|
|
10
|
+
bank bankVar
|
|
11
|
+
|
|
12
|
+
loop loopVar:
|
|
13
|
+
.sample auto
|
package/rust/cli/new.rs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// TODO Implement the new command to create a new project with a template
|