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