@devaloop/devalang 0.0.1-alpha.2 → 0.0.1-alpha.3

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 (96) hide show
  1. package/Cargo.toml +46 -46
  2. package/README.md +7 -6
  3. package/docs/CHANGELOG.md +11 -6
  4. package/docs/ROADMAP.md +5 -1
  5. package/docs/TODO.md +6 -31
  6. package/examples/exported.deva +1 -1
  7. package/examples/index.deva +1 -0
  8. package/out-tsc/bin/devalang.exe +0 -0
  9. package/package.json +1 -2
  10. package/project-version.json +3 -3
  11. package/rust/cli/build.rs +57 -40
  12. package/rust/cli/check.rs +47 -111
  13. package/rust/cli/init.rs +1 -1
  14. package/rust/cli/mod.rs +174 -2
  15. package/rust/{utils/config.rs → config/loader.rs} +3 -2
  16. package/rust/{core/types/config.rs → config/mod.rs} +5 -5
  17. package/rust/core/builder/mod.rs +21 -27
  18. package/rust/core/debugger/lexer.rs +12 -0
  19. package/rust/core/debugger/mod.rs +12 -49
  20. package/rust/core/debugger/preprocessor.rs +23 -0
  21. package/rust/core/error/mod.rs +60 -0
  22. package/rust/core/lexer/{at.rs → handler/at.rs} +1 -1
  23. package/rust/core/lexer/{brace.rs → handler/brace.rs} +1 -1
  24. package/rust/core/lexer/{colon.rs → handler/colon.rs} +1 -1
  25. package/rust/core/lexer/{comment.rs → handler/comment.rs} +3 -3
  26. package/rust/core/lexer/{dot.rs → handler/dot.rs} +1 -1
  27. package/rust/core/lexer/{equal.rs → handler/equal.rs} +1 -1
  28. package/rust/core/lexer/{identifier.rs → handler/identifier.rs} +1 -1
  29. package/rust/core/lexer/{indent.rs → handler/indent.rs} +10 -5
  30. package/rust/core/lexer/handler/mod.rs +238 -0
  31. package/rust/core/lexer/{newline.rs → handler/newline.rs} +6 -10
  32. package/rust/core/lexer/{number.rs → handler/number.rs} +1 -1
  33. package/rust/core/lexer/handler/string.rs +66 -0
  34. package/rust/core/lexer/mod.rs +25 -14
  35. package/rust/core/lexer/token.rs +55 -0
  36. package/rust/core/mod.rs +5 -2
  37. package/rust/core/parser/handler/at.rs +166 -0
  38. package/rust/core/parser/handler/bank.rs +38 -0
  39. package/rust/core/parser/handler/dot.rs +112 -0
  40. package/rust/core/parser/handler/identifier.rs +134 -0
  41. package/rust/core/parser/handler/loop_.rs +55 -0
  42. package/rust/core/parser/handler/mod.rs +6 -0
  43. package/rust/core/parser/handler/tempo.rs +47 -0
  44. package/rust/core/parser/mod.rs +204 -166
  45. package/rust/core/parser/statement.rs +91 -0
  46. package/rust/core/preprocessor/loader.rs +105 -0
  47. package/rust/core/preprocessor/mod.rs +2 -24
  48. package/rust/core/preprocessor/module.rs +37 -56
  49. package/rust/core/preprocessor/processor.rs +41 -0
  50. package/rust/core/preprocessor/resolver.rs +372 -0
  51. package/rust/core/shared/duration.rs +8 -0
  52. package/rust/core/shared/mod.rs +2 -0
  53. package/rust/core/shared/value.rs +18 -0
  54. package/rust/core/store/export.rs +28 -0
  55. package/rust/core/store/global.rs +39 -0
  56. package/rust/core/store/import.rs +28 -0
  57. package/rust/core/store/mod.rs +4 -0
  58. package/rust/core/store/variable.rs +28 -0
  59. package/rust/core/utils/mod.rs +2 -0
  60. package/rust/core/utils/validation.rs +35 -0
  61. package/rust/lib.rs +0 -1
  62. package/rust/main.rs +17 -19
  63. package/rust/utils/logger.rs +69 -34
  64. package/rust/utils/mod.rs +3 -5
  65. package/templates/minimal/.devalang +1 -1
  66. package/templates/welcome/.devalang +1 -1
  67. package/rust/audio/mod.rs +0 -1
  68. package/rust/core/lexer/bracket.rs +0 -41
  69. package/rust/core/lexer/driver.rs +0 -286
  70. package/rust/core/lexer/quote.rs +0 -61
  71. package/rust/core/parser/at.rs +0 -142
  72. package/rust/core/parser/bank.rs +0 -42
  73. package/rust/core/parser/dot.rs +0 -137
  74. package/rust/core/parser/identifer.rs +0 -91
  75. package/rust/core/parser/loop_.rs +0 -62
  76. package/rust/core/parser/tempo.rs +0 -42
  77. package/rust/core/parser/variable.rs +0 -129
  78. package/rust/core/preprocessor/dependencies.rs +0 -54
  79. package/rust/core/preprocessor/resolver/at.rs +0 -24
  80. package/rust/core/preprocessor/resolver/bank.rs +0 -59
  81. package/rust/core/preprocessor/resolver/loop_.rs +0 -82
  82. package/rust/core/preprocessor/resolver/mod.rs +0 -113
  83. package/rust/core/preprocessor/resolver/tempo.rs +0 -70
  84. package/rust/core/preprocessor/resolver/trigger.rs +0 -176
  85. package/rust/core/types/cli.rs +0 -182
  86. package/rust/core/types/mod.rs +0 -8
  87. package/rust/core/types/module.rs +0 -41
  88. package/rust/core/types/parser.rs +0 -73
  89. package/rust/core/types/statement.rs +0 -105
  90. package/rust/core/types/store.rs +0 -116
  91. package/rust/core/types/token.rs +0 -83
  92. package/rust/core/types/variable.rs +0 -32
  93. package/rust/runner/executer.rs +0 -44
  94. package/rust/runner/mod.rs +0 -1
  95. /package/rust/{utils → core/utils}/path.rs +0 -0
  96. /package/rust/utils/{loader.rs → spinner.rs} +0 -0
