@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.
Files changed (105) hide show
  1. package/.devalang +4 -0
  2. package/Cargo.toml +46 -45
  3. package/README.md +35 -10
  4. package/docs/CHANGELOG.md +58 -0
  5. package/docs/COMMANDS.md +29 -6
  6. package/docs/CONFIG.md +28 -0
  7. package/docs/ROADMAP.md +6 -2
  8. package/docs/TODO.md +21 -18
  9. package/examples/exported.deva +1 -1
  10. package/examples/index.deva +2 -1
  11. package/out-tsc/bin/devalang.exe +0 -0
  12. package/package.json +2 -3
  13. package/project-version.json +4 -4
  14. package/rust/cli/build.rs +99 -29
  15. package/rust/cli/check.rs +95 -103
  16. package/rust/cli/init.rs +77 -0
  17. package/rust/cli/mod.rs +174 -1
  18. package/rust/cli/template.rs +56 -0
  19. package/rust/config/loader.rs +14 -0
  20. package/rust/config/mod.rs +15 -0
  21. package/rust/core/builder/mod.rs +21 -27
  22. package/rust/core/debugger/lexer.rs +12 -0
  23. package/rust/core/debugger/mod.rs +12 -49
  24. package/rust/core/debugger/preprocessor.rs +23 -0
  25. package/rust/core/error/mod.rs +60 -0
  26. package/rust/core/lexer/handler/at.rs +21 -0
  27. package/rust/core/lexer/handler/brace.rs +41 -0
  28. package/rust/core/lexer/handler/colon.rs +21 -0
  29. package/rust/core/lexer/handler/comment.rs +30 -0
  30. package/rust/core/lexer/handler/dot.rs +21 -0
  31. package/rust/core/lexer/handler/equal.rs +32 -0
  32. package/rust/core/lexer/handler/identifier.rs +38 -0
  33. package/rust/core/lexer/handler/indent.rs +52 -0
  34. package/rust/core/lexer/handler/mod.rs +238 -0
  35. package/rust/core/lexer/handler/newline.rs +19 -0
  36. package/rust/core/lexer/handler/number.rs +31 -0
  37. package/rust/core/lexer/handler/string.rs +66 -0
  38. package/rust/core/lexer/mod.rs +16 -324
  39. package/rust/core/lexer/token.rs +55 -0
  40. package/rust/core/mod.rs +5 -2
  41. package/rust/core/parser/handler/at.rs +166 -0
  42. package/rust/core/parser/handler/bank.rs +38 -0
  43. package/rust/core/parser/handler/dot.rs +112 -0
  44. package/rust/core/parser/handler/identifier.rs +134 -0
  45. package/rust/core/parser/handler/loop_.rs +55 -0
  46. package/rust/core/parser/handler/mod.rs +6 -0
  47. package/rust/core/parser/handler/tempo.rs +47 -0
  48. package/rust/core/parser/mod.rs +204 -166
  49. package/rust/core/parser/statement.rs +91 -0
  50. package/rust/core/preprocessor/loader.rs +105 -0
  51. package/rust/core/preprocessor/mod.rs +2 -24
  52. package/rust/core/preprocessor/module.rs +37 -56
  53. package/rust/core/preprocessor/processor.rs +41 -0
  54. package/rust/core/preprocessor/resolver.rs +372 -0
  55. package/rust/core/shared/duration.rs +8 -0
  56. package/rust/core/shared/mod.rs +2 -0
  57. package/rust/core/shared/value.rs +18 -0
  58. package/rust/core/store/export.rs +28 -0
  59. package/rust/core/store/global.rs +39 -0
  60. package/rust/core/store/import.rs +28 -0
  61. package/rust/core/store/mod.rs +4 -0
  62. package/rust/core/store/variable.rs +28 -0
  63. package/rust/core/utils/mod.rs +2 -0
  64. package/rust/core/utils/validation.rs +35 -0
  65. package/rust/lib.rs +0 -1
  66. package/rust/main.rs +39 -30
  67. package/rust/utils/file.rs +35 -0
  68. package/rust/utils/logger.rs +69 -34
  69. package/rust/utils/mod.rs +3 -2
  70. package/rust/utils/watcher.rs +25 -0
  71. package/templates/minimal/.devalang +4 -0
  72. package/templates/minimal/src/index.deva +2 -0
  73. package/templates/welcome/.devalang +4 -0
  74. package/templates/welcome/README.md +185 -0
  75. package/templates/welcome/samples/kick-808.wav +0 -0
  76. package/templates/welcome/src/index.deva +13 -0
  77. package/templates/welcome/src/variables.deva +5 -0
  78. package/rust/audio/mod.rs +0 -1
  79. package/rust/cli/new.rs +0 -1
  80. package/rust/core/parser/at.rs +0 -142
  81. package/rust/core/parser/bank.rs +0 -42
  82. package/rust/core/parser/dot.rs +0 -107
  83. package/rust/core/parser/identifer.rs +0 -91
  84. package/rust/core/parser/loop_.rs +0 -62
  85. package/rust/core/parser/tempo.rs +0 -42
  86. package/rust/core/parser/variable.rs +0 -129
  87. package/rust/core/preprocessor/dependencies.rs +0 -54
  88. package/rust/core/preprocessor/resolver/at.rs +0 -24
  89. package/rust/core/preprocessor/resolver/bank.rs +0 -59
  90. package/rust/core/preprocessor/resolver/loop_.rs +0 -82
  91. package/rust/core/preprocessor/resolver/mod.rs +0 -113
  92. package/rust/core/preprocessor/resolver/tempo.rs +0 -70
  93. package/rust/core/preprocessor/resolver/trigger.rs +0 -176
  94. package/rust/core/types/cli.rs +0 -160
  95. package/rust/core/types/mod.rs +0 -7
  96. package/rust/core/types/module.rs +0 -41
  97. package/rust/core/types/parser.rs +0 -73
  98. package/rust/core/types/statement.rs +0 -105
  99. package/rust/core/types/store.rs +0 -116
  100. package/rust/core/types/token.rs +0 -83
  101. package/rust/core/types/variable.rs +0 -32
  102. package/rust/runner/executer.rs +0 -44
  103. package/rust/runner/mod.rs +0 -1
  104. /package/rust/{utils → core/utils}/path.rs +0 -0
  105. /package/rust/utils/{loader.rs → spinner.rs} +0 -0
