@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,97 +1,91 @@
1
- use serde::{Deserialize, Serialize};
2
-
3
- #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4
- pub struct Token {
5
- pub kind: TokenKind,
6
- pub lexeme: String,
7
- pub indent: usize,
8
- pub line: usize,
9
- pub column: usize,
10
- }
11
-
12
- impl Token {
13
- pub fn is_error(&self) -> bool {
14
- match &self.kind {
15
- TokenKind::Error(_) => {
16
- return true;
17
- }
18
- _ => {
19
- return false;
20
- }
21
- };
22
- }
23
- }
24
-
25
- #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
26
- pub enum TokenKind {
27
- // ───── Keywords ─────
28
- At,
29
- Tempo,
30
- Bank,
31
- Loop,
32
- Function,
33
- As,
34
- On,
35
- Emit,
36
-
37
- // ───── Instruments ─────
38
- Synth,
39
-
40
- // ───── Literals ─────
41
- Identifier,
42
- Number,
43
- String,
44
- Boolean,
45
- Arrow,
46
-
47
- // ───── Structures ─────
48
- Map,
49
- Array,
50
-
51
- // ───── Symbols ─────
52
- Colon,
53
- Comma,
54
- Equals,
55
- Dot,
56
- Slash,
57
- Plus,
58
- Asterisk,
59
- Minus,
60
-
61
- // ───── Operators ─────
62
- DoubleEquals,
63
- NotEquals,
64
- GreaterEqual,
65
- LessEqual,
66
- Greater,
67
- Less,
68
-
69
- // ───── Brackets ─────
70
- LBrace, // {
71
- RBrace, // }
72
- LBracket, // [
73
- RBracket, // ]
74
- LParen, // (
75
- RParen, // )
76
-
77
- // ───── Quotes ─────
78
- Quote, // '
79
- DbQuote, // "
80
-
81
- // ───── Formatting ─────
82
- Newline,
83
- Indent,
84
- Dedent,
85
- Comment,
86
-
87
- // ───── Conditions ─────
88
- If,
89
- Else,
90
- ElseIf,
91
-
92
- // ───── Special / Internal ─────
93
- Whitespace,
94
- Unknown,
95
- Error(String),
96
- EOF,
97
- }
1
+ use serde::{Deserialize, Serialize};
2
+
3
+ #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4
+ pub struct Token {
5
+ pub kind: TokenKind,
6
+ pub lexeme: String,
7
+ pub indent: usize,
8
+ pub line: usize,
9
+ pub column: usize,
10
+ }
11
+
12
+ impl Token {
13
+ pub fn is_error(&self) -> bool {
14
+ matches!(&self.kind, TokenKind::Error(_))
15
+ }
16
+ }
17
+
18
+ #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
19
+ pub enum TokenKind {
20
+ // ───── Keywords ─────
21
+ At,
22
+ Tempo,
23
+ Bank,
24
+ Pattern,
25
+ Loop,
26
+ Function,
27
+ As,
28
+ On,
29
+ Emit,
30
+
31
+ // ───── Instruments ─────
32
+ Synth,
33
+
34
+ // ───── Literals ─────
35
+ Identifier,
36
+ Number,
37
+ String,
38
+ Boolean,
39
+ Arrow,
40
+
41
+ // ───── Structures ─────
42
+ Map,
43
+ Array,
44
+
45
+ // ───── Symbols ─────
46
+ Colon,
47
+ Comma,
48
+ Equals,
49
+ Dot,
50
+ Slash,
51
+ Plus,
52
+ Asterisk,
53
+ Minus,
54
+
55
+ // ───── Operators ─────
56
+ DoubleEquals,
57
+ NotEquals,
58
+ GreaterEqual,
59
+ LessEqual,
60
+ Greater,
61
+ Less,
62
+
63
+ // ───── Brackets ─────
64
+ LBrace, // {
65
+ RBrace, // }
66
+ LBracket, // [
67
+ RBracket, // ]
68
+ LParen, // (
69
+ RParen, // )
70
+
71
+ // ───── Quotes ─────
72
+ Quote, // '
73
+ DbQuote, // "
74
+
75
+ // ───── Formatting ─────
76
+ Newline,
77
+ Indent,
78
+ Dedent,
79
+ Comment,
80
+
81
+ // ───── Conditions ─────
82
+ If,
83
+ Else,
84
+ ElseIf,
85
+
86
+ // ───── Special / Internal ─────
87
+ Whitespace,
88
+ Unknown,
89
+ Error(String),
90
+ EOF,
91
+ }
package/rust/core/mod.rs CHANGED
@@ -6,6 +6,5 @@ pub mod lexer;
6
6
  pub mod parser;
