@devaloop/devalang 0.0.1-alpha.16-hotfix.3 → 0.0.1-alpha.18
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 +10 -10
- package/.github/workflows/ci.yml +0 -1
- package/Cargo.toml +18 -2
- package/README.md +82 -34
- package/docs/CHANGELOG.md +91 -0
- package/docs/ROADMAP.md +7 -4
- package/docs/TODO.md +1 -1
- package/examples/index.deva +55 -35
- package/examples/pattern.deva +5 -5
- 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 +107 -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/cli/install/addon.rs +126 -0
- 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 -2
- package/rust/cli/{driver.rs → parser.rs} +7 -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.rs → telemetry/commands.rs} +4 -4
- 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 +40 -42
- package/rust/core/audio/engine/helpers.rs +158 -0
- package/rust/core/audio/engine/mod.rs +7 -0
- package/rust/core/audio/engine/sample.rs +359 -0
- package/rust/core/audio/engine/synth.rs +325 -0
- package/rust/core/audio/evaluator.rs +68 -27
- package/rust/core/audio/interpreter/arrow_call.rs +113 -33
- package/rust/core/audio/interpreter/call.rs +232 -56
- 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 +186 -54
- 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 +26 -6
- 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/driver.rs +61 -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 +4 -3
- 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 +1 -52
- package/rust/core/lexer/token.rs +91 -97
- package/rust/core/mod.rs +0 -1
- package/rust/core/parser/driver.rs +78 -22
- 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 +5 -3
- 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 +38 -13
- package/rust/core/parser/handler/mod.rs +1 -0
- package/rust/core/parser/handler/pattern.rs +74 -0
- 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 +181 -99
- package/rust/core/preprocessor/processor.rs +9 -9
- package/rust/core/preprocessor/resolver/bank.rs +6 -8
- package/rust/core/preprocessor/resolver/call.rs +47 -23
- package/rust/core/preprocessor/resolver/condition.rs +6 -8
- package/rust/core/preprocessor/resolver/driver.rs +28 -28
- 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/mod.rs +1 -0
- package/rust/core/preprocessor/resolver/pattern.rs +75 -0
- package/rust/core/preprocessor/resolver/spawn.rs +45 -22
- 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 +16 -2
- package/rust/core/utils/mod.rs +0 -1
- package/rust/lib.rs +102 -9
- package/rust/main.rs +159 -45
- package/rust/types/Cargo.toml +11 -0
- package/rust/types/src/addons.rs +55 -0
- package/rust/types/src/ast.rs +202 -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 +26 -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/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/rust/cli/bank.rs +0 -462
- package/rust/cli/build.rs +0 -252
- package/rust/cli/play.rs +0 -1123
- 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/addon.rs +0 -84
- 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 -83
- 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}/api.rs +0 -0
- /package/rust/{common → web}/mod.rs +0 -0
- /package/rust/{common → web}/sso.rs +0 -0
package/rust/core/lexer/token.rs
CHANGED
|
@@ -1,97 +1,91 @@
|
|
|
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
|
+
Pattern,
|
|
25
|
+
Loop,
|
|
26
|
+
Function,
|
|
27
|
+
As,
|
|
28
|
+
On,
|
|
29
|
+
Emit,
|
|
30
|
+
|
|
31
|
+
// ───── Instruments ─────
|
|
32
|
+
Synth,
|
|
33
|
+
|
|
34
|
+
// ───── Literals ─────
|
|
35
|
+
Identifier,
|
|
36
|
+
Number,
|
|
37
|
+
String,
|
|
38
|
+
Boolean,
|
|
39
|
+
Arrow,
|
|
40
|
+
|
|
41
|
+
// ───── Structures ─────
|
|
42
|
+
Map,
|
|
43
|
+
Array,
|
|
44
|
+
|
|
45
|
+
// ───── Symbols ─────
|
|
46
|
+
Colon,
|
|
47
|
+
Comma,
|
|
48
|
+
Equals,
|
|
49
|
+
Dot,
|
|
50
|
+
Slash,
|
|
51
|
+
Plus,
|
|
52
|
+
Asterisk,
|
|
53
|
+
Minus,
|
|
54
|
+
|
|
55
|
+
// ───── Operators ─────
|
|
56
|
+
DoubleEquals,
|
|
57
|
+
NotEquals,
|
|
58
|
+
GreaterEqual,
|
|
59
|
+
LessEqual,
|
|
60
|
+
Greater,
|
|
61
|
+
Less,
|
|
62
|
+
|
|
63
|
+
// ───── Brackets ─────
|
|
64
|
+
LBrace, // {
|
|
65
|
+
RBrace, // }
|
|
66
|
+
LBracket, // [
|
|
67
|
+
RBracket, // ]
|
|
68
|
+
LParen, // (
|
|
69
|
+
RParen, // )
|
|
70
|
+
|
|
71
|
+
// ───── Quotes ─────
|
|
72
|
+
Quote, // '
|
|
73
|
+
DbQuote, // "
|
|
74
|
+
|
|
75
|
+
// ───── Formatting ─────
|
|
76
|
+
Newline,
|
|
77
|
+
Indent,
|
|
78
|
+
Dedent,
|
|
79
|
+
Comment,
|
|
80
|
+
|
|
81
|
+
// ───── Conditions ─────
|
|
82
|
+
If,
|
|
83
|
+
Else,
|
|
84
|
+
ElseIf,
|
|
85
|
+
|
|
86
|
+
// ───── Special / Internal ─────
|
|
87
|
+
Whitespace,
|
|
88
|
+
Unknown,
|
|
89
|
+
Error(String),
|
|
90
|
+
EOF,
|
|
91
|
+
}
|
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,16 @@ use crate::core::{
|
|
|
7
9
|
bank::parse_bank_token,
|
|
8
10
|
condition::parse_condition_token,
|
|
9
11
|
dot::parse_dot_token,
|
|
10
|
-
|
|
12
|
+
pattern::parse_pattern_token,
|
|
13
|
+
identifier::{
|
|
14
|
+
emit::parse_emit_token, function::parse_function_token, on::parse_on_token,
|
|
15
|
+
parse_identifier_token,
|
|
16
|
+
},
|
|
11
17
|
loop_::parse_loop_token,
|
|
12
18
|
tempo::parse_tempo_token,
|
|
13
19
|
},
|
|
14
20
|
statement::Statement,
|
|
15
21
|
},
|
|
16
|
-
shared::value::Value,
|
|
17
22
|
store::global::GlobalStore,
|
|
18
23
|
};
|
|
19
24
|
|
|
@@ -26,6 +31,12 @@ pub struct Parser {
|
|
|
26
31
|
pub previous: Option<Token>,
|
|
27
32
|
}
|
|
28
33
|
|
|
34
|
+
impl Default for Parser {
|
|
35
|
+
fn default() -> Self {
|
|
36
|
+
Self::new()
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
29
40
|
impl Parser {
|
|
30
41
|
pub fn new() -> Self {
|
|
31
42
|
Parser {
|
|
@@ -53,7 +64,7 @@ impl Parser {
|
|
|
53
64
|
}
|
|
54
65
|
|
|
55
66
|
pub fn peek_is(&self, expected: &str) -> bool {
|
|
56
|
-
self.peek().
|
|
67
|
+
self.peek().is_some_and(|t| t.lexeme == expected)
|
|
57
68
|
}
|
|
58
69
|
|
|
59
70
|
pub fn peek_nth(&self, n: usize) -> Option<&Token> {
|
|
@@ -69,7 +80,7 @@ impl Parser {
|
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
pub fn advance_if(&mut self, kind: TokenKind) -> bool {
|
|
72
|
-
|
|
83
|
+
self.match_token(kind)
|
|
73
84
|
}
|
|
74
85
|
|
|
75
86
|
pub fn match_token(&mut self, kind: TokenKind) -> bool {
|
|
@@ -146,11 +157,12 @@ impl Parser {
|
|
|
146
157
|
TokenKind::Dot => parse_dot_token(self, global_store),
|
|
147
158
|
TokenKind::Tempo => parse_tempo_token(self, global_store),
|
|
148
159
|
TokenKind::Bank => parse_bank_token(self, global_store),
|
|
160
|
+
TokenKind::Pattern => parse_pattern_token(self, global_store),
|
|
149
161
|
TokenKind::Loop => parse_loop_token(self, global_store),
|
|
150
162
|
TokenKind::If => parse_condition_token(self, global_store),
|
|
151
163
|
TokenKind::Function => parse_function_token(self, global_store),
|
|
152
|
-
TokenKind::On =>
|
|
153
|
-
TokenKind::Emit =>
|
|
164
|
+
TokenKind::On => parse_on_token(self, global_store),
|
|
165
|
+
TokenKind::Emit => parse_emit_token(self, token.clone(), global_store),
|
|
154
166
|
|
|
155
167
|
| TokenKind::Else // Ignore else, already handled in `parse_condition_token`
|
|
156
168
|
| TokenKind::Comment
|
|
@@ -173,7 +185,7 @@ impl Parser {
|
|
|
173
185
|
|
|
174
186
|
_ => {
|
|
175
187
|
self.advance();
|
|
176
|
-
Statement::
|
|
188
|
+
Statement::unknown_with_pos(token.indent, token.line, token.column)
|
|
177
189
|
}
|
|
178
190
|
};
|
|
179
191
|
|
|
@@ -184,7 +196,7 @@ impl Parser {
|
|
|
184
196
|
}
|
|
185
197
|
|
|
186
198
|
pub fn check_token(&self, kind: TokenKind) -> bool {
|
|
187
|
-
self.peek().
|
|
199
|
+
self.peek().is_some_and(|t| t.kind == kind)
|
|
188
200
|
}
|
|
189
201
|
|
|
190
202
|
pub fn peek_kind(&self) -> Option<TokenKind> {
|
|
@@ -192,6 +204,8 @@ impl Parser {
|
|
|
192
204
|
}
|
|
193
205
|
|
|
194
206
|
pub fn parse_map_value(&mut self) -> Option<Value> {
|
|
207
|
+
let logger = devalang_utils::logger::Logger::new();
|
|
208
|
+
use devalang_utils::logger::LogLevel;
|
|
195
209
|
if !self.match_token(TokenKind::LBrace) {
|
|
196
210
|
return None;
|
|
197
211
|
}
|
|
@@ -234,7 +248,7 @@ impl Parser {
|
|
|
234
248
|
}
|
|
235
249
|
|
|
236
250
|
if !self.match_token(TokenKind::Colon) {
|
|
237
|
-
|
|
251
|
+
logger.log_message(LogLevel::Error, &format!("Expected ':' after map key '{}'", key));
|
|
238
252
|
break;
|
|
239
253
|
}
|
|
240
254
|
|
|
@@ -268,14 +282,11 @@ impl Parser {
|
|
|
268
282
|
number_str.push('.');
|
|
269
283
|
number_str.push_str(&decimal_token.lexeme);
|
|
270
284
|
} else {
|
|
271
|
-
|
|
272
|
-
"Expected number after dot, got {:?}",
|
|
273
|
-
decimal_token
|
|
274
|
-
);
|
|
285
|
+
logger.log_message(LogLevel::Error, &format!("Expected number after dot, got {:?}", decimal_token));
|
|
275
286
|
return Some(Value::Null);
|
|
276
287
|
}
|
|
277
288
|
} else {
|
|
278
|
-
|
|
289
|
+
logger.log_message(LogLevel::Error, "Expected number after dot, but reached EOF");
|
|
279
290
|
return Some(Value::Null);
|
|
280
291
|
}
|
|
281
292
|
}
|
|
@@ -285,11 +296,37 @@ impl Parser {
|
|
|
285
296
|
}
|
|
286
297
|
|
|
287
298
|
TokenKind::Identifier => {
|
|
299
|
+
// Support dotted identifiers in map values: alias.param or nested
|
|
300
|
+
let current_line = token.line;
|
|
301
|
+
let mut parts: Vec<String> = vec![token.lexeme.clone()];
|
|
288
302
|
self.advance();
|
|
289
|
-
|
|
303
|
+
loop {
|
|
304
|
+
let Some(next) = self.peek_clone() else { break };
|
|
305
|
+
if next.line != current_line {
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
if next.kind == TokenKind::Dot {
|
|
309
|
+
// Consume '.' and the following identifier/number on same line
|
|
310
|
+
self.advance(); // dot
|
|
311
|
+
if let Some(id2) = self.peek_clone() {
|
|
312
|
+
if id2.line == current_line
|
|
313
|
+
&& (id2.kind == TokenKind::Identifier
|
|
314
|
+
|| id2.kind == TokenKind::Number)
|
|
315
|
+
{
|
|
316
|
+
parts.push(id2.lexeme.clone());
|
|
317
|
+
self.advance(); // consume part
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
break;
|
|
322
|
+
} else {
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
Value::Identifier(parts.join("."))
|
|
290
327
|
}
|
|
291
328
|
_ => {
|
|
292
|
-
|
|
329
|
+
logger.log_message(LogLevel::Error, &format!("Unexpected token in map value: {:?}", token));
|
|
293
330
|
Value::Null
|
|
294
331
|
}
|
|
295
332
|
}
|
|
@@ -309,7 +346,7 @@ impl Parser {
|
|
|
309
346
|
}
|
|
310
347
|
|
|
311
348
|
if !self.match_token(TokenKind::RBrace) {
|
|
312
|
-
|
|
349
|
+
logger.log_message(LogLevel::Error, "Expected '}' at end of map");
|
|
313
350
|
}
|
|
314
351
|
|
|
315
352
|
Some(Value::Map(map))
|
|
@@ -317,6 +354,8 @@ impl Parser {
|
|
|
317
354
|
|
|
318
355
|
// Parse an array value like [1, 2, 3] or ["a", b]
|
|
319
356
|
pub fn parse_array_value(&mut self) -> Option<Value> {
|
|
357
|
+
let logger = devalang_utils::logger::Logger::new();
|
|
358
|
+
use devalang_utils::logger::LogLevel;
|
|
320
359
|
if !self.match_token(TokenKind::LBracket) {
|
|
321
360
|
return None;
|
|
322
361
|
}
|
|
@@ -400,7 +439,7 @@ impl Parser {
|
|
|
400
439
|
}
|
|
401
440
|
|
|
402
441
|
if !self.match_token(TokenKind::RBracket) {
|
|
403
|
-
|
|
442
|
+
logger.log_message(LogLevel::Error, "Expected ']' at end of array");
|
|
404
443
|
}
|
|
405
444
|
|
|
406
445
|
Some(Value::Array(arr))
|
|
@@ -430,7 +469,12 @@ impl Parser {
|
|
|
430
469
|
if tok.indent <= base_indent && tok.kind != TokenKind::Newline {
|
|
431
470
|
break;
|
|
432
471
|
}
|
|
433
|
-
|
|
472
|
+
if let Some(t) = self.advance() {
|
|
473
|
+
tokens.push(t.clone());
|
|
474
|
+
} else {
|
|
475
|
+
// Unexpected EOF while collecting block tokens: stop collecting
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
434
478
|
}
|
|
435
479
|
|
|
436
480
|
tokens
|
|
@@ -448,7 +492,11 @@ impl Parser {
|
|
|
448
492
|
if token.kind == TokenKind::EOF {
|
|
449
493
|
break;
|
|
450
494
|
}
|
|
451
|
-
|
|
495
|
+
if let Some(t) = self.advance() {
|
|
496
|
+
collected.push(t.clone());
|
|
497
|
+
} else {
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
452
500
|
}
|
|
453
501
|
|
|
454
502
|
collected
|
|
@@ -470,7 +518,11 @@ impl Parser {
|
|
|
470
518
|
if tok.lexeme == "else" && tok.indent == base_indent {
|
|
471
519
|
break;
|
|
472
520
|
}
|
|
473
|
-
|
|
521
|
+
if let Some(t) = self.advance() {
|
|
522
|
+
block_tokens.push(t.clone());
|
|
523
|
+
} else {
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
474
526
|
}
|
|
475
527
|
|
|
476
528
|
self.parse_block(block_tokens, global_store)
|
|
@@ -505,7 +557,11 @@ impl Parser {
|
|
|
505
557
|
if tok.indent < base_indent && tok.kind != TokenKind::Newline {
|
|
506
558
|
break;
|
|
507
559
|
}
|
|
508
|
-
|
|
560
|
+
if let Some(t) = self.advance() {
|
|
561
|
+
tokens.push(t.clone());
|
|
562
|
+
} else {
|
|
563
|
+
break;
|
|
564
|
+
}
|
|
509
565
|
}
|
|
510
566
|
|
|
511
567
|
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
|
};
|