@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
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
use devalang_types::Value;
|
|
2
|
+
|
|
1
3
|
use crate::core::{
|
|
2
4
|
lexer::token::TokenKind,
|
|
3
5
|
parser::{
|
|
4
6
|
driver::Parser,
|
|
5
7
|
statement::{Statement, StatementKind},
|
|
6
8
|
},
|
|
7
|
-
shared::value::Value,
|
|
8
9
|
store::global::GlobalStore,
|
|
9
10
|
};
|
|
10
11
|
pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> Statement {
|
|
@@ -25,10 +26,13 @@ pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> S
|
|
|
25
26
|
|
|
26
27
|
// Expect plugin author
|
|
27
28
|
let Some(author_token) = parser.peek_clone() else {
|
|
28
|
-
return
|
|
29
|
+
return crate::core::parser::statement::error_from_token(
|
|
30
|
+
use_token,
|
|
31
|
+
"Expected plugin author".to_string(),
|
|
32
|
+
);
|
|
29
33
|
};
|
|
30
34
|
if author_token.kind != TokenKind::Identifier {
|
|
31
|
-
return
|
|
35
|
+
return crate::core::parser::statement::error_from_token(
|
|
32
36
|
author_token,
|
|
33
37
|
"Expected identifier for plugin author".to_string(),
|
|
34
38
|
);
|
|
@@ -37,7 +41,7 @@ pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> S
|
|
|
37
41
|
|
|
38
42
|
// Expect '.'
|
|
39
43
|
if !parser.match_token(TokenKind::Dot) {
|
|
40
|
-
return
|
|
44
|
+
return crate::core::parser::statement::error_from_token(
|
|
41
45
|
author_token,
|
|
42
46
|
"Expected '.' after plugin author".to_string(),
|
|
43
47
|
);
|
|
@@ -45,7 +49,10 @@ pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> S
|
|
|
45
49
|
|
|
46
50
|
// Expect plugin name
|
|
47
51
|
let Some(plugin_token) = parser.peek_clone() else {
|
|
48
|
-
return
|
|
52
|
+
return crate::core::parser::statement::error_from_token(
|
|
53
|
+
author_token,
|
|
54
|
+
"Expected plugin name".to_string(),
|
|
55
|
+
);
|
|
49
56
|
};
|
|
50
57
|
|
|
51
58
|
let name = match plugin_token.kind {
|
|
@@ -54,7 +61,7 @@ pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> S
|
|
|
54
61
|
format!("{}.{}", author_token.lexeme, plugin_token.lexeme)
|
|
55
62
|
}
|
|
56
63
|
_ => {
|
|
57
|
-
return
|
|
64
|
+
return crate::core::parser::statement::error_from_token(
|
|
58
65
|
plugin_token,
|
|
59
66
|
"Expected identifier or number for plugin name".to_string(),
|
|
60
67
|
);
|
|
@@ -64,13 +71,13 @@ pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> S
|
|
|
64
71
|
// Optional alias
|
|
65
72
|
let alias = if parser.match_token(TokenKind::As) {
|
|
66
73
|
let Some(alias_token) = parser.peek_clone() else {
|
|
67
|
-
return
|
|
74
|
+
return crate::core::parser::statement::error_from_token(
|
|
68
75
|
use_token,
|
|
69
76
|
"Expected identifier after 'as'".to_string(),
|
|
70
77
|
);
|
|
71
78
|
};
|
|
72
79
|
if alias_token.kind != TokenKind::Identifier {
|
|
73
|
-
return
|
|
80
|
+
return crate::core::parser::statement::error_from_token(
|
|
74
81
|
alias_token,
|
|
75
82
|
"Expected identifier after 'as'".to_string(),
|
|
76
83
|
);
|
|
@@ -97,7 +104,10 @@ pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> S
|
|
|
97
104
|
parser.advance(); // consume 'import'
|
|
98
105
|
|
|
99
106
|
if !parser.match_token(TokenKind::LBrace) {
|
|
100
|
-
return
|
|
107
|
+
return crate::core::parser::statement::error_from_token(
|
|
108
|
+
token,
|
|
109
|
+
"Expected '{{' after 'import'".to_string(),
|
|
110
|
+
);
|
|
101
111
|
}
|
|
102
112
|
|
|
103
113
|
let mut names = Vec::new();
|
|
@@ -117,27 +127,42 @@ pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> S
|
|
|
117
127
|
_ => {
|
|
118
128
|
let message =
|
|
119
129
|
format!("Unexpected token in import list: {:?}", token.kind.clone());
|
|
120
|
-
return
|
|
130
|
+
return crate::core::parser::statement::error_from_token(
|
|
131
|
+
token.clone(),
|
|
132
|
+
message,
|
|
133
|
+
);
|
|
121
134
|
}
|
|
122
135
|
}
|
|
123
136
|
}
|
|
124
137
|
|
|
125
138
|
let Some(from_token) = parser.peek_clone() else {
|
|
126
|
-
return
|
|
139
|
+
return crate::core::parser::statement::error_from_token(
|
|
140
|
+
token,
|
|
141
|
+
"Expected 'from' after import list".to_string(),
|
|
142
|
+
);
|
|
127
143
|
};
|
|
128
144
|
|
|
129
145
|
if from_token.lexeme != "from" {
|
|
130
|
-
return
|
|
146
|
+
return crate::core::parser::statement::error_from_token(
|
|
147
|
+
token,
|
|
148
|
+
"Expected keyword 'from'".to_string(),
|
|
149
|
+
);
|
|
131
150
|
}
|
|
132
151
|
|
|
133
152
|
parser.advance(); // consume 'from'
|
|
134
153
|
|
|
135
154
|
let Some(source_token) = parser.peek() else {
|
|
136
|
-
return
|
|
155
|
+
return crate::core::parser::statement::error_from_token(
|
|
156
|
+
token,
|
|
157
|
+
"Expected string after 'from'".to_string(),
|
|
158
|
+
);
|
|
137
159
|
};
|
|
138
160
|
|
|
139
161
|
if source_token.kind != TokenKind::String {
|
|
140
|
-
return
|
|
162
|
+
return crate::core::parser::statement::error_from_token(
|
|
163
|
+
token,
|
|
164
|
+
"Expected string after 'from'".to_string(),
|
|
165
|
+
);
|
|
141
166
|
}
|
|
142
167
|
|
|
143
168
|
let source = source_token.lexeme.clone();
|
|
@@ -168,7 +193,10 @@ pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> S
|
|
|
168
193
|
} else if token.kind == TokenKind::RBrace {
|
|
169
194
|
break; // Stop at the closing brace
|
|
170
195
|
} else {
|
|
171
|
-
return
|
|
196
|
+
return crate::core::parser::statement::error_from_token(
|
|
197
|
+
token,
|
|
198
|
+
"Unexpected token in export list".to_string(),
|
|
199
|
+
);
|
|
172
200
|
}
|
|
173
201
|
}
|
|
174
202
|
|
|
@@ -189,11 +217,17 @@ pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> S
|
|
|
189
217
|
|
|
190
218
|
// Example: @load "preset.mydeva"
|
|
191
219
|
let Some(path_token) = parser.peek() else {
|
|
192
|
-
return
|
|
220
|
+
return crate::core::parser::statement::error_from_token(
|
|
221
|
+
token,
|
|
222
|
+
"Expected string after 'load'".to_string(),
|
|
223
|
+
);
|
|
193
224
|
};
|
|
194
225
|
|
|
195
226
|
if path_token.kind != TokenKind::String {
|
|
196
|
-
return
|
|
227
|
+
return crate::core::parser::statement::error_from_token(
|
|
228
|
+
token,
|
|
229
|
+
"Expected string after 'load'".to_string(),
|
|
230
|
+
);
|
|
197
231
|
}
|
|
198
232
|
|
|
199
233
|
let path = path_token.lexeme.clone();
|
|
@@ -201,21 +235,21 @@ pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> S
|
|
|
201
235
|
parser.advance(); // consume string
|
|
202
236
|
|
|
203
237
|
if !parser.match_token(TokenKind::As) {
|
|
204
|
-
return
|
|
238
|
+
return crate::core::parser::statement::error_from_token(
|
|
205
239
|
token,
|
|
206
240
|
"Expected 'as' after path in load statement".to_string(),
|
|
207
241
|
);
|
|
208
242
|
}
|
|
209
243
|
|
|
210
244
|
let Some(alias_token) = parser.peek_clone() else {
|
|
211
|
-
return
|
|
245
|
+
return crate::core::parser::statement::error_from_token(
|
|
212
246
|
token,
|
|
213
247
|
"Expected identifier after 'as' in load statement".to_string(),
|
|
214
248
|
);
|
|
215
249
|
};
|
|
216
250
|
|
|
217
251
|
if alias_token.kind != TokenKind::Identifier {
|
|
218
|
-
return
|
|
252
|
+
return crate::core::parser::statement::error_from_token(
|
|
219
253
|
token,
|
|
220
254
|
"Expected identifier after 'as' in load statement".to_string(),
|
|
221
255
|
);
|
|
@@ -239,7 +273,7 @@ pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> S
|
|
|
239
273
|
|
|
240
274
|
_ => {
|
|
241
275
|
let message = format!("Unknown keyword after '@' : {}", keyword);
|
|
242
|
-
|
|
276
|
+
crate::core::parser::statement::error_from_token(token, message)
|
|
243
277
|
}
|
|
244
278
|
}
|
|
245
279
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
use devalang_types::Value;
|
|
2
|
+
|
|
1
3
|
use crate::core::{
|
|
2
4
|
lexer::token::TokenKind,
|
|
3
5
|
parser::{
|
|
4
6
|
driver::Parser,
|
|
5
7
|
statement::{Statement, StatementKind},
|
|
6
8
|
},
|
|
7
|
-
shared::value::Value,
|
|
8
9
|
store::global::GlobalStore,
|
|
9
10
|
};
|
|
10
11
|
|
|
@@ -66,7 +67,10 @@ pub fn parse_bank_token(parser: &mut Parser, _global_store: &mut GlobalStore) ->
|
|
|
66
67
|
};
|
|
67
68
|
|
|
68
69
|
if matches!(bank_value, Value::Unknown | Value::Null) {
|
|
69
|
-
return
|
|
70
|
+
return crate::core::parser::statement::error_from_token(
|
|
71
|
+
bank_tok,
|
|
72
|
+
"Expected a bank name".to_string(),
|
|
73
|
+
);
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
// Optional alias: as <identifier>
|
|
@@ -75,10 +79,16 @@ pub fn parse_bank_token(parser: &mut Parser, _global_store: &mut GlobalStore) ->
|
|
|
75
79
|
// consume 'as'
|
|
76
80
|
parser.advance();
|
|
77
81
|
let Some(next) = parser.peek_clone() else {
|
|
78
|
-
return
|
|
82
|
+
return crate::core::parser::statement::error_from_token(
|
|
83
|
+
bank_tok,
|
|
84
|
+
"Expected identifier after 'as'".to_string(),
|
|
85
|
+
);
|
|
79
86
|
};
|
|
80
87
|
if next.kind != TokenKind::Identifier {
|
|
81
|
-
return
|
|
88
|
+
return crate::core::parser::statement::error_from_token(
|
|
89
|
+
next,
|
|
90
|
+
"Expected identifier after 'as'".to_string(),
|
|
91
|
+
);
|
|
82
92
|
}
|
|
83
93
|
parser.advance();
|
|
84
94
|
alias = Some(next.lexeme.clone());
|
|
@@ -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
|
use std::collections::HashMap;
|
|
11
11
|
|
|
12
12
|
pub fn parse_condition_token(parser: &mut Parser, global_store: &mut GlobalStore) -> Statement {
|
|
@@ -16,7 +16,10 @@ pub fn parse_condition_token(parser: &mut Parser, global_store: &mut GlobalStore
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
let Some(condition) = parser.parse_condition_until_colon() else {
|
|
19
|
-
return
|
|
19
|
+
return crate::core::parser::statement::error_from_token(
|
|
20
|
+
if_token,
|
|
21
|
+
"Expected condition after 'if'".to_string(),
|
|
22
|
+
);
|
|
20
23
|
};
|
|
21
24
|
|
|
22
25
|
parser.advance_if(TokenKind::Colon);
|
|
@@ -43,7 +46,7 @@ pub fn parse_condition_token(parser: &mut Parser, global_store: &mut GlobalStore
|
|
|
43
46
|
let next_condition = if parser.peek_is("if") {
|
|
44
47
|
parser.advance(); // consume 'if'
|
|
45
48
|
let Some(cond) = parser.parse_condition_until_colon() else {
|
|
46
|
-
return
|
|
49
|
+
return crate::core::parser::statement::error_from_token(
|
|
47
50
|
tok.clone(),
|
|
48
51
|
"Expected condition after 'else if'".to_string(),
|
|
49
52
|
);
|
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
use std::collections::HashMap;
|
|
2
|
-
|
|
3
1
|
use crate::core::{
|
|
4
2
|
lexer::token::{Token, TokenKind},
|
|
5
3
|
parser::{
|
|
6
4
|
driver::Parser,
|
|
7
5
|
statement::{Statement, StatementKind},
|
|
8
6
|
},
|
|
9
|
-
shared::value::Value,
|
|
10
7
|
store::global::GlobalStore,
|
|
11
8
|
};
|
|
9
|
+
use devalang_types::Value;
|
|
10
|
+
use std::collections::HashMap;
|
|
12
11
|
|
|
13
|
-
// Grammar:
|
|
14
|
-
// automate <identifier>:
|
|
15
|
-
// param <name> { <percent>% = <number> ... }
|
|
16
|
-
// Produces StatementKind::Automate with value map:
|
|
17
|
-
// { target: Identifier, params: Map<paramName, Map<percent, Number>> }
|
|
18
12
|
pub fn parse_automate_token(
|
|
19
13
|
parser: &mut Parser,
|
|
20
14
|
current_token: Token,
|
|
@@ -24,14 +18,14 @@ pub fn parse_automate_token(
|
|
|
24
18
|
|
|
25
19
|
// Expect target identifier
|
|
26
20
|
let Some(target_token) = parser.peek_clone() else {
|
|
27
|
-
return
|
|
21
|
+
return crate::core::parser::statement::error_from_token(
|
|
28
22
|
current_token,
|
|
29
23
|
"Expected target after 'automate'".to_string(),
|
|
30
24
|
);
|
|
31
25
|
};
|
|
32
26
|
|
|
33
27
|
if target_token.kind != TokenKind::Identifier && target_token.kind != TokenKind::String {
|
|
34
|
-
return
|
|
28
|
+
return crate::core::parser::statement::error_from_token(
|
|
35
29
|
target_token,
|
|
36
30
|
"Expected valid target after 'automate'".to_string(),
|
|
37
31
|
);
|
|
@@ -40,13 +34,13 @@ pub fn parse_automate_token(
|
|
|
40
34
|
|
|
41
35
|
// Expect ':'
|
|
42
36
|
let Some(colon_token) = parser.peek_clone() else {
|
|
43
|
-
return
|
|
37
|
+
return crate::core::parser::statement::error_from_token(
|
|
44
38
|
target_token,
|
|
45
39
|
"Expected ':' after automate target".to_string(),
|
|
46
40
|
);
|
|
47
41
|
};
|
|
48
42
|
if colon_token.kind != TokenKind::Colon {
|
|
49
|
-
return
|
|
43
|
+
return crate::core::parser::statement::error_from_token(
|
|
50
44
|
colon_token,
|
|
51
45
|
"Expected ':' after automate target".to_string(),
|
|
52
46
|
);
|
|
@@ -85,19 +79,22 @@ pub fn parse_automate_token(
|
|
|
85
79
|
local.advance(); // consume 'param'
|
|
86
80
|
// param name
|
|
87
81
|
let Some(name_tok) = local.peek_clone() else {
|
|
88
|
-
return
|
|
82
|
+
return crate::core::parser::statement::error_from_token(
|
|
89
83
|
tok,
|
|
90
84
|
"Expected parameter name after 'param'".to_string(),
|
|
91
85
|
);
|
|
92
86
|
};
|
|
93
87
|
if name_tok.kind != TokenKind::Identifier && name_tok.kind != TokenKind::String {
|
|
94
|
-
return
|
|
88
|
+
return crate::core::parser::statement::error_from_token(
|
|
89
|
+
name_tok,
|
|
90
|
+
"Expected valid parameter name".to_string(),
|
|
91
|
+
);
|
|
95
92
|
}
|
|
96
93
|
local.advance(); // consume name
|
|
97
94
|
|
|
98
95
|
// Expect '{'
|
|
99
96
|
if !local.match_token(TokenKind::LBrace) {
|
|
100
|
-
return
|
|
97
|
+
return crate::core::parser::statement::error_from_token(
|
|
101
98
|
name_tok,
|
|
102
99
|
"Expected '{' to start parameter block".to_string(),
|
|
103
100
|
);
|
|
@@ -142,7 +139,7 @@ pub fn parse_automate_token(
|
|
|
142
139
|
break;
|
|
143
140
|
}
|
|
144
141
|
if !local.match_token(TokenKind::Equals) {
|
|
145
|
-
return
|
|
142
|
+
return crate::core::parser::statement::error_from_token(
|
|
146
143
|
percent_token,
|
|
147
144
|
"Expected '=' in param entry".to_string(),
|
|
148
145
|
);
|
|
@@ -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
|
pub fn parse_call_token(
|
|
12
12
|
parser: &mut Parser,
|
|
@@ -19,7 +19,7 @@ pub fn parse_call_token(
|
|
|
19
19
|
let name_token = match parser.peek_clone() {
|
|
20
20
|
Some(t) => t,
|
|
21
21
|
None => {
|
|
22
|
-
return
|
|
22
|
+
return crate::core::parser::statement::error_from_token(
|
|
23
23
|
current_token,
|
|
24
24
|
"Expected function name after 'call'".to_string(),
|
|
25
25
|
);
|
|
@@ -27,7 +27,7 @@ pub fn parse_call_token(
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
if name_token.kind != TokenKind::Identifier {
|
|
30
|
-
return
|
|
30
|
+
return crate::core::parser::statement::error_from_token(
|
|
31
31
|
name_token,
|
|
32
32
|
"Expected function name to be an identifier".to_string(),
|
|
33
33
|
);
|
|
@@ -68,7 +68,7 @@ pub fn parse_call_token(
|
|
|
68
68
|
parser.advance(); // skip comma
|
|
69
69
|
}
|
|
70
70
|
_ => {
|
|
71
|
-
return
|
|
71
|
+
return crate::core::parser::statement::error_from_token(
|
|
72
72
|
token,
|
|
73
73
|
"Unexpected token in call arguments".to_string(),
|
|
74
74
|
);
|
|
@@ -4,12 +4,10 @@ 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
|
-
// Syntax:
|
|
12
|
-
// emit <event> [<payload>]
|
|
13
11
|
pub fn parse_emit_token(
|
|
14
12
|
parser: &mut Parser,
|
|
15
13
|
current: crate::core::lexer::token::Token,
|
|
@@ -18,10 +16,16 @@ pub fn parse_emit_token(
|
|
|
18
16
|
parser.advance(); // consume 'emit'
|
|
19
17
|
|
|
20
18
|
let Some(ev) = parser.peek_clone() else {
|
|
21
|
-
return
|
|
19
|
+
return crate::core::parser::statement::error_from_token(
|
|
20
|
+
current,
|
|
21
|
+
"Expected event name after 'emit'".into(),
|
|
22
|
+
);
|
|
22
23
|
};
|
|
23
24
|
if ev.kind != TokenKind::Identifier {
|
|
24
|
-
return
|
|
25
|
+
return crate::core::parser::statement::error_from_token(
|
|
26
|
+
ev.clone(),
|
|
27
|
+
"Expected identifier as event name".into(),
|
|
28
|
+
);
|
|
25
29
|
}
|
|
26
30
|
let event_name = ev.lexeme.clone();
|
|
27
31
|
parser.advance(); // consume event name
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
use devalang_types::Value;
|
|
2
|
+
|
|
1
3
|
use crate::core::{
|
|
2
4
|
lexer::token::TokenKind,
|
|
3
5
|
parser::{
|
|
4
6
|
driver::Parser,
|
|
5
7
|
statement::{Statement, StatementKind},
|
|
6
8
|
},
|
|
7
|
-
shared::value::Value,
|
|
8
9
|
store::global::GlobalStore,
|
|
9
10
|
};
|
|
10
11
|
|
|
@@ -18,11 +19,16 @@ pub fn parse_function_token(parser: &mut Parser, global_store: &mut GlobalStore)
|
|
|
18
19
|
|
|
19
20
|
let name_token = match parser.peek_clone() {
|
|
20
21
|
Some(tok) => tok,
|
|
21
|
-
None =>
|
|
22
|
+
None => {
|
|
23
|
+
return crate::core::parser::statement::error_from_token(
|
|
24
|
+
fn_token,
|
|
25
|
+
"Expected function name after 'fn'".to_string(),
|
|
26
|
+
);
|
|
27
|
+
}
|
|
22
28
|
};
|
|
23
29
|
|
|
24
30
|
if name_token.kind != TokenKind::Identifier {
|
|
25
|
-
return
|
|
31
|
+
return crate::core::parser::statement::error_from_token(
|
|
26
32
|
name_token.clone(),
|
|
27
33
|
"Expected function name to be an identifier".to_string(),
|
|
28
34
|
);
|
|
@@ -35,7 +41,7 @@ pub fn parse_function_token(parser: &mut Parser, global_store: &mut GlobalStore)
|
|
|
35
41
|
|
|
36
42
|
// Expect '('
|
|
37
43
|
if parser.peek_kind() != Some(TokenKind::LParen) {
|
|
38
|
-
return
|
|
44
|
+
return crate::core::parser::statement::error_from_token(
|
|
39
45
|
name_token.clone(),
|
|
40
46
|
"Expected '(' after function name".to_string(),
|
|
41
47
|
);
|
|
@@ -53,7 +59,7 @@ pub fn parse_function_token(parser: &mut Parser, global_store: &mut GlobalStore)
|
|
|
53
59
|
if parser.peek_kind() == Some(TokenKind::RParen) {
|
|
54
60
|
parser.advance(); // consume ')'
|
|
55
61
|
} else {
|
|
56
|
-
return
|
|
62
|
+
return crate::core::parser::statement::error_from_token(
|
|
57
63
|
name_token.clone(),
|
|
58
64
|
"Expected ')' after parameters".to_string(),
|
|
59
65
|
);
|
|
@@ -61,7 +67,10 @@ pub fn parse_function_token(parser: &mut Parser, global_store: &mut GlobalStore)
|
|
|
61
67
|
|
|
62
68
|
// Expect colon
|
|
63
69
|
if parser.peek_kind() != Some(TokenKind::Colon) {
|
|
64
|
-
return
|
|
70
|
+
return crate::core::parser::statement::error_from_token(
|
|
71
|
+
name_token.clone(),
|
|
72
|
+
"Expected ':' after ')'".to_string(),
|
|
73
|
+
);
|
|
65
74
|
}
|
|
66
75
|
parser.advance(); // consume ':'
|
|
67
76
|
|
|
@@ -73,7 +82,11 @@ pub fn parse_function_token(parser: &mut Parser, global_store: &mut GlobalStore)
|
|
|
73
82
|
if tok.kind == TokenKind::Dedent && tok.indent <= base_indent {
|
|
74
83
|
break;
|
|
75
84
|
}
|
|
76
|
-
|
|
85
|
+
if let Some(t) = parser.advance() {
|
|
86
|
+
body_tokens.push(t.clone());
|
|
87
|
+
} else {
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
77
90
|
}
|
|
78
91
|
|
|
79
92
|
// Parse those tokens into block statements
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
use devalang_types::Value;
|
|
2
|
+
|
|
1
3
|
use crate::core::{
|
|
2
4
|
lexer::token::{Token, TokenKind},
|
|
3
5
|
parser::{
|
|
4
6
|
driver::Parser,
|
|
5
7
|
statement::{Statement, StatementKind},
|
|
6
8
|
},
|
|
7
|
-
shared::value::Value,
|
|
8
9
|
store::global::GlobalStore,
|
|
9
10
|
};
|
|
10
11
|
use std::collections::HashMap;
|
|
@@ -17,7 +18,7 @@ pub fn parse_group_token(
|
|
|
17
18
|
parser.advance(); // consume "group"
|
|
18
19
|
|
|
19
20
|
let Some(identifier_token) = parser.peek_clone() else {
|
|
20
|
-
return
|
|
21
|
+
return crate::core::parser::statement::error_from_token(
|
|
21
22
|
current_token,
|
|
22
23
|
"Expected identifier after 'group'".to_string(),
|
|
23
24
|
);
|
|
@@ -25,20 +26,23 @@ pub fn parse_group_token(
|
|
|
25
26
|
|
|
26
27
|
if identifier_token.kind != TokenKind::Identifier && identifier_token.kind != TokenKind::String
|
|
27
28
|
{
|
|
28
|
-
return
|
|
29
|
+
return crate::core::parser::statement::error_from_token(
|
|
30
|
+
identifier_token,
|
|
31
|
+
"Expected valid identifier".to_string(),
|
|
32
|
+
);
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
parser.advance(); // consume identifier
|
|
32
36
|
|
|
33
37
|
let Some(colon_token) = parser.peek_clone() else {
|
|
34
|
-
return
|
|
38
|
+
return crate::core::parser::statement::error_from_token(
|
|
35
39
|
identifier_token,
|
|
36
40
|
"Expected ':' after group identifier".to_string(),
|
|
37
41
|
);
|
|
38
42
|
};
|
|
39
43
|
|
|
40
44
|
if colon_token.kind != TokenKind::Colon {
|
|
41
|
-
return
|
|
45
|
+
return crate::core::parser::statement::error_from_token(
|
|
42
46
|
colon_token.clone(),
|
|
43
47
|
"Expected ':' after group identifier".to_string(),
|
|
44
48
|
);
|
|
@@ -75,11 +79,11 @@ pub fn parse_group_token(
|
|
|
75
79
|
);
|
|
76
80
|
value_map.insert("body".to_string(), Value::Block(body));
|
|
77
81
|
|
|
78
|
-
|
|
82
|
+
Statement {
|
|
79
83
|
kind: StatementKind::Group,
|
|
80
84
|
value: Value::Map(value_map),
|
|
81
85
|
indent: current_token.indent,
|
|
82
86
|
line: current_token.line,
|
|
83
87
|
column: current_token.column,
|
|
84
|
-
}
|
|
88
|
+
}
|
|
85
89
|
}
|
|
@@ -7,9 +7,9 @@ use crate::core::{
|
|
|
7
7
|
handler::{dot::parse_dot_token, identifier::synth::parse_synth_token},
|
|
8
8
|
statement::{Statement, StatementKind},
|
|
9
9
|
},
|
|
10
|
-
shared::value::Value,
|
|
11
10
|
store::global::GlobalStore,
|
|
12
11
|
};
|
|
12
|
+
use devalang_types::Value;
|
|
13
13
|
|
|
14
14
|
pub fn parse_let_token(
|
|
15
15
|
parser: &mut Parser,
|
|
@@ -23,14 +23,23 @@ pub fn parse_let_token(
|
|
|
23
23
|
parser.advance();
|
|
24
24
|
token.lexeme.clone()
|
|
25
25
|
} else {
|
|
26
|
-
return
|
|
26
|
+
return crate::core::parser::statement::error_from_token(
|
|
27
|
+
token,
|
|
28
|
+
"Expected identifier after 'let'".to_string(),
|
|
29
|
+
);
|
|
27
30
|
}
|
|
28
31
|
} else {
|
|
29
|
-
return
|
|
32
|
+
return crate::core::parser::statement::error_from_token(
|
|
33
|
+
current_token,
|
|
34
|
+
"Expected identifier after 'let'".to_string(),
|
|
35
|
+
);
|
|
30
36
|
};
|
|
31
37
|
|
|
32
38
|
if !parser.match_token(TokenKind::Equals) {
|
|
33
|
-
return
|
|
39
|
+
return crate::core::parser::statement::error_from_token(
|
|
40
|
+
current_token,
|
|
41
|
+
"Expected '=' after identifier".to_string(),
|
|
42
|
+
);
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
// If RHS begins with '$' or contains expression tokens ('+', '-', '*', '/', '(', '['),
|
|
@@ -101,14 +110,17 @@ pub fn parse_let_token(
|
|
|
101
110
|
}
|
|
102
111
|
|
|
103
112
|
if key_token.kind != TokenKind::Identifier {
|
|
104
|
-
return
|
|
113
|
+
return crate::core::parser::statement::error_from_token(
|
|
114
|
+
token,
|
|
115
|
+
"Expected key identifier in map".to_string(),
|
|
116
|
+
);
|
|
105
117
|
}
|
|
106
118
|
parser.advance();
|
|
107
119
|
let key = key_token.lexeme.clone();
|
|
108
120
|
|
|
109
121
|
if !parser.match_token(TokenKind::Colon) {
|
|
110
122
|
let message = format!("Expected ':' after key '{}'", key);
|
|
111
|
-
return
|
|
123
|
+
return crate::core::parser::statement::error_from_token(token, message);
|
|
112
124
|
}
|
|
113
125
|
|
|
114
126
|
let val = match parser.peek_clone() {
|
|
@@ -129,7 +141,7 @@ pub fn parse_let_token(
|
|
|
129
141
|
|
|
130
142
|
if val == Value::Null {
|
|
131
143
|
let message = format!("Invalid value for key '{}'", key);
|
|
132
|
-
return
|
|
144
|
+
return crate::core::parser::statement::error_from_token(token, message);
|
|
133
145
|
}
|
|
134
146
|
|
|
135
147
|
map.insert(key, val);
|
|
@@ -144,13 +156,16 @@ pub fn parse_let_token(
|
|
|
144
156
|
Value::Map(map)
|
|
145
157
|
}
|
|
146
158
|
_ => {
|
|
147
|
-
return
|
|
159
|
+
return crate::core::parser::statement::error_from_token(
|
|
160
|
+
current_token,
|
|
161
|
+
"Unhandled value type after '='".to_string(),
|
|
162
|
+
);
|
|
148
163
|
}
|
|
149
164
|
};
|
|
150
165
|
|
|
151
166
|
Statement {
|
|
152
167
|
kind: StatementKind::Let { name: identifier },
|
|
153
|
-
value
|
|
168
|
+
value,
|
|
154
169
|
indent: current_token.indent,
|
|
155
170
|
line: current_token.line,
|
|
156
171
|
column: current_token.column,
|