@devaloop/devalang 0.0.1-alpha.1 → 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 (105) hide show
  1. package/.devalang +4 -0
  2. package/Cargo.toml +46 -45
  3. package/README.md +35 -10
  4. package/docs/CHANGELOG.md +58 -0
  5. package/docs/COMMANDS.md +29 -6
  6. package/docs/CONFIG.md +28 -0
  7. package/docs/ROADMAP.md +6 -2
  8. package/docs/TODO.md +21 -18
  9. package/examples/exported.deva +1 -1
  10. package/examples/index.deva +2 -1
  11. package/out-tsc/bin/devalang.exe +0 -0
  12. package/package.json +2 -3
  13. package/project-version.json +4 -4
  14. package/rust/cli/build.rs +99 -29
  15. package/rust/cli/check.rs +95 -103
  16. package/rust/cli/init.rs +77 -0
  17. package/rust/cli/mod.rs +174 -1
  18. package/rust/cli/template.rs +56 -0
  19. package/rust/config/loader.rs +14 -0
  20. package/rust/config/mod.rs +15 -0
  21. package/rust/core/builder/mod.rs +21 -27
  22. package/rust/core/debugger/lexer.rs +12 -0
  23. package/rust/core/debugger/mod.rs +12 -49
  24. package/rust/core/debugger/preprocessor.rs +23 -0
  25. package/rust/core/error/mod.rs +60 -0
  26. package/rust/core/lexer/handler/at.rs +21 -0
  27. package/rust/core/lexer/handler/brace.rs +41 -0
  28. package/rust/core/lexer/handler/colon.rs +21 -0
  29. package/rust/core/lexer/handler/comment.rs +30 -0
  30. package/rust/core/lexer/handler/dot.rs +21 -0
  31. package/rust/core/lexer/handler/equal.rs +32 -0
  32. package/rust/core/lexer/handler/identifier.rs +38 -0
  33. package/rust/core/lexer/handler/indent.rs +52 -0
  34. package/rust/core/lexer/handler/mod.rs +238 -0
  35. package/rust/core/lexer/handler/newline.rs +19 -0
  36. package/rust/core/lexer/handler/number.rs +31 -0
  37. package/rust/core/lexer/handler/string.rs +66 -0
  38. package/rust/core/lexer/mod.rs +16 -324
  39. package/rust/core/lexer/token.rs +55 -0
  40. package/rust/core/mod.rs +5 -2
  41. package/rust/core/parser/handler/at.rs +166 -0
  42. package/rust/core/parser/handler/bank.rs +38 -0
  43. package/rust/core/parser/handler/dot.rs +112 -0
  44. package/rust/core/parser/handler/identifier.rs +134 -0
  45. package/rust/core/parser/handler/loop_.rs +55 -0
  46. package/rust/core/parser/handler/mod.rs +6 -0
  47. package/rust/core/parser/handler/tempo.rs +47 -0
  48. package/rust/core/parser/mod.rs +204 -166
  49. package/rust/core/parser/statement.rs +91 -0
  50. package/rust/core/preprocessor/loader.rs +105 -0
  51. package/rust/core/preprocessor/mod.rs +2 -24
  52. package/rust/core/preprocessor/module.rs +37 -56
  53. package/rust/core/preprocessor/processor.rs +41 -0
  54. package/rust/core/preprocessor/resolver.rs +372 -0
  55. package/rust/core/shared/duration.rs +8 -0
  56. package/rust/core/shared/mod.rs +2 -0
  57. package/rust/core/shared/value.rs +18 -0
  58. package/rust/core/store/export.rs +28 -0
  59. package/rust/core/store/global.rs +39 -0
  60. package/rust/core/store/import.rs +28 -0
  61. package/rust/core/store/mod.rs +4 -0
  62. package/rust/core/store/variable.rs +28 -0
  63. package/rust/core/utils/mod.rs +2 -0
  64. package/rust/core/utils/validation.rs +35 -0
  65. package/rust/lib.rs +0 -1
  66. package/rust/main.rs +39 -30
  67. package/rust/utils/file.rs +35 -0
  68. package/rust/utils/logger.rs +69 -34
  69. package/rust/utils/mod.rs +3 -2
  70. package/rust/utils/watcher.rs +25 -0
  71. package/templates/minimal/.devalang +4 -0
  72. package/templates/minimal/src/index.deva +2 -0
  73. package/templates/welcome/.devalang +4 -0
  74. package/templates/welcome/README.md +185 -0
  75. package/templates/welcome/samples/kick-808.wav +0 -0
  76. package/templates/welcome/src/index.deva +13 -0
  77. package/templates/welcome/src/variables.deva +5 -0
  78. package/rust/audio/mod.rs +0 -1
  79. package/rust/cli/new.rs +0 -1
  80. package/rust/core/parser/at.rs +0 -142
  81. package/rust/core/parser/bank.rs +0 -42
  82. package/rust/core/parser/dot.rs +0 -107
  83. package/rust/core/parser/identifer.rs +0 -91
  84. package/rust/core/parser/loop_.rs +0 -62
  85. package/rust/core/parser/tempo.rs +0 -42
  86. package/rust/core/parser/variable.rs +0 -129
  87. package/rust/core/preprocessor/dependencies.rs +0 -54
  88. package/rust/core/preprocessor/resolver/at.rs +0 -24
  89. package/rust/core/preprocessor/resolver/bank.rs +0 -59
  90. package/rust/core/preprocessor/resolver/loop_.rs +0 -82
  91. package/rust/core/preprocessor/resolver/mod.rs +0 -113
  92. package/rust/core/preprocessor/resolver/tempo.rs +0 -70
  93. package/rust/core/preprocessor/resolver/trigger.rs +0 -176
  94. package/rust/core/types/cli.rs +0 -160
  95. package/rust/core/types/mod.rs +0 -7
  96. package/rust/core/types/module.rs +0 -41
  97. package/rust/core/types/parser.rs +0 -73
  98. package/rust/core/types/statement.rs +0 -105
  99. package/rust/core/types/store.rs +0 -116
  100. package/rust/core/types/token.rs +0 -83
  101. package/rust/core/types/variable.rs +0 -32
  102. package/rust/runner/executer.rs +0 -44
  103. package/rust/runner/mod.rs +0 -1
  104. /package/rust/{utils → core/utils}/path.rs +0 -0
  105. /package/rust/utils/{loader.rs → spinner.rs} +0 -0