@@ -0,0 +1,112 @@
1
+ use crate::core::{
2
+ lexer::token::TokenKind,
3
+ parser::{ statement::{ Statement, StatementKind }, Parser },
4
+ shared::{ duration::Duration, value::Value },
5
+ store::global::GlobalStore,
6
+ };
7
+
8
+ pub fn parse_dot_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> Statement {
9
+ parser.advance(); // consume the dot token
10
+
11
+ let Some(dot_token) = parser.previous_clone() else {
12
+ return Statement::unknown();
13
+ };
14
+
15
+ // .kick
16
+ let Some(entity_token) = parser.peek_clone() else {
17
+ return Statement {
18
+ kind: StatementKind::Trigger {
19
+ entity: String::new(),
20
+ duration: Duration::Auto,
21
+ },
22
+ value: Value::Null,
23
+ indent: dot_token.indent,
24
+ line: dot_token.line,
25
+ column: dot_token.column,
26
+ };
27
+ };
28
+
29
+ parser.advance(); // consume entity
30
+ let entity = entity_token.lexeme.clone();
31
+
32
+ // Check if there's a duration
33
+ let next = parser.peek_clone();
34
+
35
+ let (duration, value) = match next {
36
+ // If no more tokens, it's just `.kick`
37
+ None => (Duration::Auto, Value::Null),
38
+
39
+ Some(token) =>
40
+ match token.kind {
41
+ TokenKind::Newline | TokenKind::EOF => { (Duration::Auto, Value::Null) }
42
+
43
+ TokenKind::Number => {
44
+ let duration_lexeme = token.lexeme.clone();
45
+ parser.advance(); // consume duration
46
+
47
+ // Try to parse optional value (ex: .kick 250 params)
48
+ match parser.peek_clone() {
49
+ Some(param_token) if param_token.kind == TokenKind::Identifier => {
50
+ parser.advance();
51
+ (
52
+ parse_duration(duration_lexeme),
53
+ Value::Identifier(param_token.lexeme.clone()),
54
+ )
55
+ }
56
+
57
+ Some(param_token) if param_token.kind == TokenKind::LBrace => {
58
+ // Handle value as Map
59
+ let map = parser.parse_map_value(); // Assumes you have a helper for map
60
+ (parse_duration(duration_lexeme), map.unwrap_or(Value::Null))
61
+ }
62
+
63
+ _ => (parse_duration(duration_lexeme), Value::Null),
64
+ }
65
+ }
66
+
67
+ TokenKind::Identifier => {
68
+ let duration_lexeme = token.lexeme.clone();
69
+ parser.advance(); // consume duration
70
+
71
+ // Try to parse optional value (ex: .kick auto params)
72
+ match parser.peek_clone() {
73
+ Some(param_token) if param_token.kind == TokenKind::Identifier => {
74
+ parser.advance();
75
+ (
76
+ parse_duration(duration_lexeme),
77
+ Value::Identifier(param_token.lexeme.clone()),
78
+ )
79
+ }
80
+
81
+ Some(param_token) if param_token.kind == TokenKind::LBrace => {
82
+ // Handle value as Map
83
+ let map = parser.parse_map_value(); // Assumes you have a helper for map
84
+ (parse_duration(duration_lexeme), map.unwrap_or(Value::Null))
85
+ }
86
+
87
+ _ => (parse_duration(duration_lexeme), Value::Null),
88
+ }
89
+ }
90
+
91
+ _ => (Duration::Auto, Value::Null),
92
+ }
93
+ };
94
+
95
+ Statement {
96
+ kind: StatementKind::Trigger { entity, duration },
97
+ value,
98
+ indent: dot_token.indent,
99
+ line: dot_token.line,
100
+ column: dot_token.column,
101
+ }
102
+ }
103
+
104
+ fn parse_duration(s: String) -> Duration {
105
+ if s == "auto" {
106
+ Duration::Auto
107
+ } else if s.parse::<f32>().is_ok() {
108
+ Duration::Number(s.parse().unwrap())
109
+ } else {
110
+ Duration::Identifier(s)
111
+ }
112
+ }
@@ -0,0 +1,134 @@
1
+ use crate::core::{
2
+ lexer::token::{ Token, TokenKind },
3
+ parser::{ statement::{ Statement, StatementKind }, Parser },
4
+ shared::value::Value,
5
+ store::global::GlobalStore,
6
+ };
7
+ use std::collections::HashMap;
8
+
9
+ pub fn parse_identifier_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> Statement {
10
+ let Some(current_token) = parser.peek_clone() else {
11
+ return Statement::unknown();
12
+ };
13
+
14
+ if current_token.lexeme == "let" {
15
+ parser.advance(); // consume "let"
16
+
17
+ let identifier = if let Some(token) = parser.peek_clone() {
18
+ if token.kind == TokenKind::Identifier {
19
+ parser.advance();
20
+ token.lexeme.clone()
21
+ } else {
22
+ return Statement::error(token, "Expected identifier after 'let'".to_string());
23
+ }
24
+ } else {
25
+ return Statement::error(current_token, "Expected identifier after 'let'".to_string());
26
+ };
27
+
28
+ if !parser.match_token(TokenKind::Equals) {
29
+ return Statement::error(current_token, "Expected '=' after identifier".to_string());
30
+ }
31
+
32
+ let value = match parser.peek_clone() {
33
+ Some(token) if token.kind == TokenKind::Identifier => {
34
+ parser.advance();
35
+ Value::Identifier(token.lexeme.clone())
36
+ }
37
+ Some(token) if token.kind == TokenKind::String => {
38
+ parser.advance();
39
+ Value::String(token.lexeme.clone())
40
+ }
41
+ Some(token) if token.kind == TokenKind::Number => {
42
+ parser.advance();
43
+ Value::Number(token.lexeme.parse().unwrap_or(0.0))
44
+ }
45
+ Some(token) if token.kind == TokenKind::LBrace => {
46
+ parser.advance(); // consume '{'
47
+ let mut map = HashMap::new();
48
+
49
+ while let Some(key_token) = parser.peek_clone() {
50
+ if key_token.kind == TokenKind::RBrace {
51
+ parser.advance(); // consume '}'
52
+ break;
53
+ }
54
+
55
+ if key_token.kind != TokenKind::Identifier {
56
+ return Statement::error(
57
+ token,
58
+ "Expected key identifier in map".to_string()
59
+ );
60
+ }
61
+ parser.advance();
62
+ let key = key_token.lexeme.clone();
63
+
64
+ if !parser.match_token(TokenKind::Colon) {
65
+ let message = format!("Expected ':' after key '{}'", key);
66
+ return Statement::error(token, message);
67
+ }
68
+
69
+ let val = match parser.peek_clone() {
70
+ Some(t) if t.kind == TokenKind::Number => {
71
+ parser.advance();
72
+ Value::Number(t.lexeme.parse().unwrap_or(0.0))
73
+ }
74
+ Some(t) if t.kind == TokenKind::String => {
75
+ parser.advance();
76
+ Value::String(t.lexeme.clone())
77
+ }
78
+ Some(t) if t.kind == TokenKind::Identifier => {
79
+ parser.advance();
80
+ Value::Identifier(t.lexeme.clone())
81
+ }
82
+ _ => { Value::Null }
83
+ };
84
+
85
+ if val == Value::Null {
86
+ let message = format!("Invalid value for key '{}'", key);
87
+ return Statement::error(token, message);
88
+ }
89
+
90
+ map.insert(key, val);
91
+
92
+ if let Some(t) = parser.peek() {
93
+ if t.kind == TokenKind::Comma {
94
+ parser.advance(); // skip comma
95
+ }
96
+ }
97
+ }
98
+
99
+ Value::Map(map)
100
+ }
101
+ other => {
102
+ let message = format!("Unexpected value token in let: {:?}", other);
103
+ return Statement::error(current_token, message);
104
+ }
105
+ };
106
+
107
+ return Statement {
108
+ kind: StatementKind::Let { name: identifier },
109
+ value,
110
+ indent: current_token.indent,
111
+ line: current_token.line,
112
+ column: current_token.column,
113
+ };
114
+ } else {
115
+ // Unknown identifier handling
116
+ Statement {
117
+ kind: StatementKind::Unknown,
118
+ value: Value::String(current_token.lexeme.clone()),
119
+ indent: current_token.indent,
120
+ line: current_token.line,
121
+ column: current_token.column,
122
+ };
123
+ }
124
+
125
+ parser.advance(); // unknown identifier fallback
126
+
127
+ Statement {
128
+ kind: StatementKind::Unknown,
129
+ value: Value::String(current_token.lexeme.clone()),
130
+ indent: current_token.indent,
131
+ line: current_token.line,
132
+ column: current_token.column,
133
+ }
134
+ }
@@ -0,0 +1,55 @@
1
+ use std::collections::HashMap;
2
+
3
+ use crate::core::{
4
+ lexer::{ token::TokenKind },
5
+ parser::{ statement::{ Statement, StatementKind }, Parser },
6
+ shared::value::Value,
7
+ store::global::GlobalStore,
8
+ };
9
+
10
+ pub fn parse_loop_token(parser: &mut Parser, global_store: &mut GlobalStore) -> Statement {
11
+ parser.advance(); // consume 'loop'
12
+
13
+ let Some(loop_token) = parser.previous_clone() else {
14
+ return Statement::unknown();
15
+ };
16
+
17
+ // Expect an identifier (iterator)
18
+ let Some(iterator_token) = parser.peek_clone() else {
19
+ return Statement::error(loop_token, "Expected identifier after 'loop'".to_string());
20
+ };
21
+
22
+ let iterator_name = iterator_token.lexeme.clone();
23
+ parser.advance(); // consume iterator
24
+
25
+ // Expect colon
26
+ let Some(colon_token) = parser.peek_clone() else {
27
+ return Statement::error(iterator_token.clone(), "Expected ':' after iterator".to_string());
28
+ };
29
+
30
+ if colon_token.kind != TokenKind::Colon {
31
+ let message = format!("Expected ':' after iterator, got {:?}", colon_token.kind);
32
+ return Statement::error(colon_token.clone(), message);
33
+ }
34
+
35
+ parser.advance(); // consume ':'
36
+
37
+ // Collect all indented statements
38
+ let tokens = parser.collect_until(
39
+ |t| (t.kind == TokenKind::Dedent || t.kind == TokenKind::EOF)
40
+ );
41
+ let loop_body = parser.parse_block(tokens.clone(), global_store);
42
+
43
+ let mut value_map = HashMap::new();
44
+
45
+ value_map.insert("iterator".to_string(), Value::Identifier(iterator_name));
46
+ value_map.insert("body".to_string(), Value::Block(loop_body.clone()));
47
+
48
+ Statement {
49
+ kind: StatementKind::Loop,
50
+ value: Value::Map(value_map),
51
+ indent: loop_token.indent,
52
+ line: loop_token.line,
53
+ column: loop_token.column,
54
+ }
55
+ }
@@ -0,0 +1,6 @@
1
+ pub mod at;
2
+ pub mod identifier;
3
+ pub mod dot;
4
+ pub mod tempo;
5
+ pub mod bank;
6
+ pub mod loop_;
@@ -0,0 +1,47 @@
1
+ use crate::core::{
2
+ lexer::token::TokenKind,
3
+ parser::{ statement::{ Statement, StatementKind }, Parser },
4
+ shared::value::Value,
5
+ store::global::GlobalStore,
6
+ };
7
+
8
+ pub fn parse_tempo_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> Statement {
9
+ parser.advance(); // consume 'bpm'
10
+
11
+ let Some(tempo_token) = parser.previous_clone() else {
12
+ return Statement::unknown();
13
+ };
14
+
15
+ // Expect a number or identifier
16
+ let Some(value_token) = parser.peek_clone() else {
17
+ return Statement::error(
18
+ tempo_token,
19
+ "Expected a number or identifier after 'bpm'".to_string()
20
+ );
21
+ };
22
+
23
+ let value = match value_token.kind {
24
+ TokenKind::Number => {
25
+ parser.advance();
26
+ Value::Number(value_token.lexeme.parse().unwrap_or(0.0))
27
+ }
28
+ TokenKind::Identifier => {
29
+ parser.advance();
30
+ Value::Identifier(value_token.lexeme.clone())
31
+ }
32
+ _ => {
33
+ return Statement::error(
34
+ value_token.clone(),
35
+ format!("Expected a number or identifier after 'bpm', got {:?}", value_token.kind)
36
+ );
37
+ }
38
+ };
39
+
40
+ Statement {
41
+ kind: StatementKind::Tempo,
42
+ value,
43
+ indent: tempo_token.indent,
44
+ line: tempo_token.line,
45
+ column: tempo_token.column,
46
+ }
47
+ }