@@ -0,0 +1,2 @@
1
+ pub mod path;
2
+ pub mod validation;
@@ -0,0 +1,35 @@
1
+ use crate::core::{ preprocessor::module::Module, shared::value::Value, store::global::GlobalStore };
2
+
3
+ pub fn is_valid_entity(entity: &str, module: &Module, global_store: &GlobalStore) -> bool {
4
+ let built_ins = ["kick", "snare", "hat", "clap"];
5
+
6
+ if built_ins.contains(&entity) {
7
+ return true;
8
+ }
9
+
10
+ if let Some(val) = module.variable_table.get(entity) {
11
+ match val {
12
+ Value::Sample(_) => true,
13
+ _ => false,
14
+ }
15
+ } else {
16
+ false
17
+ }
18
+ }
19
+
20
+ pub fn is_valid_identifier(ident: &str, module: &Module) -> bool {
21
+ let built_ins = ["auto"];
22
+
23
+ if built_ins.contains(&ident) {
24
+ return true;
25
+ }
26
+
27
+ if let Some(val) = module.variable_table.get(ident) {
28
+ match val {
29
+ Value::Identifier(_) => true,
30
+ _ => false,
31
+ }
32
+ } else {
33
+ false
34
+ }
35
+ }
package/rust/lib.rs CHANGED
@@ -1 +0,0 @@
1
- // TODO WebAssembly support
package/rust/main.rs CHANGED
@@ -1,48 +1,57 @@
1
1
  pub mod core;
2
2
  pub mod cli;
3
- pub mod runner;
4
- pub mod audio;
5
3
  pub mod utils;
4
+ pub mod config;
6
5
 
7
- use std::{ io };
6
+ use std::io;
7
+ use cli::{ Cli };
8
8
  use clap::Parser;
9
9
  use crate::{
10
- cli::{ build::handle_build_command, check::handle_check_command },
11
- core::types::cli::{ Cli, CliCommands },
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
+ Commands,
16
+ TemplateCommand,
17
+ },
18
+ config::{ loader::load_config, Config },
12
19
  };
13
20
 
