@devaloop/devalang 0.0.1-alpha.1 → 0.0.1-alpha.10

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 (155) hide show
  1. package/.devalang +4 -0
  2. package/Cargo.toml +49 -45
  3. package/README.md +127 -46
  4. package/docs/CHANGELOG.md +172 -0
  5. package/docs/COMMANDS.md +60 -6
  6. package/docs/CONFIG.md +30 -0
  7. package/docs/ROADMAP.md +10 -7
  8. package/docs/SYNTAX.md +100 -18
  9. package/docs/TODO.md +31 -28
  10. package/examples/condition.deva +20 -0
  11. package/examples/group.deva +12 -0
  12. package/examples/index.deva +13 -4
  13. package/examples/loop.deva +16 -0
  14. package/examples/samples/hat-808.wav +0 -0
  15. package/examples/synth.deva +14 -0
  16. package/examples/variables.deva +9 -0
  17. package/out-tsc/bin/devalang.exe +0 -0
  18. package/out-tsc/scripts/version/fetch.js +1 -5
  19. package/package.json +5 -4
  20. package/project-version.json +3 -3
  21. package/rust/cli/build.rs +114 -28
  22. package/rust/cli/check.rs +96 -103
  23. package/rust/cli/init.rs +79 -0
  24. package/rust/cli/mod.rs +203 -1
  25. package/rust/cli/play.rs +193 -0
  26. package/rust/cli/template.rs +57 -0
  27. package/rust/config/loader.rs +13 -0
  28. package/rust/config/mod.rs +16 -0
  29. package/rust/core/audio/engine.rs +214 -0
  30. package/rust/core/audio/evaluator.rs +31 -0
  31. package/rust/core/audio/interpreter/arrow_call.rs +129 -0
  32. package/rust/core/audio/interpreter/call.rs +70 -0
  33. package/rust/core/audio/interpreter/condition.rs +69 -0
  34. package/rust/core/audio/interpreter/driver.rs +236 -0
  35. package/rust/core/audio/interpreter/let_.rs +19 -0
  36. package/rust/core/audio/interpreter/load.rs +18 -0
  37. package/rust/core/audio/interpreter/loop_.rs +67 -0
  38. package/rust/core/audio/interpreter/mod.rs +12 -0
  39. package/rust/core/audio/interpreter/sleep.rs +36 -0
  40. package/rust/core/audio/interpreter/spawn.rs +84 -0
  41. package/rust/core/audio/interpreter/tempo.rs +16 -0
  42. package/rust/core/audio/interpreter/trigger.rs +69 -0
  43. package/rust/core/audio/loader/mod.rs +1 -0
  44. package/rust/core/audio/loader/trigger.rs +52 -0
  45. package/rust/core/audio/mod.rs +6 -0
  46. package/rust/core/audio/player.rs +54 -0
  47. package/rust/core/audio/renderer.rs +54 -0
  48. package/rust/core/builder/mod.rs +70 -27
  49. package/rust/core/debugger/lexer.rs +27 -0
  50. package/rust/core/debugger/mod.rs +13 -49
  51. package/rust/core/debugger/preprocessor.rs +27 -0
  52. package/rust/core/debugger/store.rs +25 -0
  53. package/rust/core/error/mod.rs +60 -0
  54. package/rust/core/lexer/handler/arrow.rs +31 -0
  55. package/rust/core/lexer/handler/at.rs +21 -0
  56. package/rust/core/lexer/handler/brace.rs +41 -0
  57. package/rust/core/lexer/handler/colon.rs +21 -0
  58. package/rust/core/lexer/handler/comment.rs +30 -0
  59. package/rust/core/lexer/handler/dot.rs +21 -0
  60. package/rust/core/lexer/handler/driver.rs +230 -0
  61. package/rust/core/lexer/handler/identifier.rs +41 -0
  62. package/rust/core/lexer/handler/indent.rs +52 -0
  63. package/rust/core/lexer/handler/mod.rs +14 -0
  64. package/rust/core/lexer/handler/newline.rs +23 -0
  65. package/rust/core/lexer/handler/number.rs +31 -0
  66. package/rust/core/lexer/handler/operator.rs +44 -0
  67. package/rust/core/lexer/handler/string.rs +63 -0
  68. package/rust/core/lexer/mod.rs +37 -319
  69. package/rust/core/lexer/token.rs +86 -0
  70. package/rust/core/mod.rs +6 -2
  71. package/rust/core/parser/driver.rs +331 -0
  72. package/rust/core/parser/handler/arrow_call.rs +126 -0
  73. package/rust/core/parser/handler/at.rs +162 -0
  74. package/rust/core/parser/handler/bank.rs +41 -0
  75. package/rust/core/parser/handler/condition.rs +74 -0
  76. package/rust/core/parser/handler/dot.rs +112 -0
  77. package/rust/core/parser/handler/identifier/call.rs +41 -0
  78. package/rust/core/parser/handler/identifier/group.rs +75 -0
  79. package/rust/core/parser/handler/identifier/let_.rs +133 -0
  80. package/rust/core/parser/handler/identifier/mod.rs +51 -0
  81. package/rust/core/parser/handler/identifier/sleep.rs +33 -0
  82. package/rust/core/parser/handler/identifier/spawn.rs +41 -0
  83. package/rust/core/parser/handler/identifier/synth.rs +65 -0
  84. package/rust/core/parser/handler/loop_.rs +72 -0
  85. package/rust/core/parser/handler/mod.rs +8 -0
  86. package/rust/core/parser/handler/tempo.rs +47 -0
  87. package/rust/core/parser/mod.rs +3 -200
  88. package/rust/core/parser/statement.rs +96 -0
  89. package/rust/core/preprocessor/loader.rs +229 -0
  90. package/rust/core/preprocessor/mod.rs +2 -24
  91. package/rust/core/preprocessor/module.rs +42 -56
  92. package/rust/core/preprocessor/processor.rs +76 -0
  93. package/rust/core/preprocessor/resolver/bank.rs +41 -51
  94. package/rust/core/preprocessor/resolver/call.rs +123 -0
  95. package/rust/core/preprocessor/resolver/condition.rs +92 -0
  96. package/rust/core/preprocessor/resolver/driver.rs +227 -0
  97. package/rust/core/preprocessor/resolver/group.rs +61 -0
  98. package/rust/core/preprocessor/resolver/let_.rs +31 -0
  99. package/rust/core/preprocessor/resolver/loop_.rs +76 -67
  100. package/rust/core/preprocessor/resolver/mod.rs +12 -111
  101. package/rust/core/preprocessor/resolver/spawn.rs +58 -0
  102. package/rust/core/preprocessor/resolver/synth.rs +50 -0
  103. package/rust/core/preprocessor/resolver/tempo.rs +40 -61
  104. package/rust/core/preprocessor/resolver/trigger.rs +90 -154
  105. package/rust/core/preprocessor/resolver/value.rs +78 -0
  106. package/rust/core/shared/duration.rs +8 -0
  107. package/rust/core/shared/mod.rs +2 -0
  108. package/rust/core/shared/value.rs +28 -0
  109. package/rust/core/store/export.rs +28 -0
  110. package/rust/core/store/global.rs +39 -0
  111. package/rust/core/store/import.rs +28 -0
  112. package/rust/core/store/mod.rs +4 -0
  113. package/rust/core/store/variable.rs +28 -0
  114. package/rust/core/utils/mod.rs +2 -0
  115. package/rust/core/utils/path.rs +31 -0
  116. package/rust/core/utils/validation.rs +37 -0
  117. package/rust/lib.rs +161 -1
  118. package/rust/main.rs +46 -30
  119. package/rust/utils/file.rs +35 -0
  120. package/rust/utils/logger.rs +108 -34
  121. package/rust/utils/mod.rs +3 -2
  122. package/rust/utils/{loader.rs → spinner.rs} +2 -0
  123. package/rust/utils/watcher.rs +33 -0
  124. package/templates/minimal/.devalang +5 -0
  125. package/templates/minimal/README.md +202 -0
  126. package/templates/minimal/src/index.deva +2 -0
  127. package/templates/welcome/.devalang +5 -0
  128. package/templates/welcome/README.md +202 -0
  129. package/templates/welcome/samples/kick-808.wav +0 -0
  130. package/templates/welcome/src/index.deva +13 -0
  131. package/templates/welcome/src/variables.deva +5 -0
  132. package/typescript/scripts/version/fetch.ts +1 -6
  133. package/examples/exported.deva +0 -7
  134. package/rust/audio/mod.rs +0 -1
  135. package/rust/cli/new.rs +0 -1
  136. package/rust/core/parser/at.rs +0 -142
  137. package/rust/core/parser/bank.rs +0 -42
  138. package/rust/core/parser/dot.rs +0 -107
  139. package/rust/core/parser/identifer.rs +0 -91
  140. package/rust/core/parser/loop_.rs +0 -62
  141. package/rust/core/parser/tempo.rs +0 -42
  142. package/rust/core/parser/variable.rs +0 -129
  143. package/rust/core/preprocessor/dependencies.rs +0 -54
  144. package/rust/core/preprocessor/resolver/at.rs +0 -24
  145. package/rust/core/types/cli.rs +0 -160
  146. package/rust/core/types/mod.rs +0 -7
  147. package/rust/core/types/module.rs +0 -41
  148. package/rust/core/types/parser.rs +0 -73
  149. package/rust/core/types/statement.rs +0 -105
  150. package/rust/core/types/store.rs +0 -116
  151. package/rust/core/types/token.rs +0 -83
  152. package/rust/core/types/variable.rs +0 -32
  153. package/rust/runner/executer.rs +0 -44
  154. package/rust/runner/mod.rs +0 -1
  155. package/rust/utils/path.rs +0 -46
