@devaloop/devalang 0.0.1-alpha.2 → 0.0.1-alpha.4

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 (107) hide show
  1. package/.devalang +1 -1
  2. package/Cargo.toml +46 -46
  3. package/README.md +48 -30
  4. package/docs/CHANGELOG.md +28 -6
  5. package/docs/COMMANDS.md +31 -0
  6. package/docs/CONFIG.md +6 -4
  7. package/docs/ROADMAP.md +5 -1
  8. package/docs/TODO.md +10 -35
  9. package/examples/exported.deva +1 -1
  10. package/examples/index.deva +8 -1
  11. package/examples/samples/hat-808.wav +0 -0
  12. package/out-tsc/bin/devalang.exe +0 -0
  13. package/package.json +41 -42
  14. package/project-version.json +5 -5
  15. package/rust/audio/engine.rs +130 -0
  16. package/rust/audio/interpreter.rs +143 -0
  17. package/rust/audio/loader.rs +46 -0
  18. package/rust/audio/mod.rs +5 -1
  19. package/rust/audio/player.rs +54 -0
  20. package/rust/audio/render.rs +57 -0
  21. package/rust/cli/build.rs +73 -45
  22. package/rust/cli/check.rs +47 -111
  23. package/rust/cli/init.rs +1 -1
  24. package/rust/cli/mod.rs +203 -2
  25. package/rust/cli/play.rs +191 -0
  26. package/rust/{utils/config.rs → config/loader.rs} +3 -2
  27. package/rust/config/mod.rs +16 -0
  28. package/rust/core/builder/mod.rs +69 -27
  29. package/rust/core/debugger/lexer.rs +27 -0
  30. package/rust/core/debugger/mod.rs +12 -49
  31. package/rust/core/debugger/preprocessor.rs +27 -0
  32. package/rust/core/error/mod.rs +60 -0
  33. package/rust/core/lexer/{at.rs → handler/at.rs} +1 -1
  34. package/rust/core/lexer/{brace.rs → handler/brace.rs} +1 -1
  35. package/rust/core/lexer/{colon.rs → handler/colon.rs} +1 -1
  36. package/rust/core/lexer/{comment.rs → handler/comment.rs} +3 -3
  37. package/rust/core/lexer/{dot.rs → handler/dot.rs} +1 -1
  38. package/rust/core/lexer/{equal.rs → handler/equal.rs} +1 -1
  39. package/rust/core/lexer/{identifier.rs → handler/identifier.rs} +1 -1
  40. package/rust/core/lexer/{indent.rs → handler/indent.rs} +10 -5
  41. package/rust/core/lexer/handler/mod.rs +238 -0
  42. package/rust/core/lexer/{newline.rs → handler/newline.rs} +6 -10
  43. package/rust/core/lexer/{number.rs → handler/number.rs} +1 -1
  44. package/rust/core/lexer/handler/string.rs +66 -0
  45. package/rust/core/lexer/mod.rs +25 -14
  46. package/rust/core/lexer/token.rs +55 -0
  47. package/rust/core/mod.rs +5 -2
  48. package/rust/core/parser/handler/at.rs +166 -0
  49. package/rust/core/parser/handler/bank.rs +38 -0
  50. package/rust/core/parser/handler/dot.rs +112 -0
  51. package/rust/core/parser/handler/identifier.rs +134 -0
  52. package/rust/core/parser/handler/loop_.rs +55 -0
  53. package/rust/core/parser/handler/mod.rs +6 -0
  54. package/rust/core/parser/handler/tempo.rs +47 -0
  55. package/rust/core/parser/mod.rs +204 -166
  56. package/rust/core/parser/statement.rs +91 -0
  57. package/rust/core/preprocessor/loader.rs +116 -0
  58. package/rust/core/preprocessor/mod.rs +2 -24
  59. package/rust/core/preprocessor/module.rs +37 -56
  60. package/rust/core/preprocessor/processor.rs +41 -0
  61. package/rust/core/preprocessor/resolver/bank.rs +38 -51
  62. package/rust/core/preprocessor/resolver/loop_.rs +126 -65
  63. package/rust/core/preprocessor/resolver/mod.rs +119 -80
  64. package/rust/core/preprocessor/resolver/tempo.rs +40 -61
  65. package/rust/core/preprocessor/resolver/trigger.rs +93 -155
  66. package/rust/core/shared/duration.rs +8 -0
  67. package/rust/core/shared/mod.rs +2 -0
  68. package/rust/core/shared/value.rs +18 -0
  69. package/rust/core/store/export.rs +28 -0
  70. package/rust/core/store/global.rs +39 -0
  71. package/rust/core/store/import.rs +28 -0
  72. package/rust/core/store/mod.rs +4 -0
  73. package/rust/core/store/variable.rs +28 -0
  74. package/rust/core/utils/mod.rs +2 -0
  75. package/rust/core/utils/validation.rs +35 -0
  76. package/rust/lib.rs +0 -1
  77. package/rust/main.rs +22 -18
  78. package/rust/utils/logger.rs +69 -34
  79. package/rust/utils/mod.rs +3 -5
  80. package/rust/utils/watcher.rs +10 -2
  81. package/templates/minimal/.devalang +1 -1
  82. package/templates/welcome/.devalang +1 -1
  83. package/rust/core/lexer/bracket.rs +0 -41
  84. package/rust/core/lexer/driver.rs +0 -286
  85. package/rust/core/lexer/quote.rs +0 -61
  86. package/rust/core/parser/at.rs +0 -142
  87. package/rust/core/parser/bank.rs +0 -42
  88. package/rust/core/parser/dot.rs +0 -137
  89. package/rust/core/parser/identifer.rs +0 -91
  90. package/rust/core/parser/loop_.rs +0 -62
  91. package/rust/core/parser/tempo.rs +0 -42
  92. package/rust/core/parser/variable.rs +0 -129
  93. package/rust/core/preprocessor/dependencies.rs +0 -54
  94. package/rust/core/preprocessor/resolver/at.rs +0 -24
  95. package/rust/core/types/cli.rs +0 -182
  96. package/rust/core/types/config.rs +0 -15
  97. package/rust/core/types/mod.rs +0 -8
  98. package/rust/core/types/module.rs +0 -41
  99. package/rust/core/types/parser.rs +0 -73
  100. package/rust/core/types/statement.rs +0 -105
  101. package/rust/core/types/store.rs +0 -116
  102. package/rust/core/types/token.rs +0 -83
  103. package/rust/core/types/variable.rs +0 -32
  104. package/rust/runner/executer.rs +0 -44
  105. package/rust/runner/mod.rs +0 -1
  106. /package/rust/{utils → core/utils}/path.rs +0 -0
  107. /package/rust/utils/{loader.rs → spinner.rs} +0 -0
