@devaloop/devalang 0.0.1-alpha.1 → 0.0.1-alpha.10

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 (155) hide show
  1. package/.devalang +4 -0
  2. package/Cargo.toml +49 -45
  3. package/README.md +127 -46
  4. package/docs/CHANGELOG.md +172 -0
  5. package/docs/COMMANDS.md +60 -6
  6. package/docs/CONFIG.md +30 -0
  7. package/docs/ROADMAP.md +10 -7
  8. package/docs/SYNTAX.md +100 -18
  9. package/docs/TODO.md +31 -28
  10. package/examples/condition.deva +20 -0
  11. package/examples/group.deva +12 -0
  12. package/examples/index.deva +13 -4
  13. package/examples/loop.deva +16 -0
  14. package/examples/samples/hat-808.wav +0 -0
  15. package/examples/synth.deva +14 -0
  16. package/examples/variables.deva +9 -0
  17. package/out-tsc/bin/devalang.exe +0 -0
  18. package/out-tsc/scripts/version/fetch.js +1 -5
  19. package/package.json +5 -4
  20. package/project-version.json +3 -3
  21. package/rust/cli/build.rs +114 -28
  22. package/rust/cli/check.rs +96 -103
  23. package/rust/cli/init.rs +79 -0
  24. package/rust/cli/mod.rs +203 -1
  25. package/rust/cli/play.rs +193 -0
  26. package/rust/cli/template.rs +57 -0
  27. package/rust/config/loader.rs +13 -0
  28. package/rust/config/mod.rs +16 -0
  29. package/rust/core/audio/engine.rs +214 -0
  30. package/rust/core/audio/evaluator.rs +31 -0
  31. package/rust/core/audio/interpreter/arrow_call.rs +129 -0
  32. package/rust/core/audio/interpreter/call.rs +70 -0
  33. package/rust/core/audio/interpreter/condition.rs +69 -0
  34. package/rust/core/audio/interpreter/driver.rs +236 -0
  35. package/rust/core/audio/interpreter/let_.rs +19 -0
  36. package/rust/core/audio/interpreter/load.rs +18 -0
  37. package/rust/core/audio/interpreter/loop_.rs +67 -0
  38. package/rust/core/audio/interpreter/mod.rs +12 -0
  39. package/rust/core/audio/interpreter/sleep.rs +36 -0
  40. package/rust/core/audio/interpreter/spawn.rs +84 -0
  41. package/rust/core/audio/interpreter/tempo.rs +16 -0
  42. package/rust/core/audio/interpreter/trigger.rs +69 -0
  43. package/rust/core/audio/loader/mod.rs +1 -0
  44. package/rust/core/audio/loader/trigger.rs +52 -0
  45. package/rust/core/audio/mod.rs +6 -0
  46. package/rust/core/audio/player.rs +54 -0
  47. package/rust/core/audio/renderer.rs +54 -0
  48. package/rust/core/builder/mod.rs +70 -27
  49. package/rust/core/debugger/lexer.rs +27 -0
  50. package/rust/core/debugger/mod.rs +13 -49
  51. package/rust/core/debugger/preprocessor.rs +27 -0
  52. package/rust/core/debugger/store.rs +25 -0
  53. package/rust/core/error/mod.rs +60 -0
  54. package/rust/core/lexer/handler/arrow.rs +31 -0
  55. package/rust/core/lexer/handler/at.rs +21 -0
  56. package/rust/core/lexer/handler/brace.rs +41 -0
  57. package/rust/core/lexer/handler/colon.rs +21 -0
  58. package/rust/core/lexer/handler/comment.rs +30 -0
  59. package/rust/core/lexer/handler/dot.rs +21 -0
  60. package/rust/core/lexer/handler/driver.rs +230 -0
  61. package/rust/core/lexer/handler/identifier.rs +41 -0
  62. package/rust/core/lexer/handler/indent.rs +52 -0
  63. package/rust/core/lexer/handler/mod.rs +14 -0
  64. package/rust/core/lexer/handler/newline.rs +23 -0
  65. package/rust/core/lexer/handler/number.rs +31 -0
  66. package/rust/core/lexer/handler/operator.rs +44 -0
  67. package/rust/core/lexer/handler/string.rs +63 -0
  68. package/rust/core/lexer/mod.rs +37 -319
  69. package/rust/core/lexer/token.rs +86 -0
  70. package/rust/core/mod.rs +6 -2
  71. package/rust/core/parser/driver.rs +331 -0
  72. package/rust/core/parser/handler/arrow_call.rs +126 -0
  73. package/rust/core/parser/handler/at.rs +162 -0
  74. package/rust/core/parser/handler/bank.rs +41 -0
  75. package/rust/core/parser/handler/condition.rs +74 -0
  76. package/rust/core/parser/handler/dot.rs +112 -0
  77. package/rust/core/parser/handler/identifier/call.rs +41 -0
  78. package/rust/core/parser/handler/identifier/group.rs +75 -0
  79. package/rust/core/parser/handler/identifier/let_.rs +133 -0
  80. package/rust/core/parser/handler/identifier/mod.rs +51 -0
  81. package/rust/core/parser/handler/identifier/sleep.rs +33 -0
  82. package/rust/core/parser/handler/identifier/spawn.rs +41 -0
  83. package/rust/core/parser/handler/identifier/synth.rs +65 -0
  84. package/rust/core/parser/handler/loop_.rs +72 -0
  85. package/rust/core/parser/handler/mod.rs +8 -0
  86. package/rust/core/parser/handler/tempo.rs +47 -0
  87. package/rust/core/parser/mod.rs +3 -200
  88. package/rust/core/parser/statement.rs +96 -0
  89. package/rust/core/preprocessor/loader.rs +229 -0
  90. package/rust/core/preprocessor/mod.rs +2 -24
  91. package/rust/core/preprocessor/module.rs +42 -56
  92. package/rust/core/preprocessor/processor.rs +76 -0
  93. package/rust/core/preprocessor/resolver/bank.rs +41 -51
  94. package/rust/core/preprocessor/resolver/call.rs +123 -0
  95. package/rust/core/preprocessor/resolver/condition.rs +92 -0
  96. package/rust/core/preprocessor/resolver/driver.rs +227 -0
  97. package/rust/core/preprocessor/resolver/group.rs +61 -0
  98. package/rust/core/preprocessor/resolver/let_.rs +31 -0
  99. package/rust/core/preprocessor/resolver/loop_.rs +76 -67
  100. package/rust/core/preprocessor/resolver/mod.rs +12 -111
  101. package/rust/core/preprocessor/resolver/spawn.rs +58 -0
  102. package/rust/core/preprocessor/resolver/synth.rs +50 -0
  103. package/rust/core/preprocessor/resolver/tempo.rs +40 -61
  104. package/rust/core/preprocessor/resolver/trigger.rs +90 -154
  105. package/rust/core/preprocessor/resolver/value.rs +78 -0
  106. package/rust/core/shared/duration.rs +8 -0
  107. package/rust/core/shared/mod.rs +2 -0
  108. package/rust/core/shared/value.rs +28 -0
  109. package/rust/core/store/export.rs +28 -0
  110. package/rust/core/store/global.rs +39 -0
  111. package/rust/core/store/import.rs +28 -0
  112. package/rust/core/store/mod.rs +4 -0
  113. package/rust/core/store/variable.rs +28 -0
  114. package/rust/core/utils/mod.rs +2 -0
  115. package/rust/core/utils/path.rs +31 -0
  116. package/rust/core/utils/validation.rs +37 -0
  117. package/rust/lib.rs +161 -1
  118. package/rust/main.rs +46 -30
  119. package/rust/utils/file.rs +35 -0
  120. package/rust/utils/logger.rs +108 -34
  121. package/rust/utils/mod.rs +3 -2
  122. package/rust/utils/{loader.rs → spinner.rs} +2 -0
  123. package/rust/utils/watcher.rs +33 -0
  124. package/templates/minimal/.devalang +5 -0
  125. package/templates/minimal/README.md +202 -0
  126. package/templates/minimal/src/index.deva +2 -0
  127. package/templates/welcome/.devalang +5 -0
  128. package/templates/welcome/README.md +202 -0
  129. package/templates/welcome/samples/kick-808.wav +0 -0
  130. package/templates/welcome/src/index.deva +13 -0
  131. package/templates/welcome/src/variables.deva +5 -0
  132. package/typescript/scripts/version/fetch.ts +1 -6
  133. package/examples/exported.deva +0 -7
  134. package/rust/audio/mod.rs +0 -1
  135. package/rust/cli/new.rs +0 -1
  136. package/rust/core/parser/at.rs +0 -142
  137. package/rust/core/parser/bank.rs +0 -42
  138. package/rust/core/parser/dot.rs +0 -107
  139. package/rust/core/parser/identifer.rs +0 -91
  140. package/rust/core/parser/loop_.rs +0 -62
  141. package/rust/core/parser/tempo.rs +0 -42
  142. package/rust/core/parser/variable.rs +0 -129
  143. package/rust/core/preprocessor/dependencies.rs +0 -54
  144. package/rust/core/preprocessor/resolver/at.rs +0 -24
  145. package/rust/core/types/cli.rs +0 -160
  146. package/rust/core/types/mod.rs +0 -7
  147. package/rust/core/types/module.rs +0 -41
  148. package/rust/core/types/parser.rs +0 -73
  149. package/rust/core/types/statement.rs +0 -105
  150. package/rust/core/types/store.rs +0 -116
  151. package/rust/core/types/token.rs +0 -83
  152. package/rust/core/types/variable.rs +0 -32
  153. package/rust/runner/executer.rs +0 -44
  154. package/rust/runner/mod.rs +0 -1
  155. package/rust/utils/path.rs +0 -46
