@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.
Files changed (235) hide show
  1. package/.cargo/config.toml +2 -0
  2. package/.devalang +6 -10
  3. package/.github/workflows/ci.yml +19 -8
  4. package/Cargo.toml +18 -2
  5. package/README.md +80 -33
  6. package/docs/CHANGELOG.md +56 -0
  7. package/docs/ROADMAP.md +6 -3
  8. package/examples/index.deva +52 -35
  9. package/out-tsc/bin/index.d.ts +2 -0
  10. package/out-tsc/core/functions/index.d.ts +37 -0
  11. package/out-tsc/core/functions/index.js +76 -0
  12. package/out-tsc/core/index.d.ts +6 -0
  13. package/out-tsc/core/index.js +22 -0
  14. package/out-tsc/core/types/index.d.ts +4 -0
  15. package/out-tsc/core/types/index.js +20 -0
  16. package/out-tsc/core/types/plugin.d.ts +18 -0
  17. package/out-tsc/core/types/plugin.js +2 -0
  18. package/out-tsc/core/types/result.d.ts +27 -0
  19. package/out-tsc/core/types/result.js +2 -0
  20. package/out-tsc/core/types/statement.d.ts +106 -0
  21. package/out-tsc/core/types/statement.js +2 -0
  22. package/out-tsc/core/types/value.d.ts +43 -0
  23. package/out-tsc/core/types/value.js +2 -0
  24. package/out-tsc/index.d.ts +7 -0
  25. package/out-tsc/index.js +41 -2
  26. package/out-tsc/pkg/devalang_core.d.ts +7 -0
  27. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +33 -0
  28. package/out-tsc/scripts/copy-wasm-dts.d.ts +1 -0
  29. package/out-tsc/scripts/copy-wasm-dts.js +73 -0
  30. package/out-tsc/scripts/postinstall.d.ts +1 -0
  31. package/out-tsc/scripts/postinstall.js +33 -23
  32. package/out-tsc/scripts/version/bump.d.ts +1 -0
  33. package/out-tsc/scripts/version/fetch.d.ts +1 -0
  34. package/out-tsc/scripts/version/index.d.ts +1 -0
  35. package/out-tsc/scripts/version/sync.d.ts +1 -0
  36. package/package.json +16 -4
  37. package/project-version.json +3 -3
  38. package/rust/cli/bank/api.rs +122 -0
  39. package/rust/cli/bank/commands.rs +275 -0
  40. package/rust/cli/bank/mod.rs +29 -0
  41. package/rust/cli/build/commands.rs +97 -0
  42. package/rust/cli/build/mod.rs +2 -0
  43. package/rust/cli/build/process.rs +146 -0
  44. package/rust/cli/{check.rs → check/mod.rs} +18 -31
  45. package/rust/cli/discover/commands.rs +253 -0
  46. package/rust/cli/discover/config.rs +111 -0
  47. package/rust/cli/discover/fs.rs +19 -0
  48. package/rust/cli/discover/install.rs +103 -0
  49. package/rust/cli/discover/metadata.rs +48 -0
  50. package/rust/cli/discover/mod.rs +5 -0
  51. package/rust/cli/{init.rs → init/commands.rs} +88 -87
  52. package/rust/cli/init/mod.rs +1 -0
  53. package/rust/{installer → cli/install}/addon.rs +5 -9
  54. package/rust/cli/install/bank.rs +53 -0
  55. package/rust/cli/{install.rs → install/commands.rs} +9 -9
  56. package/rust/{installer → cli/install}/mod.rs +2 -3
  57. package/rust/cli/install/plugin.rs +61 -0
  58. package/rust/cli/{login.rs → login/commands.rs} +8 -11
  59. package/rust/cli/login/mod.rs +1 -0
  60. package/rust/cli/mod.rs +2 -3
  61. package/rust/cli/{driver.rs → parser.rs} +19 -2
  62. package/rust/cli/play/commands.rs +324 -0
  63. package/rust/cli/play/io.rs +17 -0
  64. package/rust/cli/play/mod.rs +5 -0
  65. package/rust/cli/play/process.rs +150 -0
  66. package/rust/cli/play/realtime.rs +91 -0
  67. package/rust/cli/play/utils.rs +23 -0
  68. package/rust/cli/telemetry/commands.rs +22 -0
  69. package/rust/cli/telemetry/event_creator.rs +80 -0
  70. package/rust/cli/telemetry/mod.rs +3 -0
  71. package/rust/cli/telemetry/send.rs +51 -0
  72. package/rust/cli/{template.rs → template/commands.rs} +1 -1
  73. package/rust/cli/template/mod.rs +1 -0
  74. package/rust/cli/{update.rs → update/commands.rs} +6 -6
  75. package/rust/cli/update/mod.rs +1 -0
  76. package/rust/config/driver.rs +57 -72
  77. package/rust/config/mod.rs +1 -2
  78. package/rust/config/ops.rs +26 -0
  79. package/rust/config/settings.rs +60 -50
  80. package/rust/core/audio/engine/helpers.rs +146 -0
  81. package/rust/core/audio/engine/mod.rs +7 -0
  82. package/rust/core/audio/engine/sample.rs +298 -0
  83. package/rust/core/audio/engine/synth.rs +310 -0
  84. package/rust/core/audio/evaluator.rs +15 -12
  85. package/rust/core/audio/interpreter/arrow_call.rs +99 -24
  86. package/rust/core/audio/interpreter/call.rs +81 -60
  87. package/rust/core/audio/interpreter/condition.rs +3 -2
  88. package/rust/core/audio/interpreter/driver.rs +206 -151
  89. package/rust/core/audio/interpreter/let_.rs +1 -1
  90. package/rust/core/audio/interpreter/load.rs +2 -1
  91. package/rust/core/audio/interpreter/loop_.rs +7 -6
  92. package/rust/core/audio/interpreter/sleep.rs +2 -1
  93. package/rust/core/audio/interpreter/spawn.rs +45 -57
  94. package/rust/core/audio/interpreter/tempo.rs +31 -10
  95. package/rust/core/audio/interpreter/trigger.rs +2 -2
  96. package/rust/core/audio/loader/trigger.rs +4 -7
  97. package/rust/core/audio/player.rs +6 -0
  98. package/rust/core/audio/renderer.rs +5 -7
  99. package/rust/core/audio/special/env.rs +3 -1
  100. package/rust/core/audio/special/math.rs +4 -4
  101. package/rust/core/audio/special/modulator.rs +2 -2
  102. package/rust/core/builder/mod.rs +9 -3
  103. package/rust/core/debugger/lexer.rs +1 -1
  104. package/rust/core/debugger/mod.rs +6 -0
  105. package/rust/core/debugger/module.rs +4 -4
  106. package/rust/core/debugger/preprocessor.rs +1 -1
  107. package/rust/core/debugger/store.rs +2 -2
  108. package/rust/core/error/mod.rs +189 -0
  109. package/rust/core/lexer/handler/arrow.rs +1 -1
  110. package/rust/core/lexer/handler/at.rs +1 -1
  111. package/rust/core/lexer/handler/brace.rs +2 -2
  112. package/rust/core/lexer/handler/colon.rs +1 -1
  113. package/rust/core/lexer/handler/comment.rs +1 -1
  114. package/rust/core/lexer/handler/dot.rs +1 -1
  115. package/rust/core/lexer/handler/driver.rs +1 -1
  116. package/rust/core/lexer/handler/identifier.rs +1 -1
  117. package/rust/core/lexer/handler/mod.rs +1 -2
  118. package/rust/core/lexer/handler/number.rs +1 -1
  119. package/rust/core/lexer/handler/operator.rs +1 -1
  120. package/rust/core/lexer/handler/parenthesis.rs +2 -2
  121. package/rust/core/lexer/handler/slash.rs +1 -1
  122. package/rust/core/lexer/handler/string.rs +1 -1
  123. package/rust/core/lexer/mod.rs +22 -12
  124. package/rust/core/lexer/token.rs +90 -97
  125. package/rust/core/mod.rs +0 -1
  126. package/rust/core/parser/driver.rs +66 -13
  127. package/rust/core/parser/handler/arrow_call.rs +28 -8
  128. package/rust/core/parser/handler/at.rs +55 -21
  129. package/rust/core/parser/handler/bank.rs +14 -4
  130. package/rust/core/parser/handler/condition.rs +6 -3
  131. package/rust/core/parser/handler/dot.rs +2 -1
  132. package/rust/core/parser/handler/identifier/automate.rs +13 -16
  133. package/rust/core/parser/handler/identifier/call.rs +4 -4
  134. package/rust/core/parser/handler/identifier/emit.rs +9 -5
  135. package/rust/core/parser/handler/identifier/function.rs +20 -7
  136. package/rust/core/parser/handler/identifier/group.rs +11 -7
  137. package/rust/core/parser/handler/identifier/let_.rs +24 -9
  138. package/rust/core/parser/handler/identifier/mod.rs +6 -5
  139. package/rust/core/parser/handler/identifier/on.rs +16 -7
  140. package/rust/core/parser/handler/identifier/print.rs +6 -9
  141. package/rust/core/parser/handler/identifier/sleep.rs +12 -5
  142. package/rust/core/parser/handler/identifier/spawn.rs +4 -4
  143. package/rust/core/parser/handler/identifier/synth.rs +79 -9
  144. package/rust/core/parser/handler/loop_.rs +39 -14
  145. package/rust/core/parser/handler/tempo.rs +9 -5
  146. package/rust/core/parser/mod.rs +0 -1
  147. package/rust/core/parser/statement.rs +6 -137
  148. package/rust/core/plugin/loader.rs +41 -27
  149. package/rust/core/plugin/runner.rs +68 -17
  150. package/rust/core/preprocessor/loader.rs +155 -33
  151. package/rust/core/preprocessor/processor.rs +2 -2
  152. package/rust/core/preprocessor/resolver/bank.rs +6 -8
  153. package/rust/core/preprocessor/resolver/call.rs +20 -24
  154. package/rust/core/preprocessor/resolver/condition.rs +6 -8
  155. package/rust/core/preprocessor/resolver/driver.rs +14 -16
  156. package/rust/core/preprocessor/resolver/function.rs +6 -6
  157. package/rust/core/preprocessor/resolver/group.rs +6 -8
  158. package/rust/core/preprocessor/resolver/loop_.rs +8 -10
  159. package/rust/core/preprocessor/resolver/spawn.rs +19 -23
  160. package/rust/core/preprocessor/resolver/synth.rs +6 -8
  161. package/rust/core/preprocessor/resolver/tempo.rs +6 -8
  162. package/rust/core/preprocessor/resolver/trigger.rs +22 -19
  163. package/rust/core/preprocessor/resolver/value.rs +99 -4
  164. package/rust/core/store/export.rs +28 -28
  165. package/rust/core/store/function.rs +6 -0
  166. package/rust/core/store/global.rs +7 -1
  167. package/rust/core/store/import.rs +28 -28
  168. package/rust/core/store/variable.rs +1 -1
  169. package/rust/core/utils/mod.rs +0 -1
  170. package/rust/lib.rs +102 -9
  171. package/rust/main.rs +156 -45
  172. package/rust/types/Cargo.toml +8 -0
  173. package/rust/types/src/addons.rs +55 -0
  174. package/rust/types/src/ast.rs +198 -0
  175. package/rust/types/src/config.rs +74 -0
  176. package/rust/types/src/lib.rs +12 -0
  177. package/rust/types/src/telemetry.rs +85 -0
  178. package/rust/utils/Cargo.toml +23 -0
  179. package/rust/utils/{error.rs → src/error.rs} +186 -200
  180. package/rust/utils/src/file.rs +94 -0
  181. package/rust/utils/src/first_usage.rs +97 -0
  182. package/rust/utils/{mod.rs → src/lib.rs} +1 -1
  183. package/rust/utils/{logger.rs → src/logger.rs} +17 -12
  184. package/rust/utils/src/path.rs +88 -0
  185. package/rust/utils/src/signature.rs +41 -0
  186. package/rust/utils/{spinner.rs → src/spinner.rs} +3 -5
  187. package/rust/utils/src/version.rs +27 -0
  188. package/rust/utils/{watcher.rs → src/watcher.rs} +13 -1
  189. package/rust/web/api.rs +5 -0
  190. package/rust/web/cdn.rs +34 -0
  191. package/templates/minimal/README.md +98 -54
  192. package/templates/welcome/README.md +98 -54
  193. package/templates/welcome/src/index.deva +56 -8
  194. package/templates/welcome/src/variables.deva +2 -4
  195. package/tests/rust/TODO.md +0 -0
  196. package/tests/typescript/index.spec.ts +136 -0
  197. package/tests/typescript/playhead.spec.ts +36 -0
  198. package/tests/typescript/render_e2e.spec.ts +77 -0
  199. package/tsconfig.json +1 -1
  200. package/typescript/core/functions/index.ts +83 -0
  201. package/typescript/core/index.ts +6 -0
  202. package/typescript/core/types/index.ts +4 -0
  203. package/typescript/core/types/plugin.ts +19 -0
  204. package/typescript/core/types/result.ts +29 -0
  205. package/typescript/core/types/statement.ts +47 -0
  206. package/typescript/core/types/value.ts +29 -0
  207. package/typescript/index.ts +7 -2
  208. package/typescript/pkg/devalang_core.d.ts +4 -0
  209. package/typescript/scripts/copy-wasm-dts.ts +41 -0
  210. package/typescript/scripts/postinstall.ts +45 -32
  211. package/rust/cli/bank.rs +0 -462
  212. package/rust/cli/build.rs +0 -252
  213. package/rust/cli/generator.rs +0 -1
  214. package/rust/cli/play.rs +0 -1123
  215. package/rust/cli/telemetry.rs +0 -19
  216. package/rust/common/api.rs +0 -5
  217. package/rust/common/cdn.rs +0 -5
  218. package/rust/config/loader.rs +0 -165
  219. package/rust/config/stats.rs +0 -257
  220. package/rust/core/audio/engine.rs +0 -696
  221. package/rust/core/shared/bank.rs +0 -21
  222. package/rust/core/shared/duration.rs +0 -9
  223. package/rust/core/shared/mod.rs +0 -3
  224. package/rust/core/shared/value.rs +0 -35
  225. package/rust/core/utils/validation.rs +0 -35
  226. package/rust/installer/bank.rs +0 -62
  227. package/rust/installer/plugin.rs +0 -54
  228. package/rust/installer/utils.rs +0 -56
  229. package/rust/utils/file.rs +0 -38
  230. package/rust/utils/first_usage.rs +0 -76
  231. package/rust/utils/signature.rs +0 -19
  232. package/rust/utils/telemetry.rs +0 -292
  233. package/rust/utils/version.rs +0 -15
  234. /package/rust/{common → web}/mod.rs +0 -0
  235. /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 Statement::error(use_token, "Expected plugin author".to_string());
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 Statement::error(
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 Statement::error(
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 Statement::error(author_token, "Expected plugin name".to_string());
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 Statement::error(
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 Statement::error(
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 Statement::error(
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 Statement::error(token, "Expected '{{' after 'import'".to_string());
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 Statement::error(token.clone(), message);
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 Statement::error(token, "Expected 'from' after import list".to_string());
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 Statement::error(token, "Expected keyword 'from'".to_string());
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 Statement::error(token, "Expected string after 'from'".to_string());
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 Statement::error(token, "Expected string after 'from'".to_string());
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 Statement::error(token, "Unexpected token in export list".to_string());
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 Statement::error(token, "Expected string after 'load'".to_string());
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 Statement::error(token, "Expected string after 'load'".to_string());
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 Statement::error(
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 Statement::error(
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 Statement::error(
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
- Statement::error(token, message)
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 Statement::error(bank_tok, "Expected a bank name".to_string());
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 Statement::error(bank_tok, "Expected identifier after 'as'".to_string());
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 Statement::error(next, "Expected identifier after 'as'".to_string());
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 Statement::error(if_token, "Expected condition after 'if'".to_string());
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 Statement::error(
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,10 +1,11 @@
1
+ use devalang_types::{Duration, 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::{duration::Duration, value::Value},
8
9
  };
9
10
 
10
11
  pub fn parse_dot_token(
@@ -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 Statement::error(
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 Statement::error(
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 Statement::error(
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 Statement::error(
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 Statement::error(
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 Statement::error(name_tok, "Expected valid parameter name".to_string());
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 Statement::error(
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 Statement::error(
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 Statement::error(
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 Statement::error(
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 Statement::error(
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 Statement::error(current, "Expected event name after 'emit'".into());
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 Statement::error(ev.clone(), "Expected identifier as event name".into());
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 => return Statement::error(fn_token, "Expected function name after 'fn'".to_string()),
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 Statement::error(
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 Statement::error(
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 Statement::error(
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 Statement::error(name_token.clone(), "Expected ':' after ')'".to_string());
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
- body_tokens.push(parser.advance().unwrap().clone());
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 Statement::error(
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 Statement::error(identifier_token, "Expected valid identifier".to_string());
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 Statement::error(
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 Statement::error(
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
- return Statement {
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 Statement::error(token, "Expected identifier after 'let'".to_string());
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 Statement::error(current_token, "Expected identifier after 'let'".to_string());
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 Statement::error(current_token, "Expected '=' after identifier".to_string());
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 Statement::error(token, "Expected key identifier in map".to_string());
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 Statement::error(token, message);
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 Statement::error(token, message);
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 Statement::error(current_token, "Unhandled value type after '='".to_string());
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: value,
168
+ value,
154
169
  indent: current_token.indent,
155
170
  line: current_token.line,
156
171
  column: current_token.column,