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

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 (107) hide show
  1. package/.devalang +1 -1
  2. package/Cargo.toml +46 -46
  3. package/README.md +48 -30
  4. package/docs/CHANGELOG.md +28 -6
  5. package/docs/COMMANDS.md +31 -0
  6. package/docs/CONFIG.md +6 -4
  7. package/docs/ROADMAP.md +5 -1
  8. package/docs/TODO.md +10 -35
  9. package/examples/exported.deva +1 -1
  10. package/examples/index.deva +8 -1
  11. package/examples/samples/hat-808.wav +0 -0
  12. package/out-tsc/bin/devalang.exe +0 -0
  13. package/package.json +41 -42
  14. package/project-version.json +5 -5
  15. package/rust/audio/engine.rs +130 -0
  16. package/rust/audio/interpreter.rs +143 -0
  17. package/rust/audio/loader.rs +46 -0
  18. package/rust/audio/mod.rs +5 -1
  19. package/rust/audio/player.rs +54 -0
  20. package/rust/audio/render.rs +57 -0
  21. package/rust/cli/build.rs +73 -45
  22. package/rust/cli/check.rs +47 -111
  23. package/rust/cli/init.rs +1 -1
  24. package/rust/cli/mod.rs +203 -2
  25. package/rust/cli/play.rs +191 -0
  26. package/rust/{utils/config.rs → config/loader.rs} +3 -2
  27. package/rust/config/mod.rs +16 -0
  28. package/rust/core/builder/mod.rs +69 -27
  29. package/rust/core/debugger/lexer.rs +27 -0
  30. package/rust/core/debugger/mod.rs +12 -49
  31. package/rust/core/debugger/preprocessor.rs +27 -0
  32. package/rust/core/error/mod.rs +60 -0
  33. package/rust/core/lexer/{at.rs → handler/at.rs} +1 -1
  34. package/rust/core/lexer/{brace.rs → handler/brace.rs} +1 -1
  35. package/rust/core/lexer/{colon.rs → handler/colon.rs} +1 -1
  36. package/rust/core/lexer/{comment.rs → handler/comment.rs} +3 -3
  37. package/rust/core/lexer/{dot.rs → handler/dot.rs} +1 -1
  38. package/rust/core/lexer/{equal.rs → handler/equal.rs} +1 -1
  39. package/rust/core/lexer/{identifier.rs → handler/identifier.rs} +1 -1
  40. package/rust/core/lexer/{indent.rs → handler/indent.rs} +10 -5
  41. package/rust/core/lexer/handler/mod.rs +238 -0
  42. package/rust/core/lexer/{newline.rs → handler/newline.rs} +6 -10
  43. package/rust/core/lexer/{number.rs → handler/number.rs} +1 -1
  44. package/rust/core/lexer/handler/string.rs +66 -0
  45. package/rust/core/lexer/mod.rs +25 -14
  46. package/rust/core/lexer/token.rs +55 -0
  47. package/rust/core/mod.rs +5 -2
  48. package/rust/core/parser/handler/at.rs +166 -0
  49. package/rust/core/parser/handler/bank.rs +38 -0
  50. package/rust/core/parser/handler/dot.rs +112 -0
  51. package/rust/core/parser/handler/identifier.rs +134 -0
  52. package/rust/core/parser/handler/loop_.rs +55 -0
  53. package/rust/core/parser/handler/mod.rs +6 -0
  54. package/rust/core/parser/handler/tempo.rs +47 -0
  55. package/rust/core/parser/mod.rs +204 -166
  56. package/rust/core/parser/statement.rs +91 -0
  57. package/rust/core/preprocessor/loader.rs +116 -0
  58. package/rust/core/preprocessor/mod.rs +2 -24
  59. package/rust/core/preprocessor/module.rs +37 -56
  60. package/rust/core/preprocessor/processor.rs +41 -0
  61. package/rust/core/preprocessor/resolver/bank.rs +38 -51
  62. package/rust/core/preprocessor/resolver/loop_.rs +126 -65
  63. package/rust/core/preprocessor/resolver/mod.rs +119 -80
  64. package/rust/core/preprocessor/resolver/tempo.rs +40 -61
  65. package/rust/core/preprocessor/resolver/trigger.rs +93 -155
  66. package/rust/core/shared/duration.rs +8 -0
  67. package/rust/core/shared/mod.rs +2 -0
  68. package/rust/core/shared/value.rs +18 -0
  69. package/rust/core/store/export.rs +28 -0
  70. package/rust/core/store/global.rs +39 -0
  71. package/rust/core/store/import.rs +28 -0
  72. package/rust/core/store/mod.rs +4 -0
  73. package/rust/core/store/variable.rs +28 -0
  74. package/rust/core/utils/mod.rs +2 -0
  75. package/rust/core/utils/validation.rs +35 -0
  76. package/rust/lib.rs +0 -1
  77. package/rust/main.rs +22 -18
  78. package/rust/utils/logger.rs +69 -34
  79. package/rust/utils/mod.rs +3 -5
  80. package/rust/utils/watcher.rs +10 -2
  81. package/templates/minimal/.devalang +1 -1
  82. package/templates/welcome/.devalang +1 -1
  83. package/rust/core/lexer/bracket.rs +0 -41
  84. package/rust/core/lexer/driver.rs +0 -286
  85. package/rust/core/lexer/quote.rs +0 -61
  86. package/rust/core/parser/at.rs +0 -142
  87. package/rust/core/parser/bank.rs +0 -42
  88. package/rust/core/parser/dot.rs +0 -137
  89. package/rust/core/parser/identifer.rs +0 -91
  90. package/rust/core/parser/loop_.rs +0 -62
  91. package/rust/core/parser/tempo.rs +0 -42
  92. package/rust/core/parser/variable.rs +0 -129
  93. package/rust/core/preprocessor/dependencies.rs +0 -54
  94. package/rust/core/preprocessor/resolver/at.rs +0 -24
  95. package/rust/core/types/cli.rs +0 -182
  96. package/rust/core/types/config.rs +0 -15
  97. package/rust/core/types/mod.rs +0 -8
  98. package/rust/core/types/module.rs +0 -41
  99. package/rust/core/types/parser.rs +0 -73
  100. package/rust/core/types/statement.rs +0 -105
  101. package/rust/core/types/store.rs +0 -116
  102. package/rust/core/types/token.rs +0 -83
  103. package/rust/core/types/variable.rs +0 -32
  104. package/rust/runner/executer.rs +0 -44
  105. package/rust/runner/mod.rs +0 -1
  106. /package/rust/{utils → core/utils}/path.rs +0 -0
  107. /package/rust/utils/{loader.rs → spinner.rs} +0 -0