@@ -0,0 +1,28 @@
1
+ use std::collections::HashMap;
2
+
3
+ use crate::core::shared::value::Value;
4
+
5
+ #[derive(Debug, Default, Clone, PartialEq)]
6
+ pub struct ExportTable {
7
+ pub exports: HashMap<String, Value>,
8
+ }
9
+
10
+ impl ExportTable {
11
+ pub fn new() -> Self {
12
+ ExportTable {
13
+ exports: HashMap::new(),
14
+ }
15
+ }
16
+
17
+ pub fn add_export(&mut self, name: String, value: Value) {
18
+ self.exports.insert(name, value);
19
+ }
20
+
21
+ pub fn get_export(&self, name: &str) -> Option<&Value> {
22
+ self.exports.get(name)
23
+ }
24
+
25
+ pub fn remove_export(&mut self, name: &str) -> Option<Value> {
26
+ self.exports.remove(name)
27
+ }
28
+ }
@@ -0,0 +1,39 @@
1
+ use std::collections::HashMap;
2
+ use crate::core::preprocessor::module::Module;
3
+
4
+ #[derive(Debug, Default, Clone)]
5
+ pub struct GlobalStore {
6
+ pub modules: HashMap<String, Module>,
7
+ }
8
+
9
+ impl GlobalStore {
10
+ pub fn new() -> Self {
11
+ GlobalStore {
12
+ modules: HashMap::new(),
13
+ }
14
+ }
15
+
16
+ pub fn resolve_all_imports(&mut self) {
17
+ for module in self.modules.values_mut() {
18
+ for (name, source_path) in &module.import_table.imports {
19
+ println!("Resolving import: {} from {:?}", name, source_path);
20
+ }
21
+ }
22
+ }
23
+
24
+ pub fn insert_module(&mut self, path: String, module: Module) {
25
+ self.modules.insert(path, module);
26
+ }
27
+
28
+ pub fn modules_mut(&mut self) -> &mut HashMap<String, Module> {
29
+ &mut self.modules
30
+ }
31
+
32
+ pub fn get_module(&self, path: &str) -> Option<&Module> {
33
+ self.modules.get(path)
34
+ }
35
+
36
+ pub fn remove_module(&mut self, path: &str) -> Option<Module> {
37
+ self.modules.remove(path)
38
+ }
39
+ }
@@ -0,0 +1,28 @@
1
+ use std::collections::HashMap;
2
+
3
+ use crate::core::shared::value::Value;
4
+
5
+ #[derive(Debug, Default, Clone, PartialEq)]
6
+ pub struct ImportTable {
7
+ pub imports: HashMap<String, Value>,
8
+ }
9
+
10
+ impl ImportTable {
11
+ pub fn new() -> Self {
12
+ ImportTable {
13
+ imports: HashMap::new(),
14
+ }
15
+ }
16
+
17
+ pub fn add_import(&mut self, name: String, value: Value) {
18
+ self.imports.insert(name, value);
19
+ }
20
+
21
+ pub fn get_import(&self, name: &str) -> Option<&Value> {
22
+ self.imports.get(name)
23
+ }
24
+
25
+ pub fn remove_import(&mut self, name: &str) -> Option<Value> {
26
+ self.imports.remove(name)
27
+ }
28
+ }
@@ -0,0 +1,4 @@
1
+ pub mod global;
2
+ pub mod export;
3
+ pub mod import;
4
+ pub mod variable;
@@ -0,0 +1,28 @@
1
+ use std::collections::HashMap;
2
+
3
+ use crate::core::shared::value::Value;
4
+
5
+ #[derive(Debug, Default, Clone, PartialEq)]
6
+ pub struct VariableTable {
7
+ pub variables: HashMap<String, Value>,
8
+ }
9
+
10
+ impl VariableTable {
11
+ pub fn new() -> Self {
12
+ VariableTable {
13
+ variables: HashMap::new(),
14
+ }
15
+ }
16
+
17
+ pub fn set(&mut self, name: String, value: Value) {
18
+ self.variables.insert(name, value);
19
+ }
20
+
21
+ pub fn get(&self, name: &str) -> Option<&Value> {
22
+ self.variables.get(name)
23
+ }
24
+
25
+ pub fn remove(&mut self, name: &str) -> Option<Value> {
26
+ self.variables.remove(name)
27
+ }
28
+ }
@@ -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,59 +1,63 @@
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;
5
+ pub mod audio;
6
6
 