14
21
  fn main() -> io::Result<()> {
15
- let cli = Cli::parse();
22
+ let cli: Cli = Cli::parse();
23
+ let mut config: Option<Config> = None;
24
+
25
+ if !cli.no_config {
26
+ config = load_config(None);
27
+ } else {
28
+ println!("No configuration file loaded. Running with arguments only.");
29
+ }
16
30
 
17
31
  match cli.command {
18
- // TODO - Implement the new command
19
- // CliCommands::New { name, template } => {
20
- // log_message("Command 'new project' is not implemented yet.", "WARNING");
21
- // }
22
-
23
- // TODO - Implement the template command
24
- // CliCommands::Template { command } =>
25
- // match command {
26
- // CliTemplateCommand::List => {
27
- // log_message("Command 'template list' is not implemented yet.", "WARNING");
28
- // }
29
- // CliTemplateCommand::Info { name } => {
30
- // log_message("Command 'template info' is not implemented yet.", "WARNING");
31
- // }
32
- // }
33
-
34
- CliCommands::Build { entry, output, watch, compilation_mode, debug, compress } => {
35
- handle_build_command(entry, output);
32
+ Commands::Init { name, template } => {
33
+ handle_init_command(name, template);
34
+ }
35
+
36
+ Commands::Template { command } =>
37
+ match command {
38
+ TemplateCommand::List => {
39
+ handle_template_list_command();
40
+ }
41
+ TemplateCommand::Info { name } => {
42
+ handle_template_info_command(name);
43
+ }
44
+ }
45
+
46
+ Commands::Check { entry, output, watch, compilation_mode, debug } => {
47
+ handle_check_command(config, entry, output, watch);
36
48
  }
37
49
 
38
- CliCommands::Check { entry, output, watch, compilation_mode, debug } => {
39
- handle_check_command(entry, output);
50
+ Commands::Build { entry, output, watch, compilation_mode, debug, compress } => {
51
+ handle_build_command(config, entry, output, watch);
40
52
  }
41
53
 
42
- // TODO - Implement the play command
43
- // CliCommands::Play {} => {
44
- // log_message("Command 'play' is not implemented yet.", "WARNING");
45
- // }
54
+ _ => {}
46
55
  }
47
56
 
48
57
  Ok(())
@@ -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
+ }
@@ -1,49 +1,84 @@
1
- use crossterm::style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor};
1
+ use crossterm::style::{ Attribute, Color, ResetColor, SetAttribute, SetForegroundColor };
2
2
  use std::{ fmt::Write };
3
3
 
4
- pub fn log_message(message: &str, status: &str) {
5
- let formatted_status = format_status(status);
6
- println!("🦊 {} {} {}", language_signature(), formatted_status, message);
4
+ #[derive(Debug, Clone, PartialEq)]
5
+ pub enum LogLevel {
6
+ Success,
7
+ Error,
8
+ Info,
9
+ Warning,
10
+ Watcher,
11
+ Debug,
7
12
  }
8
13
 
9
- fn language_signature() -> String {
10
- let mut s = String::new();
14
+ #[derive(Debug, Clone)]
15
+ pub struct Logger {}
11
16
 
12
- write!(&mut s, "{}", SetForegroundColor(Color::Grey)).unwrap();
13
- s.push('[');
17
+ impl Logger {
18
+ pub fn new() -> Self {
19
+ Logger {}
20
+ }
14
21
 
15
- write!(&mut s, "{}", SetForegroundColor(Color::Rgb { r: 29, g: 211, b: 176 })).unwrap();
16
- write!(&mut s, "{}", SetAttribute(Attribute::Bold)).unwrap();
17
- s.push_str("Devalang");
18
- write!(&mut s, "{}", SetAttribute(Attribute::Reset)).unwrap();
22
+ pub fn log_message(&self, level: LogLevel, message: &str) {
23
+ let formatted_status = self.format_status(level);
24
+ println!("🦊 {} {} {}", self.language_signature(), formatted_status, message);
25
+ }
19
26
 
20
- write!(&mut s, "{}", SetForegroundColor(Color::Grey)).unwrap();
21
- s.push(']');
27
+ pub fn log_error_with_stacktrace(&self, message: &str, stacktrace: &str) {
28
+ let formatted_status = self.format_status(LogLevel::Error);
29
+ println!("🦊 {} {} {}", self.language_signature(), formatted_status, message);
30
+ println!(" ↳ {}", stacktrace);
31
+ }
22
32
 
23
- write!(&mut s, "{}", ResetColor).unwrap();
33
+ fn language_signature(&self) -> String {
34
+ let mut s = String::new();
24
35
 
25
- s
26
- }
36
+ write!(&mut s, "{}", SetForegroundColor(Color::Grey)).unwrap();
37
+ s.push('[');
38
+
39
+ write!(&mut s, "{}", SetForegroundColor(Color::Rgb { r: 29, g: 211, b: 176 })).unwrap();
40
+ write!(&mut s, "{}", SetAttribute(Attribute::Bold)).unwrap();
41
+ s.push_str("Devalang");
42
+ write!(&mut s, "{}", SetAttribute(Attribute::Reset)).unwrap();
43
+
44
+ write!(&mut s, "{}", SetForegroundColor(Color::Grey)).unwrap();
45
+ s.push(']');
46
+
47
+ write!(&mut s, "{}", ResetColor).unwrap();
48
+
49
+ s
50
+ }
51
+
52
+ fn format_status(&self, level: LogLevel) -> String {
53
+ let mut s = String::new();
27
54
 
28
- fn format_status(status: &str) -> String {
29
- let mut s = String::new();
55
+ let color = match level {
56
+ LogLevel::Success => Color::Rgb { r: 76, g: 175, b: 80 },
57
+ LogLevel::Error => Color::Rgb { r: 244, g: 67, b: 54 },
58
+ LogLevel::Info => Color::Rgb { r: 33, g: 150, b: 243 },
59
+ LogLevel::Warning => Color::Rgb { r: 255, g: 152, b: 0 },
60
+ LogLevel::Watcher => Color::Rgb { r: 156, g: 39, b: 176 },
61
+ LogLevel::Debug => Color::Rgb { r: 103, g: 58, b: 183 },
62
+ };
30
63
 
31
- let color = match status {
32
- "SUCCESS" => Color::Rgb { r: 76, g: 175, b: 80 },
33
- "ERROR" => Color::Rgb { r: 244, g: 67, b: 54 },
34
- "INFO" => Color::Rgb { r: 33, g: 150, b: 243 },
35
- "WARNING" => Color::Rgb { r: 255, g: 152, b: 0 },
36
- _ => Color::Grey,
37
- };
64
+ let status = match level {
65
+ LogLevel::Success => "SUCCESS",
66
+ LogLevel::Error => "ERROR",
67
+ LogLevel::Info => "INFO",
68
+ LogLevel::Warning => "WARNING",
69
+ LogLevel::Watcher => "WATCHER",
70
+ LogLevel::Debug => "DEBUG",
71
+ };
38
72
 
39
- s.push('[');
40
- write!(&mut s, "{}", SetForegroundColor(color)).unwrap();
41
- write!(&mut s, "{}", SetAttribute(Attribute::Bold)).unwrap();
42
- s.push_str(status);
43
- write!(&mut s, "{}", SetAttribute(Attribute::Reset)).unwrap();
44
- s.push(']');
73
+ s.push('[');
74
+ write!(&mut s, "{}", SetForegroundColor(color)).unwrap();
75
+ write!(&mut s, "{}", SetAttribute(Attribute::Bold)).unwrap();
76
+ s.push_str(status);
77
+ write!(&mut s, "{}", SetAttribute(Attribute::Reset)).unwrap();
78
+ s.push(']');
45
79
 
46
- write!(&mut s, "{}", ResetColor).unwrap();
80
+ write!(&mut s, "{}", ResetColor).unwrap();
47
81
 
48
- s
82
+ s
83
+ }
49
84
  }
package/rust/utils/mod.rs CHANGED
@@ -1,5 +1,6 @@
1
1
  pub mod version;
2
2
  pub mod signature;
3
- pub mod path;
4
- pub mod loader;
3
+ pub mod spinner;
4
+ pub mod watcher;
5
+ pub mod file;
5
6
  pub mod logger;
@@ -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,4 @@
1
+ [defaults]
2
+ entry = "./src"
3
+ output = "./output"
4
+ watch = false
@@ -0,0 +1,2 @@
1
+ # Write your Devalang code here
2
+ # ...
@@ -0,0 +1,4 @@
1
+ [defaults]
2
+ entry = "./src"
3
+ output = "./output"
4
+ watch = false
@@ -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
+ ![Rust](https://img.shields.io/badge/Made%20with-Rust-orange?logo=rust)
6
+ ![TypeScript](https://img.shields.io/badge/Built%20with-TypeScript-blue?logo=typescript)
7
+ ![Node.js](https://img.shields.io/badge/Node.js-18%2B-brightgreen?logo=node.js)
8
+
9
+ ![Project Status](https://img.shields.io/badge/status-alpha-red)
10
+ ![Version](https://img.shields.io/badge/version-0.0.1-blue)
11
+ ![License: MIT](https://img.shields.io/badge/license-MIT-green)
12
+ ![Platform](https://img.shields.io/badge/platform-Windows-blue)
13
+
14
+ ![npm](https://img.shields.io/npm/dm/@devaloop/devalang)
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)
@@ -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
@@ -0,0 +1,5 @@
1
+ let bpmVar = 120
2
+ let bankVar = 808
3
+ let loopVar = 10
4
+
5
+ @export { bpmVar, bankVar, loopVar }
package/rust/audio/mod.rs DELETED
@@ -1 +0,0 @@
1
- // TODO Audio engine
package/rust/cli/new.rs DELETED
@@ -1 +0,0 @@
1
- // TODO Implement the new command to create a new project with a template