@@ -0,0 +1,50 @@
1
+ use crate::{
2
+ core::{
3
+ parser::statement::{ Statement, StatementKind },
4
+ preprocessor::{ module::Module, resolver::driver::resolve_statement },
5
+ shared::value::Value,
6
+ store::global::GlobalStore,
7
+ },
8
+ utils::logger::{ LogLevel, Logger },
9
+ };
10
+
11
+ pub fn resolve_synth(
12
+ stmt: &Statement,
13
+ module: &Module,
14
+ path: &str,
15
+ global_store: &mut GlobalStore
16
+ ) -> Statement {
17
+ let logger = Logger::new();
18
+
19
+ let Value::Map(synth_map) = &stmt.value else {
20
+ return type_error(&logger, module, stmt, "Expected a map in synth statement".to_string());
21
+ };
22
+
23
+ let mut resolved_map = synth_map.clone();
24
+
25
+ if let Some(Value::Block(body)) = synth_map.get("body") {
26
+ let resolved_body = body.iter()
27
+ .map(|s| resolve_statement(s, module, path, global_store))
28
+ .collect::<Vec<_>>();
29
+ resolved_map.insert("body".to_string(), Value::Block(resolved_body));
30
+ } else {
31
+ logger.log_message(LogLevel::Warning, "synth without a body");
32
+ }
33
+
34
+ Statement {
35
+ kind: StatementKind::Synth,
36
+ value: Value::Map(resolved_map),
37
+ ..stmt.clone()
38
+ }
39
+ }
40
+
41
+ fn type_error(logger: &Logger, module: &Module, stmt: &Statement, message: String) -> Statement {
42
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
43
+ logger.log_error_with_stacktrace(&message, &stacktrace);
44
+
45
+ Statement {
46
+ kind: StatementKind::Error { message },
47
+ value: Value::Null,
48
+ ..stmt.clone()
49
+ }
50
+ }
@@ -1,70 +1,49 @@
1
- use crate::core::types::{module::Module, statement::{Statement, StatementKind, StatementResolved, StatementResolvedValue}, variable::VariableValue};
1
+ use crate::{
2
+ core::{
3
+ parser::statement::{ Statement, StatementKind },
4
+ preprocessor::module::Module,
5
+ shared::value::Value,
6
+ store::global::GlobalStore,
7
+ },
8
+ utils::logger::Logger,
9
+ };
2
10
 