7
- use std::{ io };
7
+ use std::io;
8
+ use cli::{ Cli };
8
9
  use clap::Parser;
9
10
  use crate::{
10
11
  cli::{
11
12
  build::handle_build_command,
12
13
  check::handle_check_command,
13
14
  init::handle_init_command,
15
+ play::handle_play_command,
14
16
  template::{ handle_template_info_command, handle_template_list_command },
17
+ Commands,
18
+ TemplateCommand,
15
19
  },
16
- core::types::{ cli::{ Cli, CliCommands, CliTemplateCommand }, config::DevalangConfig },
17
- utils::{ config::load_config, logger::log_message },
20
+ config::{ loader::load_config, Config },
18
21
  };
19
22
 
20
23
  fn main() -> io::Result<()> {
21
24
  let cli: Cli = Cli::parse();
22
- let mut config: Option<DevalangConfig> = None;
25
+ let mut config: Option<Config> = None;
23
26
 
24
27
  if !cli.no_config {
25
28
  config = load_config(None);
26
29
  } else {
27
- log_message("Configuration file loading is skipped.", "WARNING");
30
+ println!("No configuration file loaded. Running with arguments only.");
28
31
  }
29
32
 
30
33
  match cli.command {
31
- CliCommands::Init { name, template } => {
34
+ Commands::Init { name, template } => {
32
35
  handle_init_command(name, template);
33
36
  }
34
37
 
35
- CliCommands::Template { command } =>
38
+ Commands::Template { command } =>
36
39
  match command {
37
- CliTemplateCommand::List => {
40
+ TemplateCommand::List => {
38
41
  handle_template_list_command();
39
42
  }
40
- CliTemplateCommand::Info { name } => {
43
+ TemplateCommand::Info { name } => {
41
44
  handle_template_info_command(name);
42
45
  }
43
46
  }
44
47
 
45
- CliCommands::Build { entry, output, watch, compilation_mode, debug, compress } => {
48
+ Commands::Check { entry, output, watch, compilation_mode, debug } => {
49
+ handle_check_command(config, entry, output, watch);
50
+ }
51
+
52
+ Commands::Build { entry, output, watch, compilation_mode, debug, compress } => {
46
53
  handle_build_command(config, entry, output, watch);
47
54
  }
48
55
 
49
- CliCommands::Check { entry, output, watch, compilation_mode, debug } => {
50
- handle_check_command(config, entry, output, watch);
56
+ Commands::Play { entry, output, watch, repeat } => {
57
+ handle_play_command(config, entry, output, watch, repeat);
51
58
  }
52
59
 
53
- // TODO - Implement the play command
54
- // CliCommands::Play {} => {
55
- // log_message("Command 'play' is not implemented yet.", "WARNING");
56
- // }
60
+ _ => {}
57
61
  }
58
62
 
59
63
  Ok(())
@@ -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,8 +1,6 @@
1
1
  pub mod version;
2
2
  pub mod signature;
3
- pub mod path;
4
- pub mod loader;
5
- pub mod logger;
6
- pub mod file;
3
+ pub mod spinner;
7
4
  pub mod watcher;
8
- pub mod config;
5
+ pub mod file;
6
+ pub mod logger;
@@ -1,6 +1,8 @@
1
1
  use notify::{ Watcher, RecursiveMode, Config, RecommendedWatcher };
2
2
  use std::sync::mpsc::channel;
3
3
 
4
+ use std::time::{ Duration, Instant };
5
+
4
6
  pub fn watch_directory<F>(entry: String, callback: F) -> notify::Result<()>
5
7
  where F: Fn() + Send + 'static
6
8
  {
@@ -9,13 +11,19 @@ pub fn watch_directory<F>(entry: String, callback: F) -> notify::Result<()>
9
11
  let mut watcher: RecommendedWatcher = Watcher::new(tx, Config::default())?;
10
12
  watcher.watch(&entry.as_ref(), RecursiveMode::Recursive)?;
11
13
 
14
+ let mut last_trigger = Instant::now();
15
+
12
16
  loop {
13
17
  match rx.recv() {
14
18
  Ok(_) => {
15
- callback();
19
+ let now = Instant::now();
20
+ if now.duration_since(last_trigger) > Duration::from_millis(200) {
21
+ callback();
22
+ last_trigger = now;
23
+ }
16
24
  }
17
25
  Err(e) => {
18
- eprintln!("Channel error : {:?}", e);
26
+ eprintln!("Channel error: {:?}", e);
19
27
  break;
20
28
  }
21
29
  }
@@ -1,4 +1,4 @@
1
1
  [defaults]
2
2
  entry = "./src"
3
3
  output = "./output"
4
- watch = true
4
+ watch = false
@@ -1,4 +1,4 @@
1
1
  [defaults]
2
2
  entry = "./src"
3
3
  output = "./output"
4
- watch = true
4
+ watch = false
@@ -1,41 +0,0 @@
1
- use crate::core::types::token::{ Token, TokenKind };
2
-
3
- pub fn handle_rbracket_lexer(
4
- char: char,
5
- chars: &mut std::iter::Peekable<std::str::Chars>,
6
- current_indent: &mut usize,
7
- indent_stack: &mut Vec<usize>,
8
- tokens: &mut Vec<Token>,
9
- line: &mut usize,
10
- column: &mut usize
11
- ) {
12
- tokens.push(Token {
13
- kind: TokenKind::RBracket,
14
- lexeme: char.to_string(),
15
- line: *line,
16
- column: *column,
17
- indent: *current_indent,
18
- });
19
-
20
- *column += 1;
21
- }
22
-
23
- pub fn handle_lbracket_lexer(
24
- char: char,
25
- chars: &mut std::iter::Peekable<std::str::Chars>,
26
- current_indent: &mut usize,
27
- indent_stack: &mut Vec<usize>,
28
- tokens: &mut Vec<Token>,
29
- line: &mut usize,
30
- column: &mut usize
31
- ) {
32
- tokens.push(Token {
33
- kind: TokenKind::LBracket,
34
- lexeme: char.to_string(),
35
- line: *line,
36
- column: *column,
37
- indent: *current_indent,
38
- });
39
-
40
- *column += 1;
41
- }