@@ -1,70 +1,51 @@
1
1
  use crate::core::{
2
- lexer::lex,
3
- parser::{ parse_without_resolving },
4
- preprocessor::{
5
- collect_dependencies_recursively,
6
- resolver::{ resolve_exports, resolve_imports },
2
+ lexer::token::Token,
3
+ parser::statement::Statement,
4
+ store::{
5
+ export::ExportTable,
6
+ global::GlobalStore,
7
+ import::ImportTable,
8
+ variable::VariableTable,
7
9
  },
8
- types::{ module::Module, parser::Parser, store::{ ExportTable, GlobalStore, ImportTable } },
9
10
  };
10
11
 
11
- pub fn load_all_modules(entry_file: &str) -> GlobalStore {
12
- let mut global_store = GlobalStore::default();
13
- let files = collect_dependencies_recursively(entry_file);
12
+ #[derive(Debug, Clone)]
13
+ pub struct Module {
14
+ pub path: String,
15
+ pub resolved: bool,
16
+ pub tokens: Vec<Token>,
17
+ pub statements: Vec<Statement>,
18
+ pub variable_table: VariableTable,
19
+ pub export_table: ExportTable,
20
+ pub import_table: ImportTable,
21
+ }
14
22
 
15
- for file in &files {
16
- if let Err(e) = load_module_into_global_store(file, &mut global_store) {
17
- eprintln!("❌ Error loading {}: {}", file, e);
23
+ impl Module {
24
+ pub fn new(path: &str) -> Self {
25
+ Module {
26
+ path: path.to_string(),
27
+ tokens: Vec::new(),
28
+ statements: Vec::new(),
29
+ variable_table: VariableTable::new(),
30
+ export_table: ExportTable::new(),
31
+ import_table: ImportTable::new(),
32
+ resolved: false,
18
33
  }
19
34
  }
20
35
 
21
- for file in &files {
22
- if let Some(module) = global_store.modules.clone().get_mut(file) {
23
- let imports = resolve_imports(module, &mut global_store);
24
- module.import_table = imports.clone();
25
-
26
- let global_store_module = global_store.modules.get(&file.clone().to_string());
27
- if let Some(global_store_module_found) = global_store_module {
28
- global_store.insert_module(file.to_string(), module.clone());
29
- } else {
30
- eprintln!("❌ Module {} not found in global store after import resolution", file);
31
- }
32
- }
36
+ pub fn is_resolved(&self) -> bool {
37
+ self.resolved
33
38
  }
34
39
 
35
- global_store
36
- }
37
-
38
- pub fn load_module_into_global_store(
39
- path: &str,
40
- global_store: &mut GlobalStore
41
- ) -> Result<(), String> {
42
- if global_store.modules.contains_key(path) {
43
- return Ok(());
40
+ pub fn set_resolved(&mut self, resolved: bool) {
41
+ self.resolved = resolved;
44
42
  }
45
43
 
46
- let content = std::fs::read_to_string(path).map_err(|_| format!("Cannot read file: {}", path))?;
47
-
48
- let tokens = lex(content);
49
-
50
- let mut parser = Parser::new(tokens.clone());
51
-
52
- parser.current_module = path.to_string();
53
-
54
- let raw_statements = parse_without_resolving(tokens.clone(), &mut parser, global_store);
55
-
56
- let export_table = resolve_exports(&raw_statements, &mut parser);
57
-
58
- let mut module = Module {
59
- path: path.to_string(),
60
- tokens: tokens.clone(),
61
- statements: raw_statements,
62
- variable_table: parser.variable_table.clone(),
63
- export_table: export_table.clone(),
64
- import_table: parser.import_table.clone(),
65
- };
66
-
67
- global_store.insert_module(path.to_string(), module.clone());
44
+ pub fn add_token(&mut self, token: Token) {
45
+ self.tokens.push(token);
46
+ }
68
47
 
69
- Ok(())
48
+ pub fn add_statement(&mut self, statement: Statement) {
49
+ self.statements.push(statement);
50
+ }
70
51
  }
@@ -0,0 +1,41 @@
1
+ use crate::core::{
2
+ parser::{ statement::StatementKind, Parser },
3
+ preprocessor::loader::ModuleLoader,
4
+ shared::value::Value,
5
+ store::global::GlobalStore,
6
+ };
7
+
8
+ pub fn process_modules(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
9
+ for module in global_store.modules.values_mut() {
10
+ for stmt in &module.statements {
11
+ match &stmt.kind {
12
+ StatementKind::Let { name } => {
13
+ module.variable_table.variables.insert(name.clone(), stmt.value.clone());
14
+ }
15
+
16
+ StatementKind::Load { source, alias } => {
17
+ module.variable_table.variables.insert(
18
+ alias.clone(),
19
+ Value::Sample(source.clone())
20
+ );
21
+ }
22
+
23
+ StatementKind::Export { names, source } => {
24
+ for name in names {
25
+ if let Some(val) = module.variable_table.get(name) {
26
+ module.export_table.add_export(name.clone(), val.clone());
27
+ }
28
+ }
29
+ }
30
+
31
+ StatementKind::Import { names, source } => {
32
+ for name in names {
33
+ module.import_table.add_import(name.clone(), Value::String(source.clone()));
34
+ }
35
+ }
36
+
37
+ _ => {}
38
+ }
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,372 @@
1
+ use std::collections::HashMap;
2
+
3
+ use crate::{
4
+ core::{
5
+ parser::statement::{ self, Statement, StatementKind },
6
+ preprocessor::loader::ModuleLoader,
7
+ shared::{ duration::Duration, value::Value },
8
+ store::global::GlobalStore,
9
+ utils::validation::{ is_valid_entity, is_valid_identifier },
10
+ },
11
+ utils::logger::Logger,
12
+ };
13
+
14
+ pub fn resolve_all_modules(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
15
+ for module in global_store.clone().modules.values_mut() {
16
+ resolve_imports(module_loader, global_store);
17
+ }
18
+ }
19
+
20
+ pub fn resolve_imports(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
21
+ for (module_path, module) in global_store.clone().modules.iter_mut() {
22
+ for (name, source_path) in &module.import_table.imports {
23
+ match source_path {
24
+ Value::String(source_path) => {
25
+ if let Some(source_module) = global_store.modules.get(source_path) {
26
+ if let Some(value) = source_module.export_table.get_export(name) {
27
+ module.variable_table.set(name.clone(), value.clone());
28
+ } else {
29
+ println!(
30
+ "[warn] '{module_path}': '{name}' not found in exports of '{source_path}'"
31
+ );
32
+ }
33
+ } else {
34
+ println!(
35
+ "[warn] '{module_path}': cannot find source module '{source_path}'"
36
+ );
37
+ }
38
+ }
39
+ _ => {
40
+ println!(
41
+ "[warn] '{module_path}': expected string for import source, found {:?}",
42
+ source_path
43
+ );
44
+ }
45
+ }
46
+ }
47
+ }
48
+ }
49
+
50
+ pub fn resolve_and_flatten_all_modules(
51
+ global_store: &mut GlobalStore
52
+ ) -> HashMap<String, Vec<Statement>> {
53
+ let logger = Logger::new();
54
+
55
+ // 1. Imports resolving
56
+ let global_store_clone = global_store.clone();
57
+ for (module_path, module) in global_store.modules.iter_mut() {
58
+ for (name, source_path) in &module.import_table.imports {
59
+ match source_path {
60
+ Value::String(source_path) => {
61
+ if let Some(source_module) = global_store_clone.modules.get(source_path) {
62
+ if let Some(value) = source_module.export_table.get_export(name) {
63
+ module.variable_table.set(name.clone(), value.clone());
64
+ } else {
65
+ let message = format!(
66
+ "'{name}' not found in exports of '{source_path}'"
67
+ );
68
+ logger.log_error_with_stacktrace(&message, module_path);
69
+ }
70
+ } else {
71
+ let message = format!("cannot find source module '{source_path}'");
72
+ logger.log_error_with_stacktrace(&message, module_path);
73
+ }
74
+ }
75
+ _ => {
76
+ let message = format!(
77
+ "expected string for import source, found {:?}",
78
+ source_path
79
+ );
80
+ logger.log_error_with_stacktrace(&message, module_path);
81
+ }
82
+ }
83
+ }
84
+ }
85
+
86
+ // 2. Full statement resolution
87
+ let mut resolved_map = HashMap::new();
88
+
89
+ for (path, module) in &global_store.modules {
90
+ let mut resolved = Vec::new();
91
+
92
+ for mut stmt in module.statements.clone() {
93
+ match &mut stmt.kind {
94
+ StatementKind::Bank => {
95
+ if let Value::Identifier(ident) = &stmt.value {
96
+ if let Some(val) = module.variable_table.get(ident) {
97
+ stmt.value = val.clone();
98
+ } else {
99
+ let message = format!(
100
+ "Bank identifier '{ident}' not found in variable table"
101
+ );
102
+
103
+ logger.log_error_with_stacktrace(&message, &module.path);
104
+
105
+ stmt.kind = StatementKind::Error {
106
+ message: format!(
107
+ "Bank identifier '{ident}' not found in variable table"
108
+ ),
109
+ };
110
+ stmt.value = Value::Null;
111
+ }
112
+ } else if let Value::String(_) = &stmt.value {
113
+ // Value is already a string, no need to modify
114
+ } else {
115
+ let message = format!(
116
+ "Expected a string or identifier for bank, found {:?}",
117
+ stmt.value
118
+ );
119
+
120
+ logger.log_error_with_stacktrace(&message, &module.path);
121
+
122
+ stmt.kind = StatementKind::Error {
123
+ message: "Expected a string or identifier for bank".to_string(),
124
+ };
125
+ stmt.value = Value::Null;
126
+ }
127
+ }
128
+
129
+ StatementKind::Tempo => {
130
+ if let Value::Identifier(ident) = &stmt.value {
131
+ if let Some(val) = module.variable_table.get(ident) {
132
+ stmt.value = val.clone();
133
+ } else {
134
+ let message = format!(
135
+ "Tempo identifier '{ident}' not found in variable table"
136
+ );
137
+
138
+ logger.log_error_with_stacktrace(&message, &module.path);
139
+
140
+ stmt.kind = StatementKind::Error {
141
+ message: format!(
142
+ "Tempo identifier '{ident}' not found in variable table"
143
+ ),
144
+ };
145
+ stmt.value = Value::Null;
146
+ }
147
+ } else if let Value::Number(_) = &stmt.value {
148
+ // Value is already a number, no need to modify
149
+ } else {
150
+ let message = format!(
151
+ "Expected a number or identifier for tempo, found {:?}",
152
+ stmt.value
153
+ );
154
+
155
+ logger.log_error_with_stacktrace(&message, &module.path);
156
+
157
+ stmt.kind = StatementKind::Error {
158
+ message: "Expected a number or identifier for tempo".to_string(),
159
+ };
160
+ stmt.value = Value::Null;
161
+ }
162
+ }
163
+
164
+ StatementKind::Trigger { entity, duration } => {
165
+ if !is_valid_entity(entity, module, global_store) {
166
+ let message =
167
+ format!("Invalid entity '{}', expected a valid identifier", entity);
168
+
169
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
170
+ logger.log_error_with_stacktrace(&message, &stacktrace);
171
+
172
+ stmt.kind = StatementKind::Error {
173
+ message: format!("Invalid entity '{}'", entity),
174
+ };
175
+ stmt.value = Value::Null;
176
+
177
+ resolved.push(stmt);
178
+ continue;
179
+ }
180
+
181
+ // Duration resolution
182
+ if let Duration::Identifier(ident) = duration {
183
+ if let Some(val) = module.variable_table.get(ident) {
184
+ match val {
185
+ Value::Number(num) => {
186
+ *duration = Duration::Number(*num);
187
+ }
188
+ Value::String(s) => {
189
+ *duration = Duration::Identifier(s.clone());
190
+ }
191
+ Value::Identifier(id) if id == "auto" => {
192
+ *duration = Duration::Auto;
193
+ }
194
+ _ => {}
195
+ }
196
+ }
197
+ }
198
+
199
+ // Associated value resolution
200
+ if let Value::Identifier(ident) = &stmt.value {
201
+ if let Some(val) = module.variable_table.get(ident) {
202
+ stmt.value = val.clone();
203
+ } else {
204
+ let stacktrace = format!(
205
+ "{}:{}:{}",
206
+ module.path,
207
+ stmt.line,
208
+ stmt.column
209
+ );
210
+ let message = format!(
211
+ "'{path}': value identifier '{ident}' not found in variable table"
212
+ );
213
+
214
+ logger.log_error_with_stacktrace(&message, &stacktrace);
215
+
216
+ stmt.kind = StatementKind::Error {
217
+ message: format!(
218
+ "Value identifier '{ident}' not found in variable table"
219
+ ),
220
+ };
221
+ stmt.value = Value::Null;
222
+ }
223
+ }
224
+ }
225
+
226
+ StatementKind::Let { .. } => {
227
+ if let Value::Identifier(ident) = &stmt.value {
228
+ if let Some(val) = module.variable_table.get(ident) {
229
+ stmt.value = val.clone();
230
+ } else {
231
+ if !is_valid_identifier(ident, module) {
232
+ let message = format!(
233
+ "'{path}': value identifier '{ident}' not found in variable table"
234
+ );
235
+
236
+ logger.log_error_with_stacktrace(&message, &module.path);
237
+
238
+ stmt.kind = StatementKind::Error {
239
+ message: format!(
240
+ "Value identifier '{ident}' not found in variable table"
241
+ ),
242
+ };
243
+ stmt.value = Value::Null;
244
+ } else {
245
+ stmt.value = Value::Identifier(ident.clone());
246
+ }
247
+ }
248
+ }
249
+ }
250
+
251
+ StatementKind::Loop => {
252
+ if let Value::Map(value_map) = &stmt.value {
253
+ let iterator_value = match value_map.get("iterator") {
254
+ Some(Value::Identifier(ident)) => {
255
+ if let Some(val) = module.variable_table.get(ident) {
256
+ match val {
257
+ Value::Number(n) => Value::Number(*n),
258
+ _ => {
259
+ let message = format!(
260
+ "Loop iterator '{ident}' must resolve to a number"
261
+ );
262
+ let stacktrace = format!(
263
+ "{}:{}:{}",
264
+ module.path,
265
+ stmt.line,
266
+ stmt.column
267
+ );
268
+ logger.log_error_with_stacktrace(&message, &stacktrace);
269
+
270
+ stmt.kind = StatementKind::Error {
271
+ message,
272
+ };
273
+ Value::Null
274
+ }
275
+ }
276
+ } else {
277
+ let message = format!(
278
+ "'{path}': loop iterator '{ident}' not found in variable table"
279
+ );
280
+ let stacktrace = format!(
281
+ "{}:{}:{}",
282
+ module.path,
283
+ stmt.line,
284
+ stmt.column
285
+ );
286
+ logger.log_error_with_stacktrace(&message, &stacktrace);
287
+
288
+ stmt.kind = StatementKind::Error {
289
+ message: format!("Loop iterator '{ident}' not found"),
290
+ };
291
+ Value::Null
292
+ }
293
+ }
294
+
295
+ Some(Value::Number(n)) => Value::Number(*n),
296
+
297
+ Some(v) => {
298
+ let message = format!(
299
+ "Unexpected value for loop iterator: {:?}, expected number or identifier",
300
+ v
301
+ );
302
+ let stacktrace = format!(
303
+ "{}:{}:{}",
304
+ module.path,
305
+ stmt.line,
306
+ stmt.column
307
+ );
308
+ logger.log_error_with_stacktrace(&message, &stacktrace);
309
+
310
+ stmt.kind = StatementKind::Error {
311
+ message,
312
+ };
313
+ Value::Null
314
+ }
315
+
316
+ None => {
317
+ let message = format!(
318
+ "Missing 'iterator' key in loop statement map"
319
+ );
320
+ let stacktrace = format!(
321
+ "{}:{}:{}",
322
+ module.path,
323
+ stmt.line,
324
+ stmt.column
325
+ );
326
+ logger.log_error_with_stacktrace(&message, &stacktrace);
327
+
328
+ stmt.kind = StatementKind::Error {
329
+ message,
330
+ };
331
+ Value::Null
332
+ }
333
+ };
334
+
335
+ let body_value = value_map.get("body").cloned().unwrap_or(Value::Null);
336
+
337
+ let mut loop_map = std::collections::HashMap::new();
338
+ loop_map.insert("iterator".to_string(), iterator_value);
339
+ loop_map.insert("body".to_string(), body_value);
340
+
341
+ stmt.value = Value::Map(loop_map);
342
+ } else {
343
+ let message = format!(
344
+ "'{path}': expected a map for loop value, found {:?}",
345
+ stmt.value
346
+ );
347
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
348
+
349
+ logger.log_error_with_stacktrace(&message, &stacktrace);
350
+
351
+ stmt.kind = StatementKind::Error {
352
+ message: "Expected a map for loop value".to_string(),
353
+ };
354
+ stmt.value = Value::Null;
355
+ }
356
+ }
357
+
358
+ StatementKind::Import { names, source } => {}
359
+
360
+ StatementKind::Export { names, source } => {}
361
+
362
+ _ => {}
363
+ }
364
+
365
+ resolved.push(stmt);
366
+ }
367
+
368
+ resolved_map.insert(path.clone(), resolved);
369
+ }
370
+
371
+ resolved_map
372
+ }
@@ -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,18 @@
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
+ }
@@ -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;
@@ -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 VariableTable {
7
+ pub variables: HashMap<String, Value>,
8
+ }
9
+
10
+ impl VariableTable {
11
+ pub fn new() -> Self {
12
+ VariableTable {
13
+ variables: HashMap::new(),
14
+ }
15
+ }
16
+
17
+ pub fn set(&mut self, name: String, value: Value) {
18
+ self.variables.insert(name, value);
19
+ }
20
+
21
+ pub fn get(&self, name: &str) -> Option<&Value> {
22
+ self.variables.get(name)
23
+ }
24
+
25
+ pub fn remove(&mut self, name: &str) -> Option<Value> {
26
+ self.variables.remove(name)
27
+ }
28
+ }