@@ -1,333 +1,51 @@
1
- use crate::core::types::token::{ Token, TokenKind };
1
+ pub mod handler;
2
+ pub mod token;
2
3
 
3
- pub fn lex(input: String) -> Vec<Token> {
4
- let mut tokens = Vec::new();
4
+ use std::fs;
5
+ use std::path::{Path, PathBuf};
6
+ use crate::core::{
7
+ lexer::{ handler::driver::handle_content_lexing, token::Token },
8
+ utils::path::normalize_path,
9
+ };
5
10
 
6
- let mut line = 1;
7
- let mut column = 1;
11
+ pub struct Lexer {}
8
12
 
9
- let mut indent_stack: Vec<usize> = vec![0];
10
- let mut current_indent = 0;
11
- let mut at_line_start = true;
12
-
13
- let mut chars = input.chars().peekable();
14
-
15
- while let Some(_) = chars.peek() {
16
- if at_line_start {
17
- current_indent = 0;
18
-
19
- while let Some(&c) = chars.peek() {
20
- if c == ' ' {
21
- current_indent += 1;
22
- chars.next();
23
- column += 1;
24
- } else {
25
- break;
26
- }
27
- }
28
-
29
- let last_indent = *indent_stack.last().unwrap();
30
- if current_indent > last_indent {
31
- indent_stack.push(current_indent);
32
- tokens.push(Token {
33
- kind: TokenKind::Indent,
34
- lexeme: String::new(),
35
- line,
36
- column,
37
- indent: current_indent,
38
- });
39
- } else {
40
- while current_indent < *indent_stack.last().unwrap() {
41
- indent_stack.pop();
42
- tokens.push(Token {
43
- kind: TokenKind::Dedent,
44
- lexeme: String::new(),
45
- line,
46
- column,
47
- indent: current_indent,
48
- });
49
- }
50
- }
51
-
52
- at_line_start = false;
53
- }
54
-
55
- let Some(ch) = chars.next() else {
56
- break;
57
- };
58
-
59
- if ch == '\n' {
60
- tokens.push(Token {
61
- kind: TokenKind::Newline,
62
- lexeme: ch.to_string(),
63
- line,
64
- column,
65
- indent: current_indent,
66
- });
13
+ impl Lexer {
14
+ pub fn new() -> Self {
15
+ Lexer {}
16
+ }
67
17
 
68
- line += 1;
69
- column = 1;
70
- at_line_start = true;
18
+ pub fn lex_from_source(&self, source: &str) -> Result<Vec<Token>, String> {
19
+ handle_content_lexing(source.to_string())
20
+ }
71
21
 
72
- continue;
73
- }
22
+ pub fn lex_tokens(&self, entrypoint: &str) -> Vec<Token> {
23
+ let path = normalize_path(entrypoint);
24
+ let resolved_path = Self::resolve_entry_path(&path);
74
25
 
75
- if ch == ' ' || ch == '\t' {
76
- column += if ch == '\t' { 4 } else { 1 };
77
- continue;
78
- }
26
+ let file_content =
27
+ fs::read_to_string(&resolved_path).expect("Failed to read the entrypoint file");
79
28
 
80
- if ch == '#' {
81
- let mut comment = String::new();
82
- while let Some(&c) = chars.peek() {
83
- if c == '\n' {
84
- break;
85
- }
86
- comment.push(c);
87
- chars.next();
88
- column += 1;
89
- }
90
- tokens.push(Token {
91
- kind: TokenKind::Comment(comment.trim().to_string()),
92
- lexeme: ch.to_string(),
93
- line,
94
- column,
95
- indent: current_indent,
96
- });
97
- continue;
98
- }
29
+ handle_content_lexing(file_content).expect("Failed to lex the content")
30
+ }
99
31
 
100
- if ch == ':' {
101
- tokens.push(Token {
102
- kind: TokenKind::Colon,
103
- lexeme: ch.to_string(),
104
- line,
105
- column,
106
- indent: current_indent,
107
- });
108
- column += 1;
109
- continue;
110
- }
32
+ fn resolve_entry_path(path: &str) -> String {
33
+ let candidate = Path::new(path);
111
34
 
112
- if ch == '=' {
113
- if let Some('=') = chars.peek() {
114
- chars.next();
115
- tokens.push(Token {
116
- kind: TokenKind::DoubleEquals,
117
- lexeme: ch.to_string(),
118
- line,
119
- column,
120
- indent: current_indent,
121
- });
122
- column += 2;
35
+ if candidate.is_dir() {
36
+ let index_path = candidate.join("index.deva");
37
+ if index_path.exists() {
38
+ return index_path.to_string_lossy().replace("\\", "/");
123
39
  } else {
124
- tokens.push(Token {
125
- kind: TokenKind::Equals,
126
- lexeme: ch.to_string(),
127
- line,
128
- column,
129
- indent: current_indent,
130
- });
131
- column += 1;
40
+ panic!(
41
+ "Expected 'index.deva' in directory '{}', but it was not found",
42
+ path
43
+ );
132
44
  }
133
- continue;
134
- }
135
-
136
- if ch == '[' {
137
- tokens.push(Token {
138
- kind: TokenKind::LBracket,
139
- lexeme: ch.to_string(),
140
- line,
141
- column,
142
- indent: current_indent,
143
- });
144
- column += 1;
145
- continue;
146
- }
147
-
148
- if ch == ']' {
149
- tokens.push(Token {
150
- kind: TokenKind::RBracket,
151
- lexeme: ch.to_string(),
152
- line,
153
- column,
154
- indent: current_indent,
155
- });
156
- column += 1;
157
- continue;
158
- }
159
-
160
- if ch == '{' {
161
- tokens.push(Token {
162
- kind: TokenKind::LBrace,
163
- lexeme: ch.to_string(),
164
- line,
165
- column,
166
- indent: current_indent,
167
- });
168
- column += 1;
169
- continue;
45
+ } else if candidate.is_file() {
46
+ return path.to_string();
47
+ } else {
48
+ panic!("Provided entrypoint '{}' is not a valid file or directory", path);
170
49
  }
171
-
172
- if ch == '}' {
173
- tokens.push(Token {
174
- kind: TokenKind::RBrace,
175
- lexeme: ch.to_string(),
176
- line,
177
- column,
178
- indent: current_indent,
179
- });
180
- column += 1;
181
- continue;
182
- }
183
-
184
- if ch == '"' {
185
- let mut string_content = String::new();
186
- column += 1; // skip the opening quote
187
-
188
- while let Some(next_ch) = chars.next() {
189
- column += 1;
190
- if next_ch == '"' {
191
- break; // closing quote reached
192
- } else {
193
- string_content.push(next_ch);
194
- }
195
- }
196
-
197
- tokens.push(Token {
198
- kind: TokenKind::String,
199
- lexeme: string_content,
200
- line,
201
- column,
202
- indent: current_indent,
203
- });
204
-
205
- continue;
206
- }
207
-
208
- if ch == '\'' {
209
- let mut string_content = String::new();
210
- column += 1;
211
-
212
- while let Some(next_ch) = chars.next() {
213
- column += 1;
214
- if next_ch == '\'' {
215
- break;
216
- } else {
217
- string_content.push(next_ch);
218
- }
219
- }
220
-
221
- tokens.push(Token {
222
- kind: TokenKind::String,
223
- lexeme: string_content,
224
- line,
225
- column,
226
- indent: current_indent,
227
- });
228
-
229
- continue;
230
- }
231
-
232
- if ch == '.' {
233
- tokens.push(Token {
234
- kind: TokenKind::Dot,
235
- lexeme: ch.to_string(),
236
- line,
237
- column,
238
- indent: current_indent,
239
- });
240
- column += 1;
241
- continue;
242
- }
243
-
244
- if ch == '@' {
245
- tokens.push(Token {
246
- kind: TokenKind::At,
247
- lexeme: ch.to_string(),
248
- line,
249
- column,
250
- indent: current_indent,
251
- });
252
- column += 1;
253
- continue;
254
- }
255
-
256
- if ch.is_ascii_digit() {
257
- let mut number = ch.to_string();
258
- while let Some(&c) = chars.peek() {
259
- if c.is_ascii_digit() {
260
- number.push(c);
261
- chars.next();
262
- column += 1;
263
- } else {
264
- break;
265
- }
266
- }
267
-
268
- // let value = number.parse::<f32>().unwrap();
269
- tokens.push(Token {
270
- kind: TokenKind::Number,
271
- lexeme: number,
272
- line,
273
- column,
274
- indent: current_indent,
275
- });
276
- continue;
277
- }
278
-
279
- if ch.is_ascii_alphabetic() {
280
- let mut ident = ch.to_string();
281
- while let Some(&c) = chars.peek() {
282
- if c.is_ascii_alphanumeric() || c == '_' {
283
- ident.push(c);
284
- chars.next();
285
- column += 1;
286
- } else {
287
- break;
288
- }
289
- }
290
-
291
- let kind = match ident.as_str() {
292
- "bank" => TokenKind::Bank,
293
- "bpm" => TokenKind::Tempo,
294
- "loop" => TokenKind::Loop,
295
- _ => TokenKind::Identifier,
296
- };
297
-
298
- tokens.push(Token {
299
- kind,
300
- lexeme: ident,
301
- line,
302
- column,
303
- indent: current_indent,
304
- });
305
- continue;
306
- }
307
-
308
- // Skip unknown char
309
- column += 1;
310
50
  }
311
-
312
- while indent_stack.len() > 1 {
313
- indent_stack.pop();
314
- current_indent = *indent_stack.last().unwrap();
315
- tokens.push(Token {
316
- kind: TokenKind::Dedent,
317
- lexeme: String::new(),
318
- line,
319
- column,
320
- indent: current_indent,
321
- });
322
- }
323
-
324
- tokens.push(Token {
325
- kind: TokenKind::EOF,
326
- lexeme: String::new(),
327
- line: line + 1, // EOF is considered to be on the next line
328
- column: 0, // EOF has no column
329
- indent: 0, // EOF has no indent
330
- });
331
-
332
- tokens
333
51
  }
@@ -0,0 +1,86 @@
1
+ use serde::{ Deserialize, Serialize };
2
+
3
+ #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4
+ pub struct Token {
5
+ pub kind: TokenKind,
6
+ pub lexeme: String,
7
+ pub indent: usize,
8
+ pub line: usize,
9
+ pub column: usize,
10
+ }
11
+
12
+ impl Token {
13
+ pub fn is_error(&self) -> bool {
14
+ match &self.kind {
15
+ TokenKind::Error(_) => {
16
+ return true;
17
+ }
18
+ _ => {
19
+ return false;
20
+ }
21
+ };
22
+ }
23
+ }
24
+
25
+ #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
26
+ pub enum TokenKind {
27
+ // ───── Keywords ─────
28
+ At,
29
+ Tempo,
30
+ Bank,
31
+ Loop,
32
+
33
+ // ───── Instruments ─────
34
+ Synth,
35
+
36
+ // ───── Literals ─────
37
+ Identifier,
38
+ Number,
39
+ String,
40
+ Boolean,
41
+ Arrow,
42
+
43
+ // ───── Structures ─────
44
+ Map,
45
+ Array,
46
+
47
+ // ───── Symbols ─────
48
+ Colon,
49
+ Comma,
50
+ Equals,
51
+ Dot,
52
+
53
+ // ───── Operators ─────
54
+ DoubleEquals,
55
+ NotEquals,
56
+ GreaterEqual,
57
+ LessEqual,
58
+ Greater,
59
+ Less,
60
+
61
+ // ───── Brackets ─────
62
+ LBrace, // {
63
+ RBrace, // }
64
+ LBracket, // [
65
+ RBracket, // ]
66
+
67
+ // ───── Quotes ─────
68
+ Quote, // '
69
+ DbQuote, // "
70
+
71
+ // ───── Formatting ─────
72
+ Newline,
73
+ Indent,
74
+ Dedent,
75
+ Comment,
76
+
77
+ // ───── Conditions ─────
78
+ If,
79
+ Else,
80
+ ElseIf,
81
+
82
+ // ───── Special / Internal ─────
83
+ Unknown,
84
+ Error(String),
85
+ EOF,
86
+ }
package/rust/core/mod.rs CHANGED
@@ -1,6 +1,10 @@
1
1
  pub mod lexer;
2
- pub mod parser;
3
2
  pub mod preprocessor;
3
+ pub mod store;
4
+ pub mod parser;
5
+ pub mod shared;
4
6
  pub mod debugger;
7
+ pub mod utils;
5
8
  pub mod builder;
6
- pub mod types;
9
+ pub mod error;
10
+ pub mod audio;