@@ -1,113 +1,152 @@
1
- pub mod bank;
1
+ pub mod trigger;
2
2
  pub mod loop_;
3
+ pub mod bank;
3
4
  pub mod tempo;
4
- pub mod trigger;
5
- pub mod at;
6
-
7
- use crate::core::{
8
- preprocessor::resolver::{
9
- bank::resolve_bank_statement,
10
- loop_::resolve_loop_statement,
11
- tempo::resolve_tempo_statement,
12
- trigger::resolve_trigger_statement,
13
- at::{ resolve_load_statement },
14
- },
15
- types::{
16
- module::Module,
17
- parser::Parser,
18
- statement::{ Statement, StatementKind, StatementResolved, StatementResolvedValue },
19
- store::{ ExportTable, GlobalStore, ImportTable },
20
- variable::VariableValue,
5
+
6
+ use std::collections::HashMap;
7
+ use crate::{
8
+ core::{
9
+ parser::statement::{ self, Statement, StatementKind },
10
+ preprocessor::{
11
+ loader::ModuleLoader,
12
+ resolver::{
13
+ bank::resolve_bank,
14
+ loop_::resolve_loop,
15
+ tempo::resolve_tempo,
16
+ trigger::resolve_trigger,
17
+ },
18
+ },
19
+ shared::{ duration::Duration, value::Value },
20
+ store::global::GlobalStore,
21
+ utils::validation::{ is_valid_entity, is_valid_identifier },
21
22
  },
23
+ utils::logger::Logger,
22
24
  };
23
25
 
24
- pub fn resolve_exports(statements: &[Statement], parser: &Parser) -> ExportTable {
25
- let mut export_table = parser.export_table.clone();
26
+ pub fn resolve_all_modules(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
27
+ for module in global_store.clone().modules.values_mut() {
28
+ resolve_imports(module_loader, global_store);
29
+ }
30
+ }
26
31
 
27
- for stmt in statements {
28
- if let StatementKind::Export = &stmt.kind {
29
- if let VariableValue::Array(tokens) = &stmt.value {
30
- for token in tokens {
31
- let var_name = &token.lexeme;
32
- if let Some(value) = parser.variable_table.variables.get(var_name) {
33
- export_table.add_export(var_name.clone(), value.clone());
32
+ pub fn resolve_imports(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
33
+ for (module_path, module) in global_store.clone().modules.iter_mut() {
34
+ for (name, source_path) in &module.import_table.imports {
35
+ match source_path {
36
+ Value::String(source_path) => {
37
+ if let Some(source_module) = global_store.modules.get(source_path) {
38
+ if let Some(value) = source_module.export_table.get_export(name) {
39
+ module.variable_table.set(name.clone(), value.clone());
40
+ } else {
41
+ println!(
42
+ "[warn] '{module_path}': '{name}' not found in exports of '{source_path}'"
43
+ );
44
+ }
34
45
  } else {
35
- eprintln!("⚠️ Variable '{}' not found in scope, export skipped", var_name);
46
+ println!(
47
+ "[warn] '{module_path}': cannot find source module '{source_path}'"
48
+ );
36
49
  }
37
50
  }
38
- } else {
39
- eprintln!("⚠️ Unexpected value type in export: {:?}", stmt.value);
51
+ _ => {
52
+ println!(
53
+ "[warn] '{module_path}': expected string for import source, found {:?}",
54
+ source_path
55
+ );
56
+ }
40
57
  }
41
58
  }
42
59
  }
43
-
44
- export_table
45
60
  }
46
61
 
47
- pub fn resolve_imports(module: &mut Module, global_store: &GlobalStore) -> ImportTable {
48
- let mut import_table = ImportTable::default();
62
+ pub fn resolve_and_flatten_all_modules(
63
+ global_store: &mut GlobalStore
64
+ ) -> HashMap<String, Vec<Statement>> {
65
+ let logger = Logger::new();
66
+ let snapshot = global_store.clone(); // pour éviter les emprunts mutables
49
67
 
50
- for stmt in &module.statements {
51
- if let StatementKind::Import { names, source } = &stmt.kind {
52
- if let Some(from_module) = global_store.modules.get(source) {
53
- for name in names {
54
- if let Some(value) = from_module.export_table.exports.get(name) {
55
- module.variable_table.variables.insert(name.clone(), value.clone());
56
- import_table.add_import(name.clone(), value.clone());
57
- } else {
58
- eprintln!("⚠️ '{}' not found in exports of '{}'", name, source);
68
+ // 1. Résolution des imports
69
+ for (module_path, module) in global_store.modules.iter_mut() {
70
+ for (name, source_path) in &module.import_table.imports {
71
+ if let Value::String(source_path_str) = source_path {
72
+ match snapshot.modules.get(source_path_str) {
73
+ Some(source_module) => {
74
+ if let Some(value) = source_module.export_table.get_export(name) {
75
+ module.variable_table.set(name.clone(), value.clone());
76
+ } else {
77
+ logger.log_error_with_stacktrace(
78
+ &format!("'{name}' not found in exports of '{source_path_str}'"),
79
+ module_path
80
+ );
81
+ }
82
+ }
83
+ None => {
84
+ logger.log_error_with_stacktrace(
85
+ &format!("Cannot find source module '{source_path_str}'"),
86
+ module_path
87
+ );
59
88
  }
60
89
  }
61
90
  } else {
62
- eprintln!("⚠️ Module '{}' not found", source);
91
+ logger.log_error_with_stacktrace(
92
+ &format!("Expected string for import source, found {:?}", source_path),
93
+ module_path
94
+ );
63
95
  }
64
96
  }
65
97
  }
66
98
 
67
- import_table
68
- }
99
+ // 2. Résolution des statements
100
+ let mut resolved_map = HashMap::new();
101
+ let store_snapshot = global_store.clone();
69
102
 
70
- pub fn resolve_statement(stmt: &Statement, module: &mut Module) -> StatementResolved {
71
- match &stmt.kind {
72
- StatementKind::Loop { iterator } => {
73
- resolve_loop_statement(stmt, iterator.clone(), module)
74
- }
103
+ for (path, module) in &store_snapshot.modules {
104
+ let mut resolved = Vec::new();
75
105
 
76
- StatementKind::Trigger { entity, duration } => {
77
- resolve_trigger_statement(stmt, entity.clone(), duration.clone(), module)
78
- }
106
+ for stmt in &module.statements {
107
+ let mut stmt = stmt.clone();
79
108
 
80
- StatementKind::Bank { .. } => { resolve_bank_statement(stmt, module) }
109
+ match &stmt.kind {
110
+ StatementKind::Trigger { entity, duration } => {
111
+ let resolved_stmt = resolve_trigger(
112
+ &stmt,
113
+ entity.as_str(),
114
+ &mut duration.clone(),
115
+ &module,
116
+ &path,
117
+ &store_snapshot
118
+ );
119
+ resolved.push(resolved_stmt);
120
+ }
81
121
 
82
- StatementKind::Tempo { .. } => { resolve_tempo_statement(stmt, module) }
122
+ StatementKind::Loop => {
123
+ let resolved_stmt = resolve_loop(&stmt, &module, &path, &store_snapshot);
124
+ resolved.push(resolved_stmt);
125
+ }
83
126
 
84
- StatementKind::Load { source, alias } => {
85
- resolve_load_statement(stmt, source, alias, module)
86
- }
127
+ StatementKind::Bank => {
128
+ let resolved_stmt = resolve_bank(&stmt, &module, &path, &store_snapshot);
129
+ resolved.push(resolved_stmt);
130
+ }
87
131
 
88
- // TODO Handle other statement kinds
89
-
90
- StatementKind::Error => {
91
- StatementResolved {
92
- kind: StatementKind::Error,
93
- value: match stmt.value {
94
- VariableValue::Text(ref msg) => StatementResolvedValue::String(msg.clone()),
95
- _ => StatementResolvedValue::Unknown,
96
- },
97
- indent: stmt.indent,
98
- line: stmt.line,
99
- column: stmt.column,
100
- }
101
- }
132
+ StatementKind::Tempo => {
133
+ let resolved_stmt = resolve_tempo(&stmt, &module, &path, &store_snapshot);
134
+ resolved.push(resolved_stmt);
135
+ }
136
+
137
+ StatementKind::Import { .. } | StatementKind::Export { .. } => {
138
+ // Rien à faire
139
+ resolved.push(stmt.clone());
140
+ }
102
141
 
103
- _ => {
104
- StatementResolved {
105
- kind: StatementKind::Unknown,
106
- value: StatementResolvedValue::Unknown,
107
- indent: stmt.indent,
108
- line: stmt.line,
109
- column: stmt.column,
142
+ _ => {
143
+ resolved.push(stmt);
144
+ }
110
145
  }
111
146
  }
147
+
148
+ resolved_map.insert(path.clone(), resolved);
112
149
  }
150
+
151
+ resolved_map
113
152
  }
@@ -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,114 @@
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,
9
+ utils::validation::is_valid_entity,
10
10
  },
11
+ utils::logger::Logger,
11
12
  };
12
13
 
13
- pub fn resolve_trigger_statement(
14
+ pub fn resolve_trigger(
14
15
  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());
16
+ entity: &str,
17
+ duration: &mut Duration,
18
+ module: &Module,
19
+ path: &str,
20
+ global_store: &GlobalStore
21
+ ) -> Statement {
22
+ let logger = Logger::new();
23
+
24
+ let mut final_duration = duration.clone();
25
+ let mut final_value = stmt.value.clone();
26
+
27
+ if !is_valid_entity(entity, module, global_store) {
28
+ let message = format!("Invalid entity '{}', expected a valid identifier", entity);
29
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
30
+ logger.log_error_with_stacktrace(&message, &stacktrace);
31
+
32
+ return Statement {
33
+ kind: stmt.kind.clone(),
34
+ value: Value::Null,
35
+ line: stmt.line,
36
+ column: stmt.column,
37
+ indent: stmt.indent,
38
+ };
25
39
  }
26
40
 
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
- }
41
+ // Résolution de duration si c'est un identifiant
42
+ if let Duration::Identifier(ident) = duration {
43
+ if let Some(val) = module.variable_table.get(ident) {
44
+ match val {
45
+ Value::Number(num) => {
46
+ final_duration = Duration::Number(*num);
50
47
  }
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,
48
+ Value::String(s) => {
49
+ final_duration = Duration::Identifier(s.clone());
115
50
  }
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,
51
+ Value::Identifier(id) if id == "auto" => {
52
+ final_duration = Duration::Auto;
127
53
  }
54
+ _ => {}
128
55
  }
129
56
  }
130
- VariableValue::Map(map) => {
131
- let mut resolved_map = HashMap::new();
132
-
133
- // TODO Handle nested maps and arrays
57
+ }
134
58
 
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,
59
+ // ✅ Résolution de value (params, effets)
60
+ final_value = match &stmt.value {
61
+ Value::Identifier(ident) => {
62
+ match module.variable_table.get(ident) {
63
+ Some(val) => val.clone(),
64
+ None => {
65
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
66
+ let message = format!(
67
+ "'{path}': value identifier '{ident}' not found in variable table"
68
+ );
69
+ logger.log_error_with_stacktrace(&message, &stacktrace);
70
+ Value::Null
71
+ }
144
72
  }
145
73
  }
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,
74
+ Value::Map(map) => {
75
+ let mut resolved_map = HashMap::new();
76
+ for (k, v) in map.iter() {
77
+ let resolved_v = match v {
78
+ Value::Identifier(id) => {
79
+ module.variable_table.get(id).cloned().unwrap_or(Value::Null)
80
+ }
81
+ other => other.clone(),
82
+ };
83
+ resolved_map.insert(k.clone(), resolved_v);
156
84
  }
85
+ Value::Map(resolved_map)
157
86
  }
87
+ other => other.clone(),
88
+ };
158
89
 
159
- // TODO Parse other parameters
160
-
161
- _ => {
162
- eprintln!("⚠️ Invalid value type for Trigger statement: {:?}", stmt.value);
163
-
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,
173
- }
174
- }
90
+ // On reconstruit le Statement avec Trigger résolu
91
+ if let StatementKind::Trigger { entity, .. } = &stmt.kind {
92
+ return Statement {
93
+ kind: StatementKind::Trigger {
94
+ entity: entity.to_string(),
95
+ duration: final_duration,
96
+ },
97
+ value: final_value,
98
+ line: stmt.line,
99
+ column: stmt.column,
100
+ indent: stmt.indent,
101
+ };
175
102
  }
103
+
104
+ return Statement {
105
+ kind: StatementKind::Trigger {
106
+ entity: entity.to_string(),
107
+ duration: final_duration,
108
+ },
109
+ value: final_value,
110
+ line: stmt.line,
111
+ column: stmt.column,
112
+ indent: stmt.indent,
113
+ };
176
114
  }
@@ -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
+ }