@devaloop/devalang 0.0.1-alpha.12 → 0.0.1-alpha.14

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 (93) hide show
  1. package/.devalang +8 -9
  2. package/Cargo.toml +8 -3
  3. package/README.md +36 -34
  4. package/docs/CHANGELOG.md +65 -1
  5. package/docs/CONTRIBUTING.md +1 -0
  6. package/docs/ROADMAP.md +2 -2
  7. package/docs/TODO.md +6 -5
  8. package/examples/bank.deva +2 -4
  9. package/examples/function.deva +15 -0
  10. package/examples/index.deva +25 -14
  11. package/out-tsc/bin/devalang.exe +0 -0
  12. package/package.json +6 -6
  13. package/project-version.json +3 -3
  14. package/rust/cli/bank.rs +2 -1
  15. package/rust/cli/build.rs +76 -14
  16. package/rust/cli/check.rs +71 -8
  17. package/rust/cli/driver.rs +40 -28
  18. package/rust/cli/install.rs +22 -7
  19. package/rust/cli/login.rs +134 -0
  20. package/rust/cli/mod.rs +2 -1
  21. package/rust/cli/play.rs +45 -20
  22. package/rust/common/api.rs +8 -0
  23. package/rust/common/cdn.rs +2 -5
  24. package/rust/common/mod.rs +3 -1
  25. package/rust/common/sso.rs +8 -0
  26. package/rust/config/driver.rs +19 -1
  27. package/rust/config/loader.rs +56 -10
  28. package/rust/core/audio/engine.rs +254 -91
  29. package/rust/core/audio/interpreter/arrow_call.rs +34 -15
  30. package/rust/core/audio/interpreter/call.rs +72 -47
  31. package/rust/core/audio/interpreter/condition.rs +14 -12
  32. package/rust/core/audio/interpreter/driver.rs +90 -128
  33. package/rust/core/audio/interpreter/function.rs +21 -0
  34. package/rust/core/audio/interpreter/load.rs +1 -1
  35. package/rust/core/audio/interpreter/loop_.rs +24 -18
  36. package/rust/core/audio/interpreter/mod.rs +2 -1
  37. package/rust/core/audio/interpreter/sleep.rs +0 -6
  38. package/rust/core/audio/interpreter/spawn.rs +78 -60
  39. package/rust/core/audio/interpreter/trigger.rs +157 -70
  40. package/rust/core/audio/loader/trigger.rs +37 -4
  41. package/rust/core/audio/player.rs +20 -10
  42. package/rust/core/audio/renderer.rs +24 -25
  43. package/rust/core/builder/mod.rs +11 -6
  44. package/rust/core/debugger/mod.rs +2 -0
  45. package/rust/core/debugger/module.rs +47 -0
  46. package/rust/core/debugger/store.rs +25 -11
  47. package/rust/core/error/mod.rs +6 -0
  48. package/rust/core/lexer/handler/driver.rs +23 -1
  49. package/rust/core/lexer/handler/identifier.rs +1 -0
  50. package/rust/core/lexer/handler/indent.rs +16 -2
  51. package/rust/core/lexer/handler/mod.rs +1 -0
  52. package/rust/core/lexer/handler/parenthesis.rs +41 -0
  53. package/rust/core/lexer/token.rs +4 -0
  54. package/rust/core/mod.rs +2 -1
  55. package/rust/core/parser/driver.rs +47 -4
  56. package/rust/core/parser/handler/arrow_call.rs +78 -18
  57. package/rust/core/parser/handler/bank.rs +35 -7
  58. package/rust/core/parser/handler/dot.rs +81 -123
  59. package/rust/core/parser/handler/identifier/call.rs +69 -22
  60. package/rust/core/parser/handler/identifier/function.rs +92 -0
  61. package/rust/core/parser/handler/identifier/let_.rs +13 -19
  62. package/rust/core/parser/handler/identifier/mod.rs +1 -0
  63. package/rust/core/parser/handler/identifier/spawn.rs +74 -27
  64. package/rust/core/parser/statement.rs +16 -4
  65. package/rust/core/plugin/loader.rs +48 -0
  66. package/rust/core/plugin/mod.rs +1 -0
  67. package/rust/core/preprocessor/loader.rs +50 -32
  68. package/rust/core/preprocessor/module.rs +3 -1
  69. package/rust/core/preprocessor/processor.rs +26 -1
  70. package/rust/core/preprocessor/resolver/call.rs +61 -84
  71. package/rust/core/preprocessor/resolver/condition.rs +11 -6
  72. package/rust/core/preprocessor/resolver/driver.rs +52 -6
  73. package/rust/core/preprocessor/resolver/function.rs +78 -0
  74. package/rust/core/preprocessor/resolver/group.rs +43 -13
  75. package/rust/core/preprocessor/resolver/let_.rs +7 -10
  76. package/rust/core/preprocessor/resolver/mod.rs +2 -1
  77. package/rust/core/preprocessor/resolver/spawn.rs +64 -30
  78. package/rust/core/preprocessor/resolver/trigger.rs +7 -3
  79. package/rust/core/preprocessor/resolver/value.rs +10 -1
  80. package/rust/core/shared/value.rs +4 -1
  81. package/rust/core/store/function.rs +34 -0
  82. package/rust/core/store/global.rs +9 -10
  83. package/rust/core/store/mod.rs +2 -1
  84. package/rust/core/store/variable.rs +6 -0
  85. package/rust/installer/addon.rs +80 -0
  86. package/rust/installer/bank.rs +24 -14
  87. package/rust/installer/mod.rs +4 -1
  88. package/rust/installer/plugin.rs +55 -0
  89. package/rust/lib.rs +10 -7
  90. package/rust/main.rs +32 -9
  91. package/rust/utils/logger.rs +16 -0
  92. package/rust/utils/mod.rs +45 -1
  93. package/rust/utils/spinner.rs +2 -4
