@devaloop/devalang 0.0.1-alpha.5 → 0.0.1-alpha.8
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.
- package/Cargo.toml +1 -1
- package/README.md +45 -14
- package/docs/CHANGELOG.md +39 -0
- package/docs/ROADMAP.md +2 -2
- package/docs/SYNTAX.md +80 -18
- package/docs/TODO.md +12 -11
- package/examples/condition.deva +24 -0
- package/examples/group.deva +12 -0
- package/examples/index.deva +8 -9
- package/examples/loop.deva +15 -0
- package/examples/variables.deva +9 -0
- package/out-tsc/bin/devalang.exe +0 -0
- package/package.json +44 -44
- package/project-version.json +5 -5
- package/rust/cli/build.rs +6 -2
- package/rust/cli/play.rs +2 -1
- package/rust/core/audio/evaluator.rs +31 -0
- package/rust/core/audio/interpreter/call.rs +42 -0
- package/rust/core/audio/interpreter/condition.rs +65 -0
- package/rust/core/audio/interpreter/driver.rs +204 -0
- package/rust/core/audio/interpreter/let_.rs +19 -0
- package/rust/core/audio/interpreter/load.rs +18 -0
- package/rust/core/audio/interpreter/loop_.rs +59 -0
- package/rust/core/audio/interpreter/mod.rs +11 -0
- package/rust/core/audio/interpreter/sleep.rs +36 -0
- package/rust/core/audio/interpreter/spawn.rs +65 -0
- package/rust/core/audio/interpreter/tempo.rs +16 -0
- package/rust/core/audio/interpreter/trigger.rs +69 -0
- package/rust/core/audio/loader/mod.rs +1 -0
- package/rust/{audio/loader.rs → core/audio/loader/trigger.rs} +6 -0
- package/rust/{audio → core/audio}/mod.rs +2 -1
- package/rust/{audio/render.rs → core/audio/renderer.rs} +2 -2
- package/rust/core/builder/mod.rs +2 -1
- package/rust/core/debugger/lexer.rs +1 -1
- package/rust/core/debugger/mod.rs +1 -0
- package/rust/core/debugger/store.rs +25 -0
- package/rust/core/error/mod.rs +1 -1
- package/rust/core/lexer/handler/driver.rs +215 -0
- package/rust/core/lexer/handler/identifier.rs +2 -0
- package/rust/core/lexer/handler/indent.rs +1 -1
- package/rust/core/lexer/handler/mod.rs +3 -228
- package/rust/core/lexer/handler/operator.rs +44 -0
- package/rust/core/lexer/handler/string.rs +3 -6
- package/rust/core/lexer/mod.rs +1 -1
- package/rust/core/lexer/token.rs +36 -9
- package/rust/core/mod.rs +2 -1
- package/rust/core/parser/driver.rs +312 -0
- package/rust/core/parser/handler/at.rs +3 -7
- package/rust/core/parser/handler/bank.rs +5 -2
- package/rust/core/parser/handler/condition.rs +74 -0
- package/rust/core/parser/handler/dot.rs +1 -1
- package/rust/core/parser/handler/identifier.rs +130 -2
- package/rust/core/parser/handler/loop_.rs +1 -1
- package/rust/core/parser/handler/mod.rs +2 -1
- package/rust/core/parser/handler/tempo.rs +1 -1
- package/rust/core/parser/mod.rs +3 -237
- package/rust/core/parser/statement.rs +30 -33
- package/rust/core/preprocessor/loader.rs +7 -6
- package/rust/core/preprocessor/processor.rs +29 -3
- package/rust/core/preprocessor/resolver/bank.rs +10 -9
- package/rust/core/preprocessor/resolver/call.rs +53 -0
- package/rust/core/preprocessor/resolver/condition.rs +66 -0
- package/rust/core/preprocessor/resolver/driver.rs +182 -0
- package/rust/core/preprocessor/resolver/group.rs +118 -0
- package/rust/core/preprocessor/resolver/loop_.rs +3 -6
- package/rust/core/preprocessor/resolver/mod.rs +6 -147
- package/rust/core/preprocessor/resolver/spawn.rs +53 -0
- package/rust/core/preprocessor/resolver/trigger.rs +0 -3
- package/rust/lib.rs +0 -1
- package/rust/main.rs +0 -1
- package/examples/exported.deva +0 -7
- package/rust/audio/interpreter.rs +0 -143
- package/rust/core/lexer/handler/equal.rs +0 -32
- /package/rust/{audio → core/audio}/engine.rs +0 -0
- /package/rust/{audio → core/audio}/player.rs +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
use std::collections::HashMap;
|
|
2
|
+
use crate::{
|
|
3
|
+
core::{
|
|
4
|
+
parser::statement::{ self, Statement, StatementKind },
|
|
5
|
+
preprocessor::{
|
|
6
|
+
loader::ModuleLoader,
|
|
7
|
+
module::Module,
|
|
8
|
+
resolver::{
|
|
9
|
+
bank::resolve_bank, call::resolve_call, condition::resolve_condition, group::resolve_group, loop_::resolve_loop, spawn::resolve_spawn, tempo::resolve_tempo, trigger::resolve_trigger
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
shared::{ duration::Duration, value::Value },
|
|
13
|
+
store::global::GlobalStore,
|
|
14
|
+
utils::validation::{ is_valid_entity, is_valid_identifier },
|
|
15
|
+
},
|
|
16
|
+
utils::logger::Logger,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
pub fn resolve_all_modules(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
|
|
20
|
+
for module in global_store.clone().modules.values_mut() {
|
|
21
|
+
resolve_imports(module_loader, global_store);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
pub fn resolve_statement(
|
|
26
|
+
stmt: &Statement,
|
|
27
|
+
module: &Module,
|
|
28
|
+
path: &str,
|
|
29
|
+
global_store: &GlobalStore
|
|
30
|
+
) -> Statement {
|
|
31
|
+
match &stmt.kind {
|
|
32
|
+
StatementKind::Trigger { entity, duration } => {
|
|
33
|
+
resolve_trigger(
|
|
34
|
+
&mut stmt.clone(),
|
|
35
|
+
entity,
|
|
36
|
+
&mut duration.clone(),
|
|
37
|
+
module,
|
|
38
|
+
path,
|
|
39
|
+
global_store
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
StatementKind::If => { resolve_condition(stmt, module, path, global_store) }
|
|
44
|
+
|
|
45
|
+
StatementKind::Group => { resolve_group(stmt, module, path, global_store) }
|
|
46
|
+
|
|
47
|
+
StatementKind::Call => { resolve_call(stmt, module, path, global_store) }
|
|
48
|
+
|
|
49
|
+
StatementKind::Spawn => { resolve_spawn(stmt, module, path, global_store) }
|
|
50
|
+
|
|
51
|
+
// TODO: Handle other statement kinds if necessary
|
|
52
|
+
// ...
|
|
53
|
+
|
|
54
|
+
_ => stmt.clone(),
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
pub fn resolve_imports(module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
|
|
59
|
+
for (module_path, module) in global_store.clone().modules.iter_mut() {
|
|
60
|
+
for (name, source_path) in &module.import_table.imports {
|
|
61
|
+
match source_path {
|
|
62
|
+
Value::String(source_path) => {
|
|
63
|
+
if let Some(source_module) = global_store.modules.get(source_path) {
|
|
64
|
+
if let Some(value) = source_module.export_table.get_export(name) {
|
|
65
|
+
module.variable_table.set(name.clone(), value.clone());
|
|
66
|
+
} else {
|
|
67
|
+
println!(
|
|
68
|
+
"[warn] '{module_path}': '{name}' not found in exports of '{source_path}'"
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
println!(
|
|
73
|
+
"[warn] '{module_path}': cannot find source module '{source_path}'"
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
_ => {
|
|
78
|
+
println!(
|
|
79
|
+
"[warn] '{module_path}': expected string for import source, found {:?}",
|
|
80
|
+
source_path
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
pub fn resolve_and_flatten_all_modules(
|
|
89
|
+
global_store: &mut GlobalStore
|
|
90
|
+
) -> HashMap<String, Vec<Statement>> {
|
|
91
|
+
let logger = Logger::new();
|
|
92
|
+
let snapshot = global_store.clone();
|
|
93
|
+
|
|
94
|
+
// 1. Imports resolution
|
|
95
|
+
for (module_path, module) in global_store.modules.iter_mut() {
|
|
96
|
+
for (name, source_path) in &module.import_table.imports {
|
|
97
|
+
if let Value::String(source_path_str) = source_path {
|
|
98
|
+
match snapshot.modules.get(source_path_str) {
|
|
99
|
+
Some(source_module) => {
|
|
100
|
+
if let Some(value) = source_module.export_table.get_export(name) {
|
|
101
|
+
module.variable_table.set(name.clone(), value.clone());
|
|
102
|
+
} else {
|
|
103
|
+
logger.log_error_with_stacktrace(
|
|
104
|
+
&format!("'{name}' not found in exports of '{source_path_str}'"),
|
|
105
|
+
module_path
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
None => {
|
|
110
|
+
logger.log_error_with_stacktrace(
|
|
111
|
+
&format!("Cannot find source module '{source_path_str}'"),
|
|
112
|
+
module_path
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
logger.log_error_with_stacktrace(
|
|
118
|
+
&format!("Expected string for import source, found {:?}", source_path),
|
|
119
|
+
module_path
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 2. Statements resolution
|
|
126
|
+
let mut resolved_map: HashMap<String, Vec<Statement>> = HashMap::new();
|
|
127
|
+
let store_snapshot = global_store.clone();
|
|
128
|
+
|
|
129
|
+
for (path, module) in &store_snapshot.modules {
|
|
130
|
+
let mut resolved = Vec::new();
|
|
131
|
+
|
|
132
|
+
for stmt in &module.statements {
|
|
133
|
+
let mut stmt = stmt.clone();
|
|
134
|
+
|
|
135
|
+
match &stmt.kind {
|
|
136
|
+
StatementKind::Trigger { entity, duration } => {
|
|
137
|
+
let resolved_stmt = resolve_trigger(
|
|
138
|
+
&stmt,
|
|
139
|
+
entity.as_str(),
|
|
140
|
+
&mut duration.clone(),
|
|
141
|
+
&module,
|
|
142
|
+
&path,
|
|
143
|
+
&store_snapshot
|
|
144
|
+
);
|
|
145
|
+
resolved.push(resolved_stmt);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
StatementKind::Loop => {
|
|
149
|
+
let resolved_stmt = resolve_loop(&stmt, &module, &path, &store_snapshot);
|
|
150
|
+
resolved.push(resolved_stmt);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
StatementKind::Bank => {
|
|
154
|
+
let resolved_stmt = resolve_bank(&stmt, &module, &path, &store_snapshot);
|
|
155
|
+
resolved.push(resolved_stmt);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
StatementKind::Tempo => {
|
|
159
|
+
let resolved_stmt = resolve_tempo(&stmt, &module, &path, &store_snapshot);
|
|
160
|
+
resolved.push(resolved_stmt);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
StatementKind::Import { .. } | StatementKind::Export { .. } => {
|
|
164
|
+
resolved.push(stmt.clone());
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
StatementKind::Group => {
|
|
168
|
+
let resolved_stmt = resolve_group(&stmt, &module, &path, &store_snapshot);
|
|
169
|
+
resolved.push(resolved_stmt);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
_ => {
|
|
173
|
+
resolved.push(stmt);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
resolved_map.insert(path.clone(), resolved);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
resolved_map
|
|
182
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
use std::collections::HashMap;
|
|
2
|
+
|
|
3
|
+
use crate::{
|
|
4
|
+
core::{
|
|
5
|
+
parser::statement::{ Statement, StatementKind },
|
|
6
|
+
preprocessor::{ module::Module, resolver::{condition::resolve_condition, trigger::resolve_trigger} },
|
|
7
|
+
shared::value::Value,
|
|
8
|
+
store::global::GlobalStore,
|
|
9
|
+
},
|
|
10
|
+
utils::logger::Logger,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
pub fn resolve_group(
|
|
14
|
+
stmt: &Statement,
|
|
15
|
+
module: &Module,
|
|
16
|
+
path: &str,
|
|
17
|
+
global_store: &GlobalStore
|
|
18
|
+
) -> Statement {
|
|
19
|
+
let logger = Logger::new();
|
|
20
|
+
|
|
21
|
+
let Value::Map(value_map) = &stmt.value else {
|
|
22
|
+
return type_error(&logger, module, stmt, "Expected a map for group statement".to_string());
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
let group_name = match value_map.get("identifier") {
|
|
26
|
+
Some(Value::String(name)) => name.clone(),
|
|
27
|
+
Some(other) => {
|
|
28
|
+
return type_error(
|
|
29
|
+
&logger,
|
|
30
|
+
module,
|
|
31
|
+
stmt,
|
|
32
|
+
format!("Group name must be a string, found {:?}", other)
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
None => {
|
|
36
|
+
return type_error(&logger, module, stmt, "Group name is required".to_string());
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
let resolved_body = match value_map.get("body") {
|
|
41
|
+
Some(Value::Block(statements)) => {
|
|
42
|
+
let mut resolved = Vec::new();
|
|
43
|
+
|
|
44
|
+
for stmt in statements {
|
|
45
|
+
match &stmt.kind {
|
|
46
|
+
StatementKind::Trigger { entity, duration } => {
|
|
47
|
+
let resolved_trigger = resolve_trigger(
|
|
48
|
+
&mut stmt.clone(),
|
|
49
|
+
entity,
|
|
50
|
+
&mut duration.clone(),
|
|
51
|
+
module,
|
|
52
|
+
path,
|
|
53
|
+
global_store
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
resolved.push(resolved_trigger);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
StatementKind::If => {
|
|
60
|
+
let resolved_condition = resolve_condition(
|
|
61
|
+
&mut stmt.clone(),
|
|
62
|
+
module,
|
|
63
|
+
path,
|
|
64
|
+
global_store
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
resolved.push(resolved_condition);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
_ => {
|
|
71
|
+
println!("Unhandled group body statement: {:?}", stmt);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
Value::Block(resolved)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
Some(other) => {
|
|
80
|
+
return type_error(
|
|
81
|
+
&logger,
|
|
82
|
+
module,
|
|
83
|
+
stmt,
|
|
84
|
+
format!("Unexpected value for group body: {:?}", other)
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
None => {
|
|
89
|
+
return type_error(
|
|
90
|
+
&logger,
|
|
91
|
+
module,
|
|
92
|
+
stmt,
|
|
93
|
+
"Missing 'body' key in group statement".to_string()
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
let mut resolved_map = HashMap::new();
|
|
99
|
+
resolved_map.insert("identifier".to_string(), Value::String(group_name));
|
|
100
|
+
resolved_map.insert("body".to_string(), resolved_body);
|
|
101
|
+
|
|
102
|
+
Statement {
|
|
103
|
+
kind: StatementKind::Group,
|
|
104
|
+
value: Value::Map(resolved_map),
|
|
105
|
+
..stmt.clone()
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
fn type_error(logger: &Logger, module: &Module, stmt: &Statement, message: String) -> Statement {
|
|
110
|
+
let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
|
|
111
|
+
logger.log_error_with_stacktrace(&message, &stacktrace);
|
|
112
|
+
|
|
113
|
+
Statement {
|
|
114
|
+
kind: StatementKind::Error { message },
|
|
115
|
+
value: Value::Null,
|
|
116
|
+
..stmt.clone()
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
use std::collections::HashMap;
|
|
2
|
+
|
|
1
3
|
use crate::{
|
|
2
4
|
core::{
|
|
3
5
|
parser::statement::{ Statement, StatementKind },
|
|
@@ -16,9 +18,7 @@ pub fn resolve_loop(
|
|
|
16
18
|
) -> Statement {
|
|
17
19
|
let logger = Logger::new();
|
|
18
20
|
|
|
19
|
-
// Vérifie que stmt.value est bien une Map
|
|
20
21
|
if let Value::Map(value_map) = &stmt.value {
|
|
21
|
-
// Résolution de l'iterator
|
|
22
22
|
let iterator_value = match value_map.get("iterator") {
|
|
23
23
|
Some(Value::Identifier(ident)) => {
|
|
24
24
|
match module.variable_table.get(ident) {
|
|
@@ -69,7 +69,6 @@ pub fn resolve_loop(
|
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
-
// Résolution du body
|
|
73
72
|
let body_value = match value_map.get("body") {
|
|
74
73
|
Some(Value::Block(block)) => {
|
|
75
74
|
let mut resolved_block = Vec::new();
|
|
@@ -113,12 +112,10 @@ pub fn resolve_loop(
|
|
|
113
112
|
}
|
|
114
113
|
};
|
|
115
114
|
|
|
116
|
-
|
|
117
|
-
let mut resolved_map = std::collections::HashMap::new();
|
|
115
|
+
let mut resolved_map = HashMap::new();
|
|
118
116
|
resolved_map.insert("iterator".to_string(), iterator_value);
|
|
119
117
|
resolved_map.insert("body".to_string(), body_value);
|
|
120
118
|
|
|
121
|
-
// ✅ Reconstruit le StatementLoop à partir des éléments résolus
|
|
122
119
|
Statement {
|
|
123
120
|
kind: StatementKind::Loop,
|
|
124
121
|
value: Value::Map(resolved_map),
|
|
@@ -1,151 +1,10 @@
|
|
|
1
|
+
pub mod driver;
|
|
2
|
+
|
|
1
3
|
pub mod trigger;
|
|
2
4
|
pub mod loop_;
|
|
3
5
|
pub mod bank;
|
|
4
6
|
pub mod tempo;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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 },
|
|
22
|
-
},
|
|
23
|
-
utils::logger::Logger,
|
|
24
|
-
};
|
|
25
|
-
|
|
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
|
-
}
|
|
31
|
-
|
|
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
|
-
}
|
|
45
|
-
} else {
|
|
46
|
-
println!(
|
|
47
|
-
"[warn] '{module_path}': cannot find source module '{source_path}'"
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
_ => {
|
|
52
|
-
println!(
|
|
53
|
-
"[warn] '{module_path}': expected string for import source, found {:?}",
|
|
54
|
-
source_path
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
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();
|
|
67
|
-
|
|
68
|
-
// 1. Imports resolution
|
|
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
|
-
);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
} else {
|
|
91
|
-
logger.log_error_with_stacktrace(
|
|
92
|
-
&format!("Expected string for import source, found {:?}", source_path),
|
|
93
|
-
module_path
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// 2. Statements resolution
|
|
100
|
-
let mut resolved_map: HashMap<String, Vec<Statement>> = HashMap::new();
|
|
101
|
-
let store_snapshot = global_store.clone();
|
|
102
|
-
|
|
103
|
-
for (path, module) in &store_snapshot.modules {
|
|
104
|
-
let mut resolved = Vec::new();
|
|
105
|
-
|
|
106
|
-
for stmt in &module.statements {
|
|
107
|
-
let mut stmt = stmt.clone();
|
|
108
|
-
|
|
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
|
-
}
|
|
121
|
-
|
|
122
|
-
StatementKind::Loop => {
|
|
123
|
-
let resolved_stmt = resolve_loop(&stmt, &module, &path, &store_snapshot);
|
|
124
|
-
resolved.push(resolved_stmt);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
StatementKind::Bank => {
|
|
128
|
-
let resolved_stmt = resolve_bank(&stmt, &module, &path, &store_snapshot);
|
|
129
|
-
resolved.push(resolved_stmt);
|
|
130
|
-
}
|
|
131
|
-
|
|
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
|
-
resolved.push(stmt.clone());
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
_ => {
|
|
142
|
-
resolved.push(stmt);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
resolved_map.insert(path.clone(), resolved);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
resolved_map
|
|
151
|
-
}
|
|
7
|
+
pub mod group;
|
|
8
|
+
pub mod condition;
|
|
9
|
+
pub mod spawn;
|
|
10
|
+
pub mod call;
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
};
|
|
10
|
+
|
|
11
|
+
pub fn resolve_spawn(
|
|
12
|
+
stmt: &Statement,
|
|
13
|
+
module: &Module,
|
|
14
|
+
_path: &str,
|
|
15
|
+
_global_store: &GlobalStore,
|
|
16
|
+
) -> Statement {
|
|
17
|
+
let logger = Logger::new();
|
|
18
|
+
|
|
19
|
+
let Value::String(name) = &stmt.value else {
|
|
20
|
+
return type_error(&logger, module, stmt, "Spawn expects a group name as string.".to_string());
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
match module.variable_table.variables.get(name) {
|
|
24
|
+
Some(Value::Map(group_stmt)) => Statement {
|
|
25
|
+
kind: StatementKind::Spawn,
|
|
26
|
+
value: Value::Map(group_stmt.clone()),
|
|
27
|
+
..stmt.clone()
|
|
28
|
+
},
|
|
29
|
+
Some(other) => type_error(
|
|
30
|
+
&logger,
|
|
31
|
+
module,
|
|
32
|
+
stmt,
|
|
33
|
+
format!("Expected a group for '{}', but found {:?}", name, other),
|
|
34
|
+
),
|
|
35
|
+
None => type_error(
|
|
36
|
+
&logger,
|
|
37
|
+
module,
|
|
38
|
+
stmt,
|
|
39
|
+
format!("Group '{}' not found in module '{}'", name, module.path),
|
|
40
|
+
),
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fn type_error(logger: &Logger, module: &Module, stmt: &Statement, message: String) -> Statement {
|
|
45
|
+
let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
|
|
46
|
+
logger.log_error_with_stacktrace(&message, &stacktrace);
|
|
47
|
+
|
|
48
|
+
Statement {
|
|
49
|
+
kind: StatementKind::Error { message },
|
|
50
|
+
value: Value::Null,
|
|
51
|
+
..stmt.clone()
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -38,7 +38,6 @@ pub fn resolve_trigger(
|
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
// ✅ Résolution de duration si c'est un identifiant
|
|
42
41
|
if let Duration::Identifier(ident) = duration {
|
|
43
42
|
if let Some(val) = module.variable_table.get(ident) {
|
|
44
43
|
match val {
|
|
@@ -56,7 +55,6 @@ pub fn resolve_trigger(
|
|
|
56
55
|
}
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
// ✅ Résolution de value (params, effets)
|
|
60
58
|
final_value = match &stmt.value {
|
|
61
59
|
Value::Identifier(ident) => {
|
|
62
60
|
match module.variable_table.get(ident) {
|
|
@@ -87,7 +85,6 @@ pub fn resolve_trigger(
|
|
|
87
85
|
other => other.clone(),
|
|
88
86
|
};
|
|
89
87
|
|
|
90
|
-
// ✅ On reconstruit le Statement avec Trigger résolu
|
|
91
88
|
if let StatementKind::Trigger { entity, .. } = &stmt.kind {
|
|
92
89
|
return Statement {
|
|
93
90
|
kind: StatementKind::Trigger {
|
package/rust/lib.rs
CHANGED
package/rust/main.rs
CHANGED