3
- pub fn resolve_tempo_statement(
4
- tempo_statement: &Statement,
5
- module: &Module
6
- ) -> StatementResolved {
7
- match &tempo_statement.value {
8
- VariableValue::Number(num) => {
9
- if *num > 0.0 {
10
- StatementResolved {
11
- kind: StatementKind::Tempo,
12
- value: StatementResolvedValue::Number(*num),
13
- indent: tempo_statement.indent,
14
- line: tempo_statement.line,
15
- column: tempo_statement.column,
16
- }
11
+ pub fn resolve_tempo(
12
+ stmt: &Statement,
13
+ module: &Module,
14
+ path: &str,
15
+ _global_store: &GlobalStore
16
+ ) -> Statement {
17
+ let mut new_stmt = stmt.clone();
18
+ let logger = Logger::new();
19
+
20
+ match &stmt.value {
21
+ Value::Identifier(ident) => {
22
+ if let Some(val) = module.variable_table.get(ident) {
23
+ new_stmt.value = val.clone();
17
24
  } else {
18
- eprintln!("⚠️ Invalid tempo value: {}", num);
19
- StatementResolved {
20
- kind: StatementKind::Tempo,
21
- value: StatementResolvedValue::Unknown,
22
- indent: tempo_statement.indent,
23
- line: tempo_statement.line,
24
- column: tempo_statement.column,
25
- }
25
+ let message = format!("Tempo identifier '{ident}' not found in variable table");
26
+ logger.log_error_with_stacktrace(&message, &module.path);
27
+ new_stmt.kind = StatementKind::Error {
28
+ message,
29
+ };
30
+ new_stmt.value = Value::Null;
26
31
  }
27
32
  }
28
- VariableValue::Text(text) => {
29
- if let Some(value) = module.variable_table.variables.get(text) {
30
- let variable_value: StatementResolvedValue = match value {
31
- VariableValue::Number(num) if *num > 0.0 => {
32
- StatementResolvedValue::Number(*num)
33
- }
34
- VariableValue::Text(t) => StatementResolvedValue::String(t.clone()),
35
- _ => {
36
- eprintln!("⚠️ Unsupported variable type for Tempo: {:?}", value);
37
- StatementResolvedValue::Unknown
38
- }
39
- };
40
33
 
41
- StatementResolved {
42
- kind: StatementKind::Tempo,
43
- value: variable_value,
44
- indent: tempo_statement.indent,
45
- line: tempo_statement.line,
46
- column: tempo_statement.column,
47
- }
48
- } else {
49
- eprintln!("⚠️ Tempo variable '{}' not found", text);
50
- StatementResolved {
51
- kind: StatementKind::Tempo,
52
- value: StatementResolvedValue::Unknown,
53
- indent: tempo_statement.indent,
54
- line: tempo_statement.line,
55
- column: tempo_statement.column,
56
- }
57
- }
34
+ Value::Number(_) => {
35
+ // Already resolved, no modification needed
58
36
  }
59
- _ => {
60
- eprintln!("⚠️ Invalid value type for Tempo statement: {:?}", tempo_statement.value);
61
- StatementResolved {
62
- kind: StatementKind::Tempo,
63
- value: StatementResolvedValue::Unknown,
64
- indent: tempo_statement.indent,
65
- line: tempo_statement.line,
66
- column: tempo_statement.column,
67
- }
37
+
38
+ other => {
39
+ let message = format!("Expected a number or identifier for tempo, found {:?}", other);
40
+ logger.log_error_with_stacktrace(&message, &module.path);
41
+ new_stmt.kind = StatementKind::Error {
42
+ message: "Expected a number or identifier for tempo".to_string(),
43
+ };
44
+ new_stmt.value = Value::Null;
68
45
  }
69
46
  }
47
+
48
+ new_stmt
70
49
  }
@@ -1,176 +1,112 @@
1
1
  use std::collections::HashMap;
2
2
 
3
- use crate::core::{
4
- parser::parse_with_resolving_with_module,
5
- types::{
6
- module::Module,
7
- statement::{ Statement, StatementKind, StatementResolved, StatementResolvedValue },
8
- token::{ TokenDuration, TokenParamValue },
9
- variable::VariableValue,
3
+ use crate::{
4
+ core::{
5
+ parser::statement::{ Statement, StatementKind },
6
+ preprocessor::module::Module,
7
+ shared::{ duration::Duration, value::Value },
8
+ store::global::GlobalStore,
10
9
  },
10
+ utils::logger::Logger,
11
11
  };
12
12
 
13
- pub fn resolve_trigger_statement(
13
+ pub fn resolve_trigger(
14
14
  stmt: &Statement,
15
- entity: String,
16
- duration: TokenDuration,
17
- module: &Module
18
- ) -> StatementResolved {
19
- let mut entity_value = VariableValue::Unknown;
20
-
21
- if let Some(value) = module.variable_table.variables.get(&entity) {
22
- entity_value = value.clone();
23
- } else {
24
- entity_value = VariableValue::Text(entity.clone());
25
- }
26
-
27
- let duration_raw_value = match duration {
28
- TokenDuration::Auto => "auto",
29
- TokenDuration::Infinite => "infinite",
30
- TokenDuration::Number(n) => &n.to_string(),
31
- TokenDuration::Identifier(ref id) => id.as_str(),
32
- _ => "unknown",
33
- };
34
-
35
- let duration_variable_value = module.variable_table.variables.get(duration_raw_value);
36
- let mut parsed_duration_value = TokenDuration::Unknown;
37
-
38
- if duration_variable_value.is_some() {
39
- parsed_duration_value = duration_variable_value
40
- .as_ref()
41
- .map_or(TokenDuration::Unknown, |value| {
42
- match value {
43
- VariableValue::Text(text) => TokenDuration::Identifier(text.clone()),
44
- VariableValue::Number(num) => TokenDuration::Number(*num),
45
- VariableValue::Boolean(_) => TokenDuration::Unknown,
46
- _ => {
47
- eprintln!("⚠️ Invalid duration type for Trigger: {:?}", value);
48
- TokenDuration::Unknown
49
- }
15
+ entity: &str,
16
+ duration: &mut Duration,
17
+ module: &Module,
18
+ path: &str,
19
+ global_store: &GlobalStore
20
+ ) -> Statement {
21
+ let logger = Logger::new();
22
+
23
+ let mut final_duration = duration.clone();
24
+ let mut final_value = stmt.value.clone();
25
+
26
+ // Duration resolution
27
+ if let Duration::Identifier(ident) = duration {
28
+ if let Some(val) = resolve_identifier(ident, module, global_store) {
29
+ match val {
30
+ Value::Number(n) => {
31
+ final_duration = Duration::Number(n);
50
32
  }
51
- });
52
- } else if let Ok(num) = duration_raw_value.parse::<f32>() {
53
- parsed_duration_value = TokenDuration::Number(num);
54
- } else if duration_raw_value == "auto" {
55
- parsed_duration_value = TokenDuration::Auto;
56
- } else if duration_raw_value == "infinite" {
57
- parsed_duration_value = TokenDuration::Infinite;
58
- } else {
59
- eprintln!("⚠️ Invalid duration format: {}", duration_raw_value);
60
- }
61
-
62
- match &stmt.value {
63
- VariableValue::Text(text) => {
64
- if let Some(value) = module.variable_table.variables.get(text) {
65
- let parsed_entity_value: StatementResolvedValue = match value {
66
- VariableValue::Array(arr) => {
67
- StatementResolvedValue::Array(
68
- parse_with_resolving_with_module(arr.clone(), module)
69
- )
70
- }
71
- VariableValue::Map(map) => {
72
- let mut resolved_map = HashMap::new();
73
-
74
- for (key, value) in map {
75
- let resolved_value = match value {
76
- TokenParamValue::String(text) =>
77
- StatementResolvedValue::String(text.clone()),
78
- TokenParamValue::Number(num) =>
79
- StatementResolvedValue::Number(*num),
80
- TokenParamValue::Boolean(b) => StatementResolvedValue::Boolean(*b),
81
- _ => {
82
- eprintln!(
83
- "⚠️ Unsupported variable type for Trigger map: {:?}",
84
- value
85
- );
86
- StatementResolvedValue::Unknown
87
- }
88
- };
89
- resolved_map.insert(key.clone(), resolved_value);
90
- }
91
-
92
- StatementResolvedValue::Map(resolved_map)
93
- }
94
-
95
- | VariableValue::Text(_)
96
- | VariableValue::Number(_)
97
- | VariableValue::Boolean(_) => {
98
- StatementResolvedValue::String(text.clone())
99
- }
100
- _ => {
101
- eprintln!("⚠️ Unsupported variable type for Trigger entity: {:?}", value);
102
- StatementResolvedValue::Unknown
103
- }
104
- };
105
-
106
- StatementResolved {
107
- kind: StatementKind::Trigger {
108
- entity: entity.clone(),
109
- duration: parsed_duration_value,
110
- },
111
- value: parsed_entity_value,
112
- indent: stmt.indent,
113
- line: stmt.line,
114
- column: stmt.column,
33
+ Value::String(s) => {
34
+ final_duration = Duration::Identifier(s);
115
35
  }
116
- } else {
117
- eprintln!("⚠️ Trigger variable '{}' not found", text);
118
- StatementResolved {
119
- kind: StatementKind::Trigger {
120
- entity: entity.clone(),
121
- duration: parsed_duration_value,
122
- },
123
- value: StatementResolvedValue::Unknown,
124
- indent: stmt.indent,
125
- line: stmt.line,
126
- column: stmt.column,
36
+ Value::Identifier(s) if s == "auto" => {
37
+ final_duration = Duration::Auto;
127
38
  }
39
+ _ => {}
128
40
  }
129
41
  }
130
- VariableValue::Map(map) => {
131
- let mut resolved_map = HashMap::new();
132
-
133
- // TODO Handle nested maps and arrays
42
+ }
134
43
 
135
- StatementResolved {
136
- kind: StatementKind::Trigger {
137
- entity: entity.clone(),
138
- duration: parsed_duration_value,
139
- },
140
- value: StatementResolvedValue::Map(resolved_map),
141
- indent: stmt.indent,
142
- line: stmt.line,
143
- column: stmt.column,
144
- }
44
+ // Params value resolution
45
+ final_value = match &stmt.value {
46
+ Value::Identifier(ident) => {
47
+ resolve_identifier(ident, module, global_store).unwrap_or_else(|| {
48
+ logger.log_error_with_stacktrace(
49
+ &format!("'{path}': value identifier '{ident}' not found"),
50
+ &format!("{}:{}:{}", module.path, stmt.line, stmt.column)
51
+ );
52
+ Value::Null
53
+ })
145
54
  }
146
- VariableValue::Null => {
147
- StatementResolved {
148
- kind: StatementKind::Trigger {
149
- entity: entity.clone(),
150
- duration: parsed_duration_value,
151
- },
152
- value: StatementResolvedValue::Map(HashMap::new()),
153
- indent: stmt.indent,
154
- line: stmt.line,
155
- column: stmt.column,
55
+ Value::Map(map) => {
56
+ let mut resolved_map = HashMap::new();
57
+ for (k, v) in map {
58
+ let resolved = match v {
59
+ Value::Identifier(id) => {
60
+ resolve_identifier(id, module, global_store).unwrap_or(Value::Null)
61
+ }
62
+ other => other.clone(),
63
+ };
64
+ resolved_map.insert(k.clone(), resolved);
156
65
  }
66
+ Value::Map(resolved_map)
157
67
  }
68
+ other => other.clone(),
69
+ };
158
70
 
159
- // TODO Parse other parameters
71
+ Statement {
72
+ kind: StatementKind::Trigger {
73
+ entity: entity.to_string(),
74
+ duration: final_duration,
75
+ },
76
+ value: final_value,
77
+ line: stmt.line,
78
+ column: stmt.column,
79
+ indent: stmt.indent,
80
+ }
81
+ }
82
+
83
+ fn resolve_identifier(ident: &str, module: &Module, global_store: &GlobalStore) -> Option<Value> {
84
+ if let Some(val) = module.variable_table.get(ident) {
85
+ return Some(resolve_value(val, module, global_store));
86
+ }
160
87
 
161
- _ => {
162
- eprintln!("⚠️ Invalid value type for Trigger statement: {:?}", stmt.value);
88
+ for (_, other_mod) in &global_store.modules {
89
+ if let Some(val) = other_mod.export_table.get_export(ident) {
90
+ return Some(resolve_value(val, other_mod, global_store));
91
+ }
92
+ }
93
+
94
+ None
95
+ }
163
96
 
164
- StatementResolved {
165
- kind: StatementKind::Trigger {
166
- entity: entity.clone(),
167
- duration: parsed_duration_value,
168
- },
169
- value: StatementResolvedValue::Unknown,
170
- indent: stmt.indent,
171
- line: stmt.line,
172
- column: stmt.column,
97
+ fn resolve_value(val: &Value, module: &Module, global_store: &GlobalStore) -> Value {
98
+ match val {
99
+ Value::Identifier(inner) =>
100
+ resolve_identifier(inner, module, global_store).unwrap_or(
101
+ Value::Identifier(inner.clone())
102
+ ),
103
+ Value::Map(map) => {
104
+ let mut resolved = HashMap::new();
105
+ for (k, v) in map {
106
+ resolved.insert(k.clone(), resolve_value(v, module, global_store));
173
107
  }
108
+ Value::Map(resolved)
174
109
  }
110
+ other => other.clone(),
175
111
  }
176
112
  }
@@ -0,0 +1,78 @@
1
+ use std::collections::HashMap;
2
+
3
+ use crate::{
4
+ core::{
5
+ parser::statement::{ Statement, StatementKind },
6
+ preprocessor::{ module::Module, resolver::driver::resolve_statement },
7
+ shared::value::Value,
8
+ store::{ global::GlobalStore, variable::VariableTable },
9
+ },
10
+ utils::logger::{ LogLevel, Logger },
11
+ };
12
+
13
+ fn find_export_value(name: &str, global_store: &GlobalStore) -> Option<Value> {
14
+ for (_path, module) in &global_store.modules {
15
+ if let Some(val) = module.export_table.get_export(name) {
16
+ return Some(val.clone());
17
+ }
18
+ }
19
+ None
20
+ }
21
+
22
+ pub fn resolve_value(value: &Value, module: &Module, global_store: &mut GlobalStore) -> Value {
23
+ match value {
24
+ Value::Identifier(name) => {
25
+ if let Some(original_val) = module.variable_table.get(name) {
26
+ return resolve_value(original_val, module, global_store);
27
+ }
28
+
29
+ if let Some(export_val) = find_export_value(name, global_store) {
30
+ return resolve_value(&export_val, module, global_store);
31
+ }
32
+
33
+ eprintln!("⚠️ Unresolved identifier '{}'", name);
34
+ Value::Null
35
+ }
36
+
37
+ Value::Map(map) => {
38
+ if let Some(Value::Identifier(entity)) = map.get("entity") {
39
+ // SECTION Synth
40
+ if entity == "synth" {
41
+ if let Some(Value::Map(synth_data)) = map.get("value") {
42
+ let resolved_waveform = synth_data
43
+ .get("waveform")
44
+ .map(|wf| resolve_value(wf, module, global_store))
45
+ .unwrap_or(Value::Null);
46
+
47
+ let resolved_params = synth_data
48
+ .get("parameters")
49
+ .map(|p| resolve_value(p, module, global_store))
50
+ .unwrap_or(Value::Map(HashMap::new()));
51
+
52
+ let mut result = HashMap::new();
53
+ result.insert("waveform".to_string(), resolved_waveform);
54
+ result.insert("parameters".to_string(), resolved_params);
55
+
56
+ return Value::Map(result);
57
+ }
58
+ }
59
+ }
60
+
61
+ let mut resolved = HashMap::new();
62
+ for (k, v) in map {
63
+ resolved.insert(k.clone(), resolve_value(v, module, global_store));
64
+ }
65
+ Value::Map(resolved)
66
+ }
67
+
68
+ Value::Block(stmts) => {
69
+ let resolved_stmts = stmts
70
+ .iter()
71
+ .map(|stmt| resolve_statement(stmt, module, &module.path, global_store))
72
+ .collect();
73
+ Value::Block(resolved_stmts)
74
+ }
75
+
76
+ other => other.clone(),
77
+ }
78
+ }
@@ -0,0 +1,8 @@
1
+ use serde::{ Deserialize, Serialize };
2
+
3
+ #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4
+ pub enum Duration {
5
+ Number(f32),
6
+ Identifier(String),
7
+ Auto,
8
+ }
@@ -0,0 +1,2 @@
1
+ pub mod value;
2
+ pub mod duration;
@@ -0,0 +1,28 @@
1
+ use std::collections::HashMap;
2
+ use serde::{ Deserialize, Serialize };
3
+
4
+ use crate::core::parser::statement::Statement;
5
+
6
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
7
+ pub enum Value {
8
+ Boolean(bool),
9
+ Number(f32),
10
+ Identifier(String),
11
+ String(String),
12
+ Array(Vec<Value>),
13
+ Map(HashMap<String, Value>),
14
+ Block(Vec<Statement>),
15
+ Sample(String),
16
+ Unknown,
17
+ Null,
18
+ }
19
+
20
+ impl Value {
21
+ pub fn get(&self, key: &str) -> Option<&Value> {
22
+ if let Value::Map(map) = self {
23
+ map.get(key)
24
+ } else {
25
+ None
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,28 @@
1
+ use std::collections::HashMap;
2
+
3
+ use crate::core::shared::value::Value;
4
+
5
+ #[derive(Debug, Default, Clone, PartialEq)]
6
+ pub struct ExportTable {
7
+ pub exports: HashMap<String, Value>,
8
+ }
9
+
10
+ impl ExportTable {
11
+ pub fn new() -> Self {
12
+ ExportTable {
13
+ exports: HashMap::new(),
14
+ }
15
+ }
16
+
17
+ pub fn add_export(&mut self, name: String, value: Value) {
18
+ self.exports.insert(name, value);
19
+ }
20
+
21
+ pub fn get_export(&self, name: &str) -> Option<&Value> {
22
+ self.exports.get(name)
23
+ }
24
+
25
+ pub fn remove_export(&mut self, name: &str) -> Option<Value> {
26
+ self.exports.remove(name)
27
+ }
28
+ }
@@ -0,0 +1,39 @@
1
+ use std::collections::HashMap;
2
+ use crate::core::preprocessor::module::Module;
3
+
4
+ #[derive(Debug, Default, Clone)]
5
+ pub struct GlobalStore {
6
+ pub modules: HashMap<String, Module>,
7
+ }
8
+
9
+ impl GlobalStore {
10
+ pub fn new() -> Self {
11
+ GlobalStore {
12
+ modules: HashMap::new(),
13
+ }
14
+ }
15
+
16
+ pub fn resolve_all_imports(&mut self) {
17
+ for module in self.modules.values_mut() {
18
+ for (name, source_path) in &module.import_table.imports {
19
+ println!("Resolving import: {} from {:?}", name, source_path);
20
+ }
21
+ }
22
+ }
23
+
24
+ pub fn insert_module(&mut self, path: String, module: Module) {
25
+ self.modules.insert(path, module);
26
+ }
27
+
28
+ pub fn modules_mut(&mut self) -> &mut HashMap<String, Module> {
29
+ &mut self.modules
30
+ }
31
+
32
+ pub fn get_module(&self, path: &str) -> Option<&Module> {
33
+ self.modules.get(path)
34
+ }
35
+
36
+ pub fn remove_module(&mut self, path: &str) -> Option<Module> {
37
+ self.modules.remove(path)
38
+ }
39
+ }
@@ -0,0 +1,28 @@
1
+ use std::collections::HashMap;
2
+
3
+ use crate::core::shared::value::Value;
4
+
5
+ #[derive(Debug, Default, Clone, PartialEq)]
6
+ pub struct ImportTable {
7
+ pub imports: HashMap<String, Value>,
8
+ }
9
+
10
+ impl ImportTable {
11
+ pub fn new() -> Self {
12
+ ImportTable {
13
+ imports: HashMap::new(),
14
+ }
15
+ }
16
+
17
+ pub fn add_import(&mut self, name: String, value: Value) {
18
+ self.imports.insert(name, value);
19
+ }
20
+
21
+ pub fn get_import(&self, name: &str) -> Option<&Value> {
22
+ self.imports.get(name)
23
+ }
24
+
25
+ pub fn remove_import(&mut self, name: &str) -> Option<Value> {
26
+ self.imports.remove(name)
27
+ }
28
+ }
@@ -0,0 +1,4 @@
1
+ pub mod global;
2
+ pub mod export;
3
+ pub mod import;
4
+ pub mod variable;