@@ -9,6 +9,7 @@ use crate::{
9
9
  bank::resolve_bank,
10
10
  call::resolve_call,
11
11
  condition::resolve_condition,
12
+ function::resolve_function,
12
13
  group::resolve_group,
13
14
  let_::resolve_let,
14
15
  loop_::resolve_loop,
@@ -36,12 +37,22 @@ pub fn resolve_statement(
36
37
  global_store: &mut GlobalStore
37
38
  ) -> Statement {
38
39
  match &stmt.kind {
39
- StatementKind::Trigger { entity, duration } =>
40
- resolve_trigger(stmt, entity, &mut duration.clone(), module, path, global_store),
40
+ StatementKind::Trigger { entity, duration, effects } =>
41
+ resolve_trigger(
42
+ stmt,
43
+ entity,
44
+ &mut duration.clone(),
45
+ effects.clone(),
46
+ module,
47
+ path,
48
+ global_store
49
+ ),
41
50
  StatementKind::If => resolve_condition(stmt, module, path, global_store),
42
51
  StatementKind::Group => resolve_group(stmt, module, path, global_store),
43
- StatementKind::Call => resolve_call(stmt, module, path, global_store),
44
- StatementKind::Spawn => resolve_spawn(stmt, module, path, global_store),
52
+ StatementKind::Call { name, args } =>
53
+ resolve_call(stmt, name.clone(), args.clone(), module, path, global_store),
54
+ StatementKind::Spawn { name, args } =>
55
+ resolve_spawn(stmt, name.clone(), args.clone(), module, path, global_store),
45
56
  StatementKind::Bank => resolve_bank(stmt, module, path, global_store),
46
57
  StatementKind::Tempo => resolve_tempo(stmt, module, path, global_store),
47
58
  StatementKind::Loop => resolve_loop(stmt, module, path, global_store),
@@ -180,14 +191,20 @@ pub fn resolve_and_flatten_all_modules(
180
191
  let mut resolved = Vec::new();
181
192
 
182
193
  for stmt in &module.statements {
183
- let mut stmt = stmt.clone();
194
+ let stmt = stmt.clone();
184
195
 
185
196
  match &stmt.kind {
186
- StatementKind::Trigger { entity, duration } => {
197
+ StatementKind::Let { name } => {
198
+ let resolved_stmt = resolve_let(&stmt, name, &module, &path, global_store);
199
+ resolved.push(resolved_stmt);
200
+ }
201
+
202
+ StatementKind::Trigger { entity, duration, effects } => {
187
203
  let resolved_stmt = resolve_trigger(
188
204
  &stmt,
189
205
  entity.as_str(),
190
206
  &mut duration.clone(),
207
+ effects.clone(),
191
208
  &module,
192
209
  &path,
193
210
  global_store
@@ -214,11 +231,40 @@ pub fn resolve_and_flatten_all_modules(
214
231
  resolved.push(stmt.clone());
215
232
  }
216
233
 
234
+ StatementKind::Call { name, args } => {
235
+ let resolved_stmt = resolve_call(
236
+ &stmt,
237
+ name.clone(),
238
+ args.clone(),
239
+ &module,
240
+ &path,
241
+ global_store
242
+ );
243
+ resolved.push(resolved_stmt);
244
+ }
245
+
246
+ StatementKind::Spawn { name, args } => {
247
+ let resolved_stmt = resolve_spawn(
248
+ &stmt,
249
+ name.clone(),
250
+ args.clone(),
251
+ &module,
252
+ &path,
253
+ global_store
254
+ );
255
+ resolved.push(resolved_stmt);
256
+ }
257
+
217
258
  StatementKind::Group => {
218
259
  let resolved_stmt = resolve_group(&stmt, &module, &path, global_store);
219
260
  resolved.push(resolved_stmt);
220
261
  }
221
262
 
263
+ StatementKind::Function { name, parameters, body } => {
264
+ let resolved_function = resolve_function(&stmt, &module, &path, global_store);
265
+ resolved.push(resolved_function);
266
+ }
267
+
222
268
  _ => {
223
269
  resolved.push(stmt);
224
270
  }
@@ -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::{ function::FunctionDef, global::GlobalStore, variable::VariableTable },
9
+ },
10
+ utils::logger::{ LogLevel, Logger },
11
+ };
12
+
13
+ pub fn resolve_function(
14
+ stmt: &Statement,
15
+ module: &Module,
16
+ path: &str,
17
+ global_store: &mut GlobalStore
18
+ ) -> Statement {
19
+ if let StatementKind::Function { name, parameters, body } = &stmt.kind {
20
+ let resolved_body = resolve_block_statements(body, &module, path, global_store);
21
+
22
+ global_store.functions.add_function(FunctionDef {
23
+ name: name.clone(),
24
+ parameters: parameters.clone(),
25
+ body: resolved_body.clone(),
26
+ });
27
+
28
+ if let Some(current_mod) = global_store.modules.get_mut(path) {
29
+ current_mod.function_table.add_function(FunctionDef {
30
+ name: name.clone(),
31
+ parameters: parameters.clone(),
32
+ body: resolved_body.clone(),
33
+ });
34
+ } else {
35
+ eprintln!("[resolve_statement] ❌ Module path not found: {path}");
36
+ }
37
+
38
+ return Statement {
39
+ kind: StatementKind::Function {
40
+ name: name.clone(),
41
+ parameters: parameters.clone(),
42
+ body: resolved_body,
43
+ },
44
+ value: Value::Null,
45
+ ..stmt.clone()
46
+ };
47
+ } else {
48
+ return Statement {
49
+ kind: StatementKind::Error {
50
+ message: "Expected a function statement".to_string(),
51
+ },
52
+ value: Value::Null,
53
+ ..stmt.clone()
54
+ };
55
+ }
56
+ }
57
+
58
+ fn resolve_block_statements(
59
+ body: &[Statement],
60
+ module: &Module,
61
+ path: &str,
62
+ global_store: &mut GlobalStore
63
+ ) -> Vec<Statement> {
64
+ body.iter()
65
+ .map(|stmt| resolve_statement(stmt, module, path, global_store))
66
+ .collect()
67
+ }
68
+
69
+ fn type_error(logger: &Logger, module: &Module, stmt: &Statement, message: String) -> Statement {
70
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
71
+ logger.log_error_with_stacktrace(&message, &stacktrace);
72
+
73
+ Statement {
74
+ kind: StatementKind::Error { message },
75
+ value: Value::Null,
76
+ ..stmt.clone()
77
+ }
78
+ }
@@ -1,20 +1,18 @@
1
- use std::collections::HashMap;
2
-
3
1
  use crate::{
4
2
  core::{
5
- parser::statement::{ Statement, StatementKind },
6
- preprocessor::{ module::Module, resolver::driver::resolve_statement },
3
+ parser::statement::{Statement, StatementKind},
4
+ preprocessor::{module::Module, resolver::driver::resolve_statement},
7
5
  shared::value::Value,
8
- store::{ global::GlobalStore, variable::VariableTable },
6
+ store::global::GlobalStore,
9
7
  },
10
- utils::logger::{ LogLevel, Logger },
8
+ utils::logger::{LogLevel, Logger},
11
9
  };
12
10
 
13
11
  pub fn resolve_group(
14
12
  stmt: &Statement,
15
13
  module: &Module,
16
14
  path: &str,
17
- global_store: &mut GlobalStore
15
+ global_store: &mut GlobalStore,
18
16
  ) -> Statement {
19
17
  let logger = Logger::new();
20
18
 
@@ -22,27 +20,59 @@ pub fn resolve_group(
22
20
  return type_error(&logger, module, stmt, "Expected a map in group statement".to_string());
23
21
  };
24
22
 
25
- let mut resolved_map = group_map.clone();
23
+ // Check for the presence of the identifier field
24
+ let identifier = match group_map.get("identifier") {
25
+ Some(Value::String(id)) => id.clone(),
26
+ _ => {
27
+ return type_error(
28
+ &logger,
29
+ module,
30
+ stmt,
31
+ "Group statement must have an 'identifier' field".to_string(),
32
+ )
33
+ }
34
+ };
26
35
 
36
+ // Ensure the identifier does not already exist
37
+ if global_store.variables.variables.contains_key(&identifier) {
38
+ return type_error(
39
+ &logger,
40
+ module,
41
+ stmt,
42
+ format!("Group identifier '{}' already exists", identifier),
43
+ );
44
+ }
45
+
46
+ // Resolve statements in the body
47
+ let mut resolved_map = group_map.clone();
27
48
  if let Some(Value::Block(body)) = group_map.get("body") {
28
49
  let resolved_body = resolve_block_statements(body, module, path, global_store);
29
50
  resolved_map.insert("body".to_string(), Value::Block(resolved_body));
30
51
  } else {
31
- logger.log_message(LogLevel::Warning, "group without a body");
52
+ logger.log_message(LogLevel::Warning, "Group without a body");
32
53
  }
33
54
 
34
- Statement {
55
+ // Build a complete Statement for the group
56
+ let resolved_group_stmt = Statement {
35
57
  kind: StatementKind::Group,
36
- value: Value::Map(resolved_map),
58
+ value: Value::Map(resolved_map.clone()),
37
59
  ..stmt.clone()
38
- }
60
+ };
61
+
62
+ // Store the Statement directly in the global variable_table
63
+ global_store
64
+ .variables
65
+ .variables
66
+ .insert(identifier.clone(), Value::Statement(Box::new(resolved_group_stmt.clone())));
67
+
68
+ resolved_group_stmt
39
69
  }
40
70
 
41
71
  fn resolve_block_statements(
42
72
  body: &[Statement],
43
73
  module: &Module,
44
74
  path: &str,
45
- global_store: &mut GlobalStore
75
+ global_store: &mut GlobalStore,
46
76
  ) -> Vec<Statement> {
47
77
  body.iter()
48
78
  .map(|stmt| resolve_statement(stmt, module, path, global_store))
@@ -1,13 +1,8 @@
1
- use crate::
2
- core::{
3
- parser::statement:: Statement ,
4
- preprocessor::{
5
- module::Module,
6
- resolver:: value::resolve_value ,
7
- },
8
- store:: global::GlobalStore ,
9
- }
10
- ;
1
+ use crate::core::{
2
+ parser::statement::Statement,
3
+ preprocessor::{ module::Module, resolver::value::resolve_value },
4
+ store::global::GlobalStore,
5
+ };
11
6
 
12
7
  pub fn resolve_let(
13
8
  stmt: &Statement,
@@ -18,6 +13,8 @@ pub fn resolve_let(
18
13
  ) -> Statement {
19
14
  let resolved_value = resolve_value(&stmt.value, module, global_store);
20
15
 
16
+ global_store.variables.set(name.to_string(), resolved_value.clone());
17
+
21
18
  if let Some(current_mod) = global_store.modules.get_mut(path) {
22
19
  current_mod.variable_table.set(name.to_string(), resolved_value.clone());
23
20
  } else {
@@ -11,4 +11,5 @@ pub mod condition;
11
11
  pub mod spawn;
12
12
  pub mod call;
13
13
  pub mod synth;
14
- pub mod let_;
14
+ pub mod let_;
15
+ pub mod function;
@@ -14,45 +14,79 @@ use crate::{
14
14
 
15
15
  pub fn resolve_spawn(
16
16
  stmt: &Statement,
17
+ name: String,
18
+ args: Vec<Value>,
17
19
  module: &Module,
18
20
  path: &str,
19
21
  global_store: &mut GlobalStore
20
22
  ) -> Statement {
21
23
  let logger = Logger::new();
22
24
 
23
- let resolved_value = resolve_value(&stmt.value, module, global_store);
25
+ // Si c'est une fonction
26
+ if let Some(func) = global_store.functions.functions.get(&name) {
27
+ let mut resolved_map = std::collections::HashMap::new();
28
+ resolved_map.insert("name".to_string(), Value::String(name.clone()));
29
+ resolved_map.insert("args".to_string(), Value::Array(args.clone()));
30
+ resolved_map.insert("body".to_string(), Value::Block(func.body.clone()));
24
31
 
25
- match resolved_value {
26
- Value::Map(mut map) => {
27
- if let Some(Value::Block(stmts)) = map.get("body") {
28
- let resolved_block = stmts
29
- .iter()
30
- .map(|s| resolve_statement(s, module, path, global_store))
31
- .collect();
32
- map.insert("body".to_string(), Value::Block(resolved_block));
33
- }
32
+ return Statement {
33
+ kind: StatementKind::Spawn { name, args },
34
+ value: Value::Map(resolved_map),
35
+ ..stmt.clone()
36
+ };
37
+ }
34
38
 
35
- Statement {
36
- kind: StatementKind::Spawn,
37
- value: Value::Map(map),
38
- ..stmt.clone()
39
- }
40
- }
39
+ // ✅ Si c'est un group dans les variables
40
+ if let Some(variable) = global_store.variables.variables.get(&name) {
41
+ if let Value::Statement(stmt_box) = variable {
42
+ if let StatementKind::Group = stmt_box.kind {
43
+ if let Value::Map(map) = &stmt_box.value {
44
+ if let Some(Value::Block(body)) = map.get("body") {
45
+ let mut resolved_map = std::collections::HashMap::new();
46
+ resolved_map.insert("identifier".to_string(), Value::String(name.clone()));
47
+ resolved_map.insert("args".to_string(), Value::Array(args.clone()));
48
+ resolved_map.insert("body".to_string(), Value::Block(body.clone()));
41
49
 
42
- _ => {
43
- let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
44
- logger.log_message(
45
- LogLevel::Error,
46
- &format!("Expected a map in spawn statement\n → at {stacktrace}")
47
- );
48
-
49
- Statement {
50
- kind: StatementKind::Error {
51
- message: "Invalid spawn value".to_string(),
52
- },
53
- value: Value::Null,
54
- ..stmt.clone()
50
+ return Statement {
51
+ kind: StatementKind::Spawn { name, args },
52
+ value: Value::Map(resolved_map),
53
+ ..stmt.clone()
54
+ };
55
+ }
56
+ }
55
57
  }
56
58
  }
57
59
  }
58
- }
60
+
61
+ // ❌ Sinon erreur
62
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
63
+ logger.log_message(
64
+ LogLevel::Error,
65
+ &format!("Function or group '{}' not found for spawn\n → at {stacktrace}", name)
66
+ );
67
+
68
+ Statement {
69
+ kind: StatementKind::Error {
70
+ message: format!("Function or group '{}' not found for spawn", name),
71
+ },
72
+ value: Value::Null,
73
+ ..stmt.clone()
74
+ }
75
+ }
76
+
77
+ fn get_group_body(stmt_box: &Statement) -> Vec<Statement> {
78
+ if let Value::Block(body) = &stmt_box.value { body.clone() } else { vec![] }
79
+ }
80
+
81
+ fn error_stmt(logger: &Logger, module: &Module, stmt: &Statement, message: &str) -> Statement {
82
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
83
+ logger.log_message(LogLevel::Error, &format!("{message}\n → at {stacktrace}"));
84
+
85
+ Statement {
86
+ kind: StatementKind::Error {
87
+ message: message.to_string(),
88
+ },
89
+ value: Value::Null,
90
+ ..stmt.clone()
91
+ }
92
+ }
@@ -14,6 +14,7 @@ pub fn resolve_trigger(
14
14
  stmt: &Statement,
15
15
  entity: &str,
16
16
  duration: &mut Duration,
17
+ effects: Option<Value>,
17
18
  module: &Module,
18
19
  path: &str,
19
20
  global_store: &GlobalStore
@@ -44,6 +45,8 @@ pub fn resolve_trigger(
44
45
  // Params value resolution
45
46
  final_value = match &stmt.value {
46
47
  Value::Identifier(ident) => {
48
+ println!("Resolving identifier: {}", ident);
49
+
47
50
  resolve_identifier(ident, module, global_store).unwrap_or_else(|| {
48
51
  logger.log_error_with_stacktrace(
49
52
  &format!("'{path}': value identifier '{ident}' not found"),
@@ -71,9 +74,10 @@ pub fn resolve_trigger(
71
74
  Statement {
72
75
  kind: StatementKind::Trigger {
73
76
  entity: entity.to_string(),
74
- duration: final_duration,
77
+ duration: final_duration.clone(),
78
+ effects: Some(final_value.clone()),
75
79
  },
76
- value: final_value,
80
+ value: Value::Null,
77
81
  line: stmt.line,
78
82
  column: stmt.column,
79
83
  indent: stmt.indent,
@@ -86,7 +90,7 @@ fn resolve_identifier(ident: &str, module: &Module, global_store: &GlobalStore)
86
90
  }
87
91
 
88
92
  for (_, other_mod) in &global_store.modules {
89
- if let Some(val) = other_mod.export_table.get_export(ident) {
93
+ if let Some(val) = other_mod.variable_table.get(ident) {
90
94
  return Some(resolve_value(val, other_mod, global_store));
91
95
  }
92
96
  }
@@ -16,11 +16,18 @@ fn find_export_value(name: &str, global_store: &GlobalStore) -> Option<Value> {
16
16
  return Some(val.clone());
17
17
  }
18
18
  }
19
+
19
20
  None
20
21
  }
21
22
 
22
23
  pub fn resolve_value(value: &Value, module: &Module, global_store: &mut GlobalStore) -> Value {
23
24
  match value {
25
+ Value::String(s) => {
26
+ println!("Resolving value: {}", s);
27
+
28
+ Value::String(s.clone())
29
+ },
30
+
24
31
  Value::Identifier(name) => {
25
32
  if let Some(original_val) = module.variable_table.get(name) {
26
33
  return resolve_value(original_val, module, global_store);
@@ -30,7 +37,8 @@ pub fn resolve_value(value: &Value, module: &Module, global_store: &mut GlobalSt
30
37
  return resolve_value(&export_val, module, global_store);
31
38
  }
32
39
 
33
- eprintln!("⚠️ Unresolved identifier '{}'", name);
40
+ println!("⚠️ Unresolved identifier '{}'", name);
41
+
34
42
  Value::Null
35
43
  }
36
44
 
@@ -62,6 +70,7 @@ pub fn resolve_value(value: &Value, module: &Module, global_store: &mut GlobalSt
62
70
  for (k, v) in map {
63
71
  resolved.insert(k.clone(), resolve_value(v, module, global_store));
64
72
  }
73
+
65
74
  Value::Map(resolved)
66
75
  }
67
76
 
@@ -1,12 +1,13 @@
1
1
  use std::collections::HashMap;
2
2
  use serde::{ Deserialize, Serialize };
3
3
 
4
- use crate::core::parser::statement::Statement;
4
+ use crate::core::{parser::statement::{Statement, StatementKind}, shared::duration::Duration};
5
5
 
6
6
  #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
7
7
  pub enum Value {
8
8
  Boolean(bool),
9
9
  Number(f32),
10
+ Duration(Duration),
10
11
  Identifier(String),
11
12
  String(String),
12
13
  Array(Vec<Value>),
@@ -14,6 +15,8 @@ pub enum Value {
14
15
  Block(Vec<Statement>),
15
16
  Sample(String),
16
17
  Beat(String),
18
+ Statement(Box<Statement>),
19
+ StatementKind(Box<StatementKind>),
17
20
  Unknown,
18
21
  Null,
19
22
  }
@@ -0,0 +1,34 @@
1
+ use std::collections::HashMap;
2
+ use crate::core::parser::statement::Statement;
3
+
4
+ #[derive(Debug, Clone)]
5
+ pub struct FunctionDef {
6
+ pub name: String,
7
+ pub parameters: Vec<String>,
8
+ pub body: Vec<Statement>,
9
+ }
10
+
11
+ #[derive(Debug, Clone)]
12
+ pub struct FunctionTable {
13
+ pub functions: HashMap<String, FunctionDef>,
14
+ }
15
+
16
+ impl FunctionTable {
17
+ pub fn new() -> Self {
18
+ FunctionTable {
19
+ functions: HashMap::new(),
20
+ }
21
+ }
22
+
23
+ pub fn add_function(&mut self, function: FunctionDef) {
24
+ self.functions.insert(function.name.clone(), function);
25
+ }
26
+
27
+ pub fn get_function(&self, name: &str) -> Option<&FunctionDef> {
28
+ self.functions.get(name)
29
+ }
30
+
31
+ pub fn remove_function(&mut self, name: &str) -> Option<FunctionDef> {
32
+ self.functions.remove(name)
33
+ }
34
+ }
@@ -1,23 +1,22 @@
1
1
  use std::collections::HashMap;
2
- use crate::core::preprocessor::module::Module;
2
+ use crate::core::{
3
+ preprocessor::module::Module,
4
+ store::{ function::FunctionTable, variable::VariableTable },
5
+ };
3
6
 
4
- #[derive(Debug, Default, Clone)]
7
+ #[derive(Debug, Clone)]
5
8
  pub struct GlobalStore {
6
9
  pub modules: HashMap<String, Module>,
10
+ pub variables: VariableTable,
11
+ pub functions: FunctionTable,
7
12
  }
8
13
 
9
14
  impl GlobalStore {
10
15
  pub fn new() -> Self {
11
16
  GlobalStore {
12
17
  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
- }
18
+ functions: FunctionTable::new(),
19
+ variables: VariableTable::new(),
21
20
  }
22
21
  }
23
22
 
@@ -1,4 +1,5 @@
1
1
  pub mod global;
2
2
  pub mod export;
3
3
  pub mod import;
4
- pub mod variable;
4
+ pub mod variable;
5
+ pub mod function;
@@ -5,12 +5,14 @@ use crate::core::shared::value::Value;
5
5
  #[derive(Debug, Default, Clone, PartialEq)]
6
6
  pub struct VariableTable {
7
7
  pub variables: HashMap<String, Value>,
8
+ pub parent: Option<Box<VariableTable>>,
8
9
  }
9
10
 
10
11
  impl VariableTable {
11
12
  pub fn new() -> Self {
12
13
  VariableTable {
13
14
  variables: HashMap::new(),
15
+ parent: None,
14
16
  }
15
17
  }
16
18
 
@@ -18,6 +20,10 @@ impl VariableTable {
18
20
  self.variables.insert(name, value);
19
21
  }
20
22
 
23
+ pub fn with_parent(parent: VariableTable) -> Self {
24
+ Self { variables: HashMap::new(), parent: Some(Box::new(parent)) }
25
+ }
26
+
21
27
  pub fn get(&self, name: &str) -> Option<&Value> {
22
28
  self.variables.get(name)
23
29
  }