7
7
  pub mod plugin;
8
8
  pub mod preprocessor;
9
- pub mod shared;
10
9
  pub mod store;
11
10
  pub mod utils;
@@ -1,3 +1,5 @@
1
+ use devalang_types::Value;
2
+
1
3
  use crate::core::{
2
4
  lexer::token::{Token, TokenKind},
3
5
  parser::{
@@ -7,13 +9,16 @@ use crate::core::{
7
9
  bank::parse_bank_token,
8
10
  condition::parse_condition_token,
9
11
  dot::parse_dot_token,
10
- identifier::{function::parse_function_token, parse_identifier_token},
12
+ pattern::parse_pattern_token,
13
+ identifier::{
14
+ emit::parse_emit_token, function::parse_function_token, on::parse_on_token,
15
+ parse_identifier_token,
16
+ },
11
17
  loop_::parse_loop_token,
12
18
  tempo::parse_tempo_token,
13
19
  },
14
20
  statement::Statement,
15
21
  },
16
- shared::value::Value,
17
22
  store::global::GlobalStore,
18
23
  };
19
24
 
@@ -26,6 +31,12 @@ pub struct Parser {
26
31
  pub previous: Option<Token>,
27
32
  }
28
33
 
34
+ impl Default for Parser {
35
+ fn default() -> Self {
36
+ Self::new()
37
+ }
38
+ }
39
+
29
40
  impl Parser {
30
41
  pub fn new() -> Self {
31
42
  Parser {
@@ -53,7 +64,7 @@ impl Parser {
53
64
  }
54
65
 
55
66
  pub fn peek_is(&self, expected: &str) -> bool {
56
- self.peek().map_or(false, |t| t.lexeme == expected)
67
+ self.peek().is_some_and(|t| t.lexeme == expected)
57
68
  }
58
69
 
59
70
  pub fn peek_nth(&self, n: usize) -> Option<&Token> {
@@ -69,7 +80,7 @@ impl Parser {
69
80
  }
70
81
 
71
82
  pub fn advance_if(&mut self, kind: TokenKind) -> bool {
72
- if self.match_token(kind) { true } else { false }
83
+ self.match_token(kind)
73
84
  }
74
85
 
75
86
  pub fn match_token(&mut self, kind: TokenKind) -> bool {
@@ -146,11 +157,12 @@ impl Parser {
146
157
  TokenKind::Dot => parse_dot_token(self, global_store),
147
158
  TokenKind::Tempo => parse_tempo_token(self, global_store),
148
159
  TokenKind::Bank => parse_bank_token(self, global_store),
160
+ TokenKind::Pattern => parse_pattern_token(self, global_store),
149
161
  TokenKind::Loop => parse_loop_token(self, global_store),
150
162
  TokenKind::If => parse_condition_token(self, global_store),
151
163
  TokenKind::Function => parse_function_token(self, global_store),
152
- TokenKind::On => crate::core::parser::handler::identifier::on::parse_on_token(self, global_store),
153
- TokenKind::Emit => crate::core::parser::handler::identifier::emit::parse_emit_token(self, token.clone(), global_store),
164
+ TokenKind::On => parse_on_token(self, global_store),
165
+ TokenKind::Emit => parse_emit_token(self, token.clone(), global_store),
154
166
 
155
167
  | TokenKind::Else // Ignore else, already handled in `parse_condition_token`
156
168
  | TokenKind::Comment
@@ -173,7 +185,7 @@ impl Parser {
173
185
 
174
186
  _ => {
175
187
  self.advance();
176
- Statement::unknown_from_token(&token)
188
+ Statement::unknown_with_pos(token.indent, token.line, token.column)
177
189
  }
178
190
  };
179
191
 
@@ -184,7 +196,7 @@ impl Parser {
184
196
  }
185
197
 
186
198
  pub fn check_token(&self, kind: TokenKind) -> bool {
187
- self.peek().map_or(false, |t| t.kind == kind)
199
+ self.peek().is_some_and(|t| t.kind == kind)
188
200
  }
189
201
 
190
202
  pub fn peek_kind(&self) -> Option<TokenKind> {
@@ -192,6 +204,8 @@ impl Parser {
192
204
  }
193
205
 
194
206
  pub fn parse_map_value(&mut self) -> Option<Value> {
207
+ let logger = devalang_utils::logger::Logger::new();
208
+ use devalang_utils::logger::LogLevel;
195
209
  if !self.match_token(TokenKind::LBrace) {
196
210
  return None;
197
211
  }
@@ -234,7 +248,7 @@ impl Parser {
234
248
  }
235
249
 
236
250
  if !self.match_token(TokenKind::Colon) {
237
- println!("Expected ':' after map key '{}'", key);
251
+ logger.log_message(LogLevel::Error, &format!("Expected ':' after map key '{}'", key));
238
252
  break;
239
253
  }
240
254
 
@@ -268,14 +282,11 @@ impl Parser {
268
282
  number_str.push('.');
269
283
  number_str.push_str(&decimal_token.lexeme);
270
284
  } else {
271
- println!(
272
- "Expected number after dot, got {:?}",
273
- decimal_token
274
- );
285
+ logger.log_message(LogLevel::Error, &format!("Expected number after dot, got {:?}", decimal_token));
275
286
  return Some(Value::Null);
276
287
  }
277
288
  } else {
278
- println!("Expected number after dot, but reached EOF");
289
+ logger.log_message(LogLevel::Error, "Expected number after dot, but reached EOF");
279
290
  return Some(Value::Null);
280
291
  }
281
292
  }
@@ -285,11 +296,37 @@ impl Parser {
285
296
  }
286
297
 
287
298
  TokenKind::Identifier => {
299
+ // Support dotted identifiers in map values: alias.param or nested
300
+ let current_line = token.line;
301
+ let mut parts: Vec<String> = vec![token.lexeme.clone()];
288
302
  self.advance();
289
- Value::Identifier(token.lexeme.clone())
303
+ loop {
304
+ let Some(next) = self.peek_clone() else { break };
305
+ if next.line != current_line {
306
+ break;
307
+ }
308
+ if next.kind == TokenKind::Dot {
309
+ // Consume '.' and the following identifier/number on same line
310
+ self.advance(); // dot
311
+ if let Some(id2) = self.peek_clone() {
312
+ if id2.line == current_line
313
+ && (id2.kind == TokenKind::Identifier
314
+ || id2.kind == TokenKind::Number)
315
+ {
316
+ parts.push(id2.lexeme.clone());
317
+ self.advance(); // consume part
318
+ continue;
319
+ }
320
+ }
321
+ break;
322
+ } else {
323
+ break;
324
+ }
325
+ }
326
+ Value::Identifier(parts.join("."))
290
327
  }
291
328
  _ => {
292
- println!("Unexpected token in map value: {:?}", token);
329
+ logger.log_message(LogLevel::Error, &format!("Unexpected token in map value: {:?}", token));
293
330
  Value::Null
294
331
  }
295
332
  }
@@ -309,7 +346,7 @@ impl Parser {
309
346
  }
310
347
 
311
348
  if !self.match_token(TokenKind::RBrace) {
312
- println!("Expected '}}' at end of map");
349
+ logger.log_message(LogLevel::Error, "Expected '}' at end of map");
313
350
  }
314
351
 
315
352
  Some(Value::Map(map))
@@ -317,6 +354,8 @@ impl Parser {
317
354
 
318
355
  // Parse an array value like [1, 2, 3] or ["a", b]
319
356
  pub fn parse_array_value(&mut self) -> Option<Value> {
357
+ let logger = devalang_utils::logger::Logger::new();
358
+ use devalang_utils::logger::LogLevel;
320
359
  if !self.match_token(TokenKind::LBracket) {
321
360
  return None;
322
361
  }
@@ -400,7 +439,7 @@ impl Parser {
400
439
  }
401
440
 
402
441
  if !self.match_token(TokenKind::RBracket) {
403
- println!("Expected ']' at end of array");
442
+ logger.log_message(LogLevel::Error, "Expected ']' at end of array");
404
443
  }
405
444
 
406
445
  Some(Value::Array(arr))
@@ -430,7 +469,12 @@ impl Parser {
430
469
  if tok.indent <= base_indent && tok.kind != TokenKind::Newline {
431
470
  break;
432
471
  }
433
- tokens.push(self.advance().unwrap().clone());
472
+ if let Some(t) = self.advance() {
473
+ tokens.push(t.clone());
474
+ } else {
475
+ // Unexpected EOF while collecting block tokens: stop collecting
476
+ break;
477
+ }
434
478
  }
435
479
 
436
480
  tokens
@@ -448,7 +492,11 @@ impl Parser {
448
492
  if token.kind == TokenKind::EOF {
449
493
  break;
450
494
  }
451
- collected.push(self.advance().unwrap().clone());
495
+ if let Some(t) = self.advance() {
496
+ collected.push(t.clone());
497
+ } else {
498
+ break;
499
+ }
452
500
  }
453
501
 
454
502
  collected
@@ -470,7 +518,11 @@ impl Parser {
470
518
  if tok.lexeme == "else" && tok.indent == base_indent {
471
519
  break;
472
520
  }
473
- block_tokens.push(self.advance().unwrap().clone());
521
+ if let Some(t) = self.advance() {
522
+ block_tokens.push(t.clone());
523
+ } else {
524
+ break;
525
+ }
474
526
  }
475
527
 
476
528
  self.parse_block(block_tokens, global_store)
@@ -505,7 +557,11 @@ impl Parser {
505
557
  if tok.indent < base_indent && tok.kind != TokenKind::Newline {
506
558
  break;
507
559
  }
508
- tokens.push(self.advance().unwrap().clone());
560
+ if let Some(t) = self.advance() {
561
+ tokens.push(t.clone());
562
+ } else {
563
+ break;
564
+ }
509
565
  }
510
566
 
511
567
  self.parse_block(tokens, global_store)
@@ -4,9 +4,9 @@ use crate::core::{
4
4
  driver::Parser,
5
5
  statement::{Statement, StatementKind},
6
6
  },
7
- shared::value::Value,
8
7
  store::global::GlobalStore,
9
8
  };
9
+ use devalang_types::Value;
10
10
 
11
11
  fn parse_map_literal(parser: &mut Parser) -> Value {
12
12
  // Assumes '{' has already been consumed by caller
@@ -126,28 +126,48 @@ pub fn parse_arrow_call(parser: &mut Parser, _global_store: &mut GlobalStore) ->
126
126
 
127
127
  if target_token.kind != TokenKind::Identifier {
128
128
  parser.advance(); // consume target token
129
- return Statement::unknown_from_token(&target_token);
129
+ return Statement::unknown_with_pos(
130
+ target_token.indent,
131
+ target_token.line,
132
+ target_token.column,
133
+ );
130
134
  }
131
135
 
132
136
  let Some(arrow_token) = parser.peek_nth(1).cloned() else {
133
137
  parser.advance(); // consume arrow token
134
- return Statement::unknown_from_token(&target_token);
138
+ return Statement::unknown_with_pos(
139
+ target_token.indent,
140
+ target_token.line,
141
+ target_token.column,
142
+ );
135
143
  };
136
144
 
137
145
  if arrow_token.kind != TokenKind::Arrow {
138
146
  parser.advance(); // consume method token
139
- return Statement::unknown_from_token(&target_token);
147
+ return Statement::unknown_with_pos(
148
+ target_token.indent,
149
+ target_token.line,
150
+ target_token.column,
151
+ );
140
152
  }
141
153
 
142
154
  // We have a valid arrow call, so we consume the arrow token
143
155
  let Some(method_token) = parser.peek_nth(2).cloned() else {
144
156
  parser.advance();
145
- return Statement::unknown_from_token(&target_token);
157
+ return Statement::unknown_with_pos(
158
+ target_token.indent,
159
+ target_token.line,
160
+ target_token.column,
161
+ );
146
162
  };
147
163
 
148
164
  if method_token.kind != TokenKind::Identifier {
149
165
  parser.advance();
150
- return Statement::unknown_from_token(&method_token);
166
+ return Statement::unknown_with_pos(
167
+ method_token.indent,
168
+ method_token.line,
169
+ method_token.column,
170
+ );
151
171
  }
152
172
 
153
173
  // Consume the tokens for target, arrow, and method
@@ -202,10 +222,10 @@ pub fn parse_arrow_call(parser: &mut Parser, _global_store: &mut GlobalStore) ->
202
222
  TokenKind::Number => Value::Number(token.lexeme.parse::<f32>().unwrap_or(0.0)),
203
223
  TokenKind::LBrace => {
204
224
  // Handle map literal (supports nested maps)
205
- let map_val = parse_map_literal(parser);
225
+
206
226
  // We consumed the matching '}', so outer map_depth should be decremented
207
227
  // if the caller tracks it.
208
- map_val
228
+ parse_map_literal(parser)
209
229
  }
210
230
  _ => Value::Unknown,
211
231
  };