@devaloop/devalang 0.0.1-alpha.16-hotfix.1 → 0.0.1-alpha.17
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/.cargo/config.toml +2 -0
- package/.devalang +6 -10
- package/.github/workflows/ci.yml +19 -8
- package/Cargo.toml +18 -2
- package/README.md +80 -33
- package/docs/CHANGELOG.md +56 -0
- package/docs/ROADMAP.md +6 -3
- package/examples/index.deva +52 -35
- package/out-tsc/bin/index.d.ts +2 -0
- package/out-tsc/core/functions/index.d.ts +37 -0
- package/out-tsc/core/functions/index.js +76 -0
- package/out-tsc/core/index.d.ts +6 -0
- package/out-tsc/core/index.js +22 -0
- package/out-tsc/core/types/index.d.ts +4 -0
- package/out-tsc/core/types/index.js +20 -0
- package/out-tsc/core/types/plugin.d.ts +18 -0
- package/out-tsc/core/types/plugin.js +2 -0
- package/out-tsc/core/types/result.d.ts +27 -0
- package/out-tsc/core/types/result.js +2 -0
- package/out-tsc/core/types/statement.d.ts +106 -0
- package/out-tsc/core/types/statement.js +2 -0
- package/out-tsc/core/types/value.d.ts +43 -0
- package/out-tsc/core/types/value.js +2 -0
- package/out-tsc/index.d.ts +7 -0
- package/out-tsc/index.js +41 -2
- package/out-tsc/pkg/devalang_core.d.ts +7 -0
- package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +33 -0
- package/out-tsc/scripts/copy-wasm-dts.d.ts +1 -0
- package/out-tsc/scripts/copy-wasm-dts.js +73 -0
- package/out-tsc/scripts/postinstall.d.ts +1 -0
- package/out-tsc/scripts/postinstall.js +33 -23
- package/out-tsc/scripts/version/bump.d.ts +1 -0
- package/out-tsc/scripts/version/fetch.d.ts +1 -0
- package/out-tsc/scripts/version/index.d.ts +1 -0
- package/out-tsc/scripts/version/sync.d.ts +1 -0
- package/package.json +16 -4
- package/project-version.json +3 -3
- package/rust/cli/bank/api.rs +122 -0
- package/rust/cli/bank/commands.rs +275 -0
- package/rust/cli/bank/mod.rs +29 -0
- package/rust/cli/build/commands.rs +97 -0
- package/rust/cli/build/mod.rs +2 -0
- package/rust/cli/build/process.rs +146 -0
- package/rust/cli/{check.rs → check/mod.rs} +18 -31
- package/rust/cli/discover/commands.rs +253 -0
- package/rust/cli/discover/config.rs +111 -0
- package/rust/cli/discover/fs.rs +19 -0
- package/rust/cli/discover/install.rs +103 -0
- package/rust/cli/discover/metadata.rs +48 -0
- package/rust/cli/discover/mod.rs +5 -0
- package/rust/cli/{init.rs → init/commands.rs} +88 -87
- package/rust/cli/init/mod.rs +1 -0
- package/rust/{installer → cli/install}/addon.rs +5 -9
- package/rust/cli/install/bank.rs +53 -0
- package/rust/cli/{install.rs → install/commands.rs} +9 -9
- package/rust/{installer → cli/install}/mod.rs +2 -3
- package/rust/cli/install/plugin.rs +61 -0
- package/rust/cli/{login.rs → login/commands.rs} +8 -11
- package/rust/cli/login/mod.rs +1 -0
- package/rust/cli/mod.rs +2 -3
- package/rust/cli/{driver.rs → parser.rs} +19 -2
- package/rust/cli/play/commands.rs +324 -0
- package/rust/cli/play/io.rs +17 -0
- package/rust/cli/play/mod.rs +5 -0
- package/rust/cli/play/process.rs +150 -0
- package/rust/cli/play/realtime.rs +91 -0
- package/rust/cli/play/utils.rs +23 -0
- package/rust/cli/telemetry/commands.rs +22 -0
- package/rust/cli/telemetry/event_creator.rs +80 -0
- package/rust/cli/telemetry/mod.rs +3 -0
- package/rust/cli/telemetry/send.rs +51 -0
- package/rust/cli/{template.rs → template/commands.rs} +1 -1
- package/rust/cli/template/mod.rs +1 -0
- package/rust/cli/{update.rs → update/commands.rs} +6 -6
- package/rust/cli/update/mod.rs +1 -0
- package/rust/config/driver.rs +57 -72
- package/rust/config/mod.rs +1 -2
- package/rust/config/ops.rs +26 -0
- package/rust/config/settings.rs +60 -50
- package/rust/core/audio/engine/helpers.rs +146 -0
- package/rust/core/audio/engine/mod.rs +7 -0
- package/rust/core/audio/engine/sample.rs +298 -0
- package/rust/core/audio/engine/synth.rs +310 -0
- package/rust/core/audio/evaluator.rs +15 -12
- package/rust/core/audio/interpreter/arrow_call.rs +99 -24
- package/rust/core/audio/interpreter/call.rs +81 -60
- package/rust/core/audio/interpreter/condition.rs +3 -2
- package/rust/core/audio/interpreter/driver.rs +206 -151
- package/rust/core/audio/interpreter/let_.rs +1 -1
- package/rust/core/audio/interpreter/load.rs +2 -1
- package/rust/core/audio/interpreter/loop_.rs +7 -6
- package/rust/core/audio/interpreter/sleep.rs +2 -1
- package/rust/core/audio/interpreter/spawn.rs +45 -57
- package/rust/core/audio/interpreter/tempo.rs +31 -10
- package/rust/core/audio/interpreter/trigger.rs +2 -2
- package/rust/core/audio/loader/trigger.rs +4 -7
- package/rust/core/audio/player.rs +6 -0
- package/rust/core/audio/renderer.rs +5 -7
- package/rust/core/audio/special/env.rs +3 -1
- package/rust/core/audio/special/math.rs +4 -4
- package/rust/core/audio/special/modulator.rs +2 -2
- package/rust/core/builder/mod.rs +9 -3
- package/rust/core/debugger/lexer.rs +1 -1
- package/rust/core/debugger/mod.rs +6 -0
- package/rust/core/debugger/module.rs +4 -4
- package/rust/core/debugger/preprocessor.rs +1 -1
- package/rust/core/debugger/store.rs +2 -2
- package/rust/core/error/mod.rs +189 -0
- package/rust/core/lexer/handler/arrow.rs +1 -1
- package/rust/core/lexer/handler/at.rs +1 -1
- package/rust/core/lexer/handler/brace.rs +2 -2
- package/rust/core/lexer/handler/colon.rs +1 -1
- package/rust/core/lexer/handler/comment.rs +1 -1
- package/rust/core/lexer/handler/dot.rs +1 -1
- package/rust/core/lexer/handler/driver.rs +1 -1
- package/rust/core/lexer/handler/identifier.rs +1 -1
- package/rust/core/lexer/handler/mod.rs +1 -2
- package/rust/core/lexer/handler/number.rs +1 -1
- package/rust/core/lexer/handler/operator.rs +1 -1
- package/rust/core/lexer/handler/parenthesis.rs +2 -2
- package/rust/core/lexer/handler/slash.rs +1 -1
- package/rust/core/lexer/handler/string.rs +1 -1
- package/rust/core/lexer/mod.rs +22 -12
- package/rust/core/lexer/token.rs +90 -97
- package/rust/core/mod.rs +0 -1
- package/rust/core/parser/driver.rs +66 -13
- package/rust/core/parser/handler/arrow_call.rs +28 -8
- package/rust/core/parser/handler/at.rs +55 -21
- package/rust/core/parser/handler/bank.rs +14 -4
- package/rust/core/parser/handler/condition.rs +6 -3
- package/rust/core/parser/handler/dot.rs +2 -1
- package/rust/core/parser/handler/identifier/automate.rs +13 -16
- package/rust/core/parser/handler/identifier/call.rs +4 -4
- package/rust/core/parser/handler/identifier/emit.rs +9 -5
- package/rust/core/parser/handler/identifier/function.rs +20 -7
- package/rust/core/parser/handler/identifier/group.rs +11 -7
- package/rust/core/parser/handler/identifier/let_.rs +24 -9
- package/rust/core/parser/handler/identifier/mod.rs +6 -5
- package/rust/core/parser/handler/identifier/on.rs +16 -7
- package/rust/core/parser/handler/identifier/print.rs +6 -9
- package/rust/core/parser/handler/identifier/sleep.rs +12 -5
- package/rust/core/parser/handler/identifier/spawn.rs +4 -4
- package/rust/core/parser/handler/identifier/synth.rs +79 -9
- package/rust/core/parser/handler/loop_.rs +39 -14
- package/rust/core/parser/handler/tempo.rs +9 -5
- package/rust/core/parser/mod.rs +0 -1
- package/rust/core/parser/statement.rs +6 -137
- package/rust/core/plugin/loader.rs +41 -27
- package/rust/core/plugin/runner.rs +68 -17
- package/rust/core/preprocessor/loader.rs +155 -33
- package/rust/core/preprocessor/processor.rs +2 -2
- package/rust/core/preprocessor/resolver/bank.rs +6 -8
- package/rust/core/preprocessor/resolver/call.rs +20 -24
- package/rust/core/preprocessor/resolver/condition.rs +6 -8
- package/rust/core/preprocessor/resolver/driver.rs +14 -16
- package/rust/core/preprocessor/resolver/function.rs +6 -6
- package/rust/core/preprocessor/resolver/group.rs +6 -8
- package/rust/core/preprocessor/resolver/loop_.rs +8 -10
- package/rust/core/preprocessor/resolver/spawn.rs +19 -23
- package/rust/core/preprocessor/resolver/synth.rs +6 -8
- package/rust/core/preprocessor/resolver/tempo.rs +6 -8
- package/rust/core/preprocessor/resolver/trigger.rs +22 -19
- package/rust/core/preprocessor/resolver/value.rs +99 -4
- package/rust/core/store/export.rs +28 -28
- package/rust/core/store/function.rs +6 -0
- package/rust/core/store/global.rs +7 -1
- package/rust/core/store/import.rs +28 -28
- package/rust/core/store/variable.rs +1 -1
- package/rust/core/utils/mod.rs +0 -1
- package/rust/lib.rs +102 -9
- package/rust/main.rs +156 -45
- package/rust/types/Cargo.toml +8 -0
- package/rust/types/src/addons.rs +55 -0
- package/rust/types/src/ast.rs +198 -0
- package/rust/types/src/config.rs +74 -0
- package/rust/types/src/lib.rs +12 -0
- package/rust/types/src/telemetry.rs +85 -0
- package/rust/utils/Cargo.toml +23 -0
- package/rust/utils/{error.rs → src/error.rs} +186 -200
- package/rust/utils/src/file.rs +94 -0
- package/rust/utils/src/first_usage.rs +97 -0
- package/rust/utils/{mod.rs → src/lib.rs} +1 -1
- package/rust/utils/{logger.rs → src/logger.rs} +17 -12
- package/rust/utils/src/path.rs +88 -0
- package/rust/utils/src/signature.rs +41 -0
- package/rust/utils/{spinner.rs → src/spinner.rs} +3 -5
- package/rust/utils/src/version.rs +27 -0
- package/rust/utils/{watcher.rs → src/watcher.rs} +13 -1
- package/rust/web/api.rs +5 -0
- package/rust/web/cdn.rs +34 -0
- package/templates/minimal/README.md +98 -54
- package/templates/welcome/README.md +98 -54
- package/templates/welcome/src/index.deva +56 -8
- package/templates/welcome/src/variables.deva +2 -4
- package/tests/rust/TODO.md +0 -0
- package/tests/typescript/index.spec.ts +136 -0
- package/tests/typescript/playhead.spec.ts +36 -0
- package/tests/typescript/render_e2e.spec.ts +77 -0
- package/tsconfig.json +1 -1
- package/typescript/core/functions/index.ts +83 -0
- package/typescript/core/index.ts +6 -0
- package/typescript/core/types/index.ts +4 -0
- package/typescript/core/types/plugin.ts +19 -0
- package/typescript/core/types/result.ts +29 -0
- package/typescript/core/types/statement.ts +47 -0
- package/typescript/core/types/value.ts +29 -0
- package/typescript/index.ts +7 -2
- package/typescript/pkg/devalang_core.d.ts +4 -0
- package/typescript/scripts/copy-wasm-dts.ts +41 -0
- package/typescript/scripts/postinstall.ts +45 -32
- package/rust/cli/bank.rs +0 -462
- package/rust/cli/build.rs +0 -252
- package/rust/cli/generator.rs +0 -1
- package/rust/cli/play.rs +0 -1123
- package/rust/cli/telemetry.rs +0 -19
- package/rust/common/api.rs +0 -5
- package/rust/common/cdn.rs +0 -5
- package/rust/config/loader.rs +0 -165
- package/rust/config/stats.rs +0 -257
- package/rust/core/audio/engine.rs +0 -696
- package/rust/core/shared/bank.rs +0 -21
- package/rust/core/shared/duration.rs +0 -9
- package/rust/core/shared/mod.rs +0 -3
- package/rust/core/shared/value.rs +0 -35
- package/rust/core/utils/validation.rs +0 -35
- package/rust/installer/bank.rs +0 -62
- package/rust/installer/plugin.rs +0 -54
- package/rust/installer/utils.rs +0 -56
- package/rust/utils/file.rs +0 -38
- package/rust/utils/first_usage.rs +0 -76
- package/rust/utils/signature.rs +0 -19
- package/rust/utils/telemetry.rs +0 -292
- package/rust/utils/version.rs +0 -15
- /package/rust/{common → web}/mod.rs +0 -0
- /package/rust/{common → web}/sso.rs +0 -0
|
@@ -4,7 +4,7 @@ pub fn handle_rparen_lexer(
|
|
|
4
4
|
ch: char,
|
|
5
5
|
_chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
6
6
|
current_indent: &mut usize,
|
|
7
|
-
_indent_stack: &mut
|
|
7
|
+
_indent_stack: &mut [usize],
|
|
8
8
|
tokens: &mut Vec<Token>,
|
|
9
9
|
line: &mut usize,
|
|
10
10
|
column: &mut usize,
|
|
@@ -24,7 +24,7 @@ pub fn handle_lparen_lexer(
|
|
|
24
24
|
ch: char,
|
|
25
25
|
_chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
26
26
|
current_indent: &mut usize,
|
|
27
|
-
_indent_stack: &mut
|
|
27
|
+
_indent_stack: &mut [usize],
|
|
28
28
|
tokens: &mut Vec<Token>,
|
|
29
29
|
line: &mut usize,
|
|
30
30
|
column: &mut usize,
|
package/rust/core/lexer/mod.rs
CHANGED
|
@@ -10,6 +10,12 @@ use std::path::Path;
|
|
|
10
10
|
|
|
11
11
|
pub struct Lexer {}
|
|
12
12
|
|
|
13
|
+
impl Default for Lexer {
|
|
14
|
+
fn default() -> Self {
|
|
15
|
+
Self::new()
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
impl Lexer {
|
|
14
20
|
pub fn new() -> Self {
|
|
15
21
|
Lexer {}
|
|
@@ -19,36 +25,40 @@ impl Lexer {
|
|
|
19
25
|
handle_content_lexing(source.to_string())
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
pub fn lex_tokens(&self, entrypoint: &str) -> Vec<Token> {
|
|
28
|
+
pub fn lex_tokens(&self, entrypoint: &str) -> Result<Vec<Token>, String> {
|
|
23
29
|
let path = normalize_path(entrypoint);
|
|
24
|
-
let resolved_path = Self::resolve_entry_path(&path)
|
|
30
|
+
let resolved_path = Self::resolve_entry_path(&path)?;
|
|
25
31
|
|
|
26
|
-
let file_content =
|
|
27
|
-
|
|
32
|
+
let file_content = fs::read_to_string(&resolved_path).map_err(|e| {
|
|
33
|
+
format!(
|
|
34
|
+
"Failed to read the entrypoint file '{}': {}",
|
|
35
|
+
resolved_path, e
|
|
36
|
+
)
|
|
37
|
+
})?;
|
|
28
38
|
|
|
29
|
-
handle_content_lexing(file_content).
|
|
39
|
+
handle_content_lexing(file_content).map_err(|e| format!("Failed to lex the content: {}", e))
|
|
30
40
|
}
|
|
31
41
|
|
|
32
|
-
fn resolve_entry_path(path: &str) -> String {
|
|
42
|
+
fn resolve_entry_path(path: &str) -> Result<String, String> {
|
|
33
43
|
let candidate = Path::new(path);
|
|
34
44
|
|
|
35
45
|
if candidate.is_dir() {
|
|
36
46
|
let index_path = candidate.join("index.deva");
|
|
37
47
|
if index_path.exists() {
|
|
38
|
-
|
|
48
|
+
Ok(index_path.to_string_lossy().replace("\\", "/"))
|
|
39
49
|
} else {
|
|
40
|
-
|
|
50
|
+
Err(format!(
|
|
41
51
|
"Expected 'index.deva' in directory '{}', but it was not found",
|
|
42
52
|
path
|
|
43
|
-
)
|
|
53
|
+
))
|
|
44
54
|
}
|
|
45
55
|
} else if candidate.is_file() {
|
|
46
|
-
return path.to_string();
|
|
56
|
+
return Ok(path.to_string());
|
|
47
57
|
} else {
|
|
48
|
-
|
|
58
|
+
return Err(format!(
|
|
49
59
|
"Provided entrypoint '{}' is not a valid file or directory",
|
|
50
60
|
path
|
|
51
|
-
);
|
|
61
|
+
));
|
|
52
62
|
}
|
|
53
63
|
}
|
|
54
64
|
}
|
package/rust/core/lexer/token.rs
CHANGED
|
@@ -1,97 +1,90 @@
|
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// ─────
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// ───── Special / Internal ─────
|
|
93
|
-
Whitespace,
|
|
94
|
-
Unknown,
|
|
95
|
-
Error(String),
|
|
96
|
-
EOF,
|
|
97
|
-
}
|
|
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
|
+
matches!(&self.kind, TokenKind::Error(_))
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
19
|
+
pub enum TokenKind {
|
|
20
|
+
// ───── Keywords ─────
|
|
21
|
+
At,
|
|
22
|
+
Tempo,
|
|
23
|
+
Bank,
|
|
24
|
+
Loop,
|
|
25
|
+
Function,
|
|
26
|
+
As,
|
|
27
|
+
On,
|
|
28
|
+
Emit,
|
|
29
|
+
|
|
30
|
+
// ───── Instruments ─────
|
|
31
|
+
Synth,
|
|
32
|
+
|
|
33
|
+
// ───── Literals ─────
|
|
34
|
+
Identifier,
|
|
35
|
+
Number,
|
|
36
|
+
String,
|
|
37
|
+
Boolean,
|
|
38
|
+
Arrow,
|
|
39
|
+
|
|
40
|
+
// ───── Structures ─────
|
|
41
|
+
Map,
|
|
42
|
+
Array,
|
|
43
|
+
|
|
44
|
+
// ───── Symbols ─────
|
|
45
|
+
Colon,
|
|
46
|
+
Comma,
|
|
47
|
+
Equals,
|
|
48
|
+
Dot,
|
|
49
|
+
Slash,
|
|
50
|
+
Plus,
|
|
51
|
+
Asterisk,
|
|
52
|
+
Minus,
|
|
53
|
+
|
|
54
|
+
// ───── Operators ─────
|
|
55
|
+
DoubleEquals,
|
|
56
|
+
NotEquals,
|
|
57
|
+
GreaterEqual,
|
|
58
|
+
LessEqual,
|
|
59
|
+
Greater,
|
|
60
|
+
Less,
|
|
61
|
+
|
|
62
|
+
// ───── Brackets ─────
|
|
63
|
+
LBrace, // {
|
|
64
|
+
RBrace, // }
|
|
65
|
+
LBracket, // [
|
|
66
|
+
RBracket, // ]
|
|
67
|
+
LParen, // (
|
|
68
|
+
RParen, // )
|
|
69
|
+
|
|
70
|
+
// ───── Quotes ─────
|
|
71
|
+
Quote, // '
|
|
72
|
+
DbQuote, // "
|
|
73
|
+
|
|
74
|
+
// ───── Formatting ─────
|
|
75
|
+
Newline,
|
|
76
|
+
Indent,
|
|
77
|
+
Dedent,
|
|
78
|
+
Comment,
|
|
79
|
+
|
|
80
|
+
// ───── Conditions ─────
|
|
81
|
+
If,
|
|
82
|
+
Else,
|
|
83
|
+
ElseIf,
|
|
84
|
+
|
|
85
|
+
// ───── Special / Internal ─────
|
|
86
|
+
Whitespace,
|
|
87
|
+
Unknown,
|
|
88
|
+
Error(String),
|
|
89
|
+
EOF,
|
|
90
|
+
}
|
package/rust/core/mod.rs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
use devalang_types::Value;
|
|
2
|
+
|
|
1
3
|
use crate::core::{
|
|
2
4
|
lexer::token::{Token, TokenKind},
|
|
3
5
|
parser::{
|
|
@@ -7,13 +9,15 @@ use crate::core::{
|
|
|
7
9
|
bank::parse_bank_token,
|
|
8
10
|
condition::parse_condition_token,
|
|
9
11
|
dot::parse_dot_token,
|
|
10
|
-
identifier::{
|
|
12
|
+
identifier::{
|
|
13
|
+
emit::parse_emit_token, function::parse_function_token, on::parse_on_token,
|
|
14
|
+
parse_identifier_token,
|
|
15
|
+
},
|
|
11
16
|
loop_::parse_loop_token,
|
|
12
17
|
tempo::parse_tempo_token,
|
|
13
18
|
},
|
|
14
19
|
statement::Statement,
|
|
15
20
|
},
|
|
16
|
-
shared::value::Value,
|
|
17
21
|
store::global::GlobalStore,
|
|
18
22
|
};
|
|
19
23
|
|
|
@@ -26,6 +30,12 @@ pub struct Parser {
|
|
|
26
30
|
pub previous: Option<Token>,
|
|
27
31
|
}
|
|
28
32
|
|
|
33
|
+
impl Default for Parser {
|
|
34
|
+
fn default() -> Self {
|
|
35
|
+
Self::new()
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
29
39
|
impl Parser {
|
|
30
40
|
pub fn new() -> Self {
|
|
31
41
|
Parser {
|
|
@@ -53,7 +63,7 @@ impl Parser {
|
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
pub fn peek_is(&self, expected: &str) -> bool {
|
|
56
|
-
self.peek().
|
|
66
|
+
self.peek().is_some_and(|t| t.lexeme == expected)
|
|
57
67
|
}
|
|
58
68
|
|
|
59
69
|
pub fn peek_nth(&self, n: usize) -> Option<&Token> {
|
|
@@ -69,7 +79,7 @@ impl Parser {
|
|
|
69
79
|
}
|
|
70
80
|
|
|
71
81
|
pub fn advance_if(&mut self, kind: TokenKind) -> bool {
|
|
72
|
-
|
|
82
|
+
self.match_token(kind)
|
|
73
83
|
}
|
|
74
84
|
|
|
75
85
|
pub fn match_token(&mut self, kind: TokenKind) -> bool {
|
|
@@ -149,8 +159,8 @@ impl Parser {
|
|
|
149
159
|
TokenKind::Loop => parse_loop_token(self, global_store),
|
|
150
160
|
TokenKind::If => parse_condition_token(self, global_store),
|
|
151
161
|
TokenKind::Function => parse_function_token(self, global_store),
|
|
152
|
-
TokenKind::On =>
|
|
153
|
-
TokenKind::Emit =>
|
|
162
|
+
TokenKind::On => parse_on_token(self, global_store),
|
|
163
|
+
TokenKind::Emit => parse_emit_token(self, token.clone(), global_store),
|
|
154
164
|
|
|
155
165
|
| TokenKind::Else // Ignore else, already handled in `parse_condition_token`
|
|
156
166
|
| TokenKind::Comment
|
|
@@ -173,7 +183,7 @@ impl Parser {
|
|
|
173
183
|
|
|
174
184
|
_ => {
|
|
175
185
|
self.advance();
|
|
176
|
-
Statement::
|
|
186
|
+
Statement::unknown_with_pos(token.indent, token.line, token.column)
|
|
177
187
|
}
|
|
178
188
|
};
|
|
179
189
|
|
|
@@ -184,7 +194,7 @@ impl Parser {
|
|
|
184
194
|
}
|
|
185
195
|
|
|
186
196
|
pub fn check_token(&self, kind: TokenKind) -> bool {
|
|
187
|
-
self.peek().
|
|
197
|
+
self.peek().is_some_and(|t| t.kind == kind)
|
|
188
198
|
}
|
|
189
199
|
|
|
190
200
|
pub fn peek_kind(&self) -> Option<TokenKind> {
|
|
@@ -285,8 +295,34 @@ impl Parser {
|
|
|
285
295
|
}
|
|
286
296
|
|
|
287
297
|
TokenKind::Identifier => {
|
|
298
|
+
// Support dotted identifiers in map values: alias.param or nested
|
|
299
|
+
let current_line = token.line;
|
|
300
|
+
let mut parts: Vec<String> = vec![token.lexeme.clone()];
|
|
288
301
|
self.advance();
|
|
289
|
-
|
|
302
|
+
loop {
|
|
303
|
+
let Some(next) = self.peek_clone() else { break };
|
|
304
|
+
if next.line != current_line {
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
if next.kind == TokenKind::Dot {
|
|
308
|
+
// Consume '.' and the following identifier/number on same line
|
|
309
|
+
self.advance(); // dot
|
|
310
|
+
if let Some(id2) = self.peek_clone() {
|
|
311
|
+
if id2.line == current_line
|
|
312
|
+
&& (id2.kind == TokenKind::Identifier
|
|
313
|
+
|| id2.kind == TokenKind::Number)
|
|
314
|
+
{
|
|
315
|
+
parts.push(id2.lexeme.clone());
|
|
316
|
+
self.advance(); // consume part
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
break;
|
|
321
|
+
} else {
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
Value::Identifier(parts.join("."))
|
|
290
326
|
}
|
|
291
327
|
_ => {
|
|
292
328
|
println!("Unexpected token in map value: {:?}", token);
|
|
@@ -430,7 +466,12 @@ impl Parser {
|
|
|
430
466
|
if tok.indent <= base_indent && tok.kind != TokenKind::Newline {
|
|
431
467
|
break;
|
|
432
468
|
}
|
|
433
|
-
|
|
469
|
+
if let Some(t) = self.advance() {
|
|
470
|
+
tokens.push(t.clone());
|
|
471
|
+
} else {
|
|
472
|
+
// Unexpected EOF while collecting block tokens: stop collecting
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
434
475
|
}
|
|
435
476
|
|
|
436
477
|
tokens
|
|
@@ -448,7 +489,11 @@ impl Parser {
|
|
|
448
489
|
if token.kind == TokenKind::EOF {
|
|
449
490
|
break;
|
|
450
491
|
}
|
|
451
|
-
|
|
492
|
+
if let Some(t) = self.advance() {
|
|
493
|
+
collected.push(t.clone());
|
|
494
|
+
} else {
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
452
497
|
}
|
|
453
498
|
|
|
454
499
|
collected
|
|
@@ -470,7 +515,11 @@ impl Parser {
|
|
|
470
515
|
if tok.lexeme == "else" && tok.indent == base_indent {
|
|
471
516
|
break;
|
|
472
517
|
}
|
|
473
|
-
|
|
518
|
+
if let Some(t) = self.advance() {
|
|
519
|
+
block_tokens.push(t.clone());
|
|
520
|
+
} else {
|
|
521
|
+
break;
|
|
522
|
+
}
|
|
474
523
|
}
|
|
475
524
|
|
|
476
525
|
self.parse_block(block_tokens, global_store)
|
|
@@ -505,7 +554,11 @@ impl Parser {
|
|
|
505
554
|
if tok.indent < base_indent && tok.kind != TokenKind::Newline {
|
|
506
555
|
break;
|
|
507
556
|
}
|
|
508
|
-
|
|
557
|
+
if let Some(t) = self.advance() {
|
|
558
|
+
tokens.push(t.clone());
|
|
559
|
+
} else {
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
509
562
|
}
|
|
510
563
|
|
|
511
564
|
self.parse_block(tokens, global_store)
|
|
@@ -4,9 +4,9 @@ use crate::core::{
|
|
|
4
4
|
driver::Parser,
|
|
5
5
|
statement::{Statement, StatementKind},
|
|
6
6
|
},
|
|
7
|
-
shared::value::Value,
|
|
8
7
|
store::global::GlobalStore,
|
|
9
8
|
};
|
|
9
|
+
use devalang_types::Value;
|
|
10
10
|
|
|
11
11
|
fn parse_map_literal(parser: &mut Parser) -> Value {
|
|
12
12
|
// Assumes '{' has already been consumed by caller
|
|
@@ -126,28 +126,48 @@ pub fn parse_arrow_call(parser: &mut Parser, _global_store: &mut GlobalStore) ->
|
|
|
126
126
|
|
|
127
127
|
if target_token.kind != TokenKind::Identifier {
|
|
128
128
|
parser.advance(); // consume target token
|
|
129
|
-
return Statement::
|
|
129
|
+
return Statement::unknown_with_pos(
|
|
130
|
+
target_token.indent,
|
|
131
|
+
target_token.line,
|
|
132
|
+
target_token.column,
|
|
133
|
+
);
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
let Some(arrow_token) = parser.peek_nth(1).cloned() else {
|
|
133
137
|
parser.advance(); // consume arrow token
|
|
134
|
-
return Statement::
|
|
138
|
+
return Statement::unknown_with_pos(
|
|
139
|
+
target_token.indent,
|
|
140
|
+
target_token.line,
|
|
141
|
+
target_token.column,
|
|
142
|
+
);
|
|
135
143
|
};
|
|
136
144
|
|
|
137
145
|
if arrow_token.kind != TokenKind::Arrow {
|
|
138
146
|
parser.advance(); // consume method token
|
|
139
|
-
return Statement::
|
|
147
|
+
return Statement::unknown_with_pos(
|
|
148
|
+
target_token.indent,
|
|
149
|
+
target_token.line,
|
|
150
|
+
target_token.column,
|
|
151
|
+
);
|
|
140
152
|
}
|
|
141
153
|
|
|
142
154
|
// We have a valid arrow call, so we consume the arrow token
|
|
143
155
|
let Some(method_token) = parser.peek_nth(2).cloned() else {
|
|
144
156
|
parser.advance();
|
|
145
|
-
return Statement::
|
|
157
|
+
return Statement::unknown_with_pos(
|
|
158
|
+
target_token.indent,
|
|
159
|
+
target_token.line,
|
|
160
|
+
target_token.column,
|
|
161
|
+
);
|
|
146
162
|
};
|
|
147
163
|
|
|
148
164
|
if method_token.kind != TokenKind::Identifier {
|
|
149
165
|
parser.advance();
|
|
150
|
-
return Statement::
|
|
166
|
+
return Statement::unknown_with_pos(
|
|
167
|
+
method_token.indent,
|
|
168
|
+
method_token.line,
|
|
169
|
+
method_token.column,
|
|
170
|
+
);
|
|
151
171
|
}
|
|
152
172
|
|
|
153
173
|
// Consume the tokens for target, arrow, and method
|
|
@@ -202,10 +222,10 @@ pub fn parse_arrow_call(parser: &mut Parser, _global_store: &mut GlobalStore) ->
|
|
|
202
222
|
TokenKind::Number => Value::Number(token.lexeme.parse::<f32>().unwrap_or(0.0)),
|
|
203
223
|
TokenKind::LBrace => {
|
|
204
224
|
// Handle map literal (supports nested maps)
|
|
205
|
-
|
|
225
|
+
|
|
206
226
|
// We consumed the matching '}', so outer map_depth should be decremented
|
|
207
227
|
// if the caller tracks it.
|
|
208
|
-
|
|
228
|
+
parse_map_literal(parser)
|
|
209
229
|
}
|
|
210
230
|
_ => Value::Unknown,
|
|
211
231
|
};
|