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

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 (168) hide show
  1. package/.devalang +9 -0
  2. package/Cargo.toml +15 -6
  3. package/README.md +79 -81
  4. package/docs/CHANGELOG.md +213 -0
  5. package/docs/ROADMAP.md +11 -8
  6. package/docs/TODO.md +32 -29
  7. package/examples/bank.deva +9 -0
  8. package/examples/condition.deva +20 -0
  9. package/examples/duration.deva +9 -0
  10. package/examples/group.deva +12 -0
  11. package/examples/index.deva +12 -5
  12. package/examples/loop.deva +16 -0
  13. package/examples/samples/hat-808.wav +0 -0
  14. package/examples/synth.deva +14 -0
  15. package/examples/variables.deva +9 -0
  16. package/out-tsc/bin/devalang.exe +0 -0
  17. package/out-tsc/scripts/version/fetch.js +1 -5
  18. package/package.json +5 -4
  19. package/project-version.json +3 -3
  20. package/rust/cli/bank.rs +455 -0
  21. package/rust/cli/build.rs +114 -28
  22. package/rust/cli/check.rs +96 -103
  23. package/rust/cli/driver.rs +280 -0
  24. package/rust/cli/init.rs +79 -0
  25. package/rust/cli/install.rs +17 -0
  26. package/rust/cli/mod.rs +8 -1
  27. package/rust/cli/play.rs +193 -0
  28. package/rust/cli/template.rs +57 -0
  29. package/rust/cli/update.rs +4 -0
  30. package/rust/common/cdn.rs +11 -0
  31. package/rust/common/mod.rs +1 -0
  32. package/rust/config/driver.rs +76 -0
  33. package/rust/config/loader.rs +110 -0
  34. package/rust/config/mod.rs +2 -0
  35. package/rust/core/audio/engine.rs +242 -0
  36. package/rust/core/audio/evaluator.rs +31 -0
  37. package/rust/core/audio/interpreter/arrow_call.rs +142 -0
  38. package/rust/core/audio/interpreter/call.rs +70 -0
  39. package/rust/core/audio/interpreter/condition.rs +69 -0
  40. package/rust/core/audio/interpreter/driver.rs +236 -0
  41. package/rust/core/audio/interpreter/let_.rs +19 -0
  42. package/rust/core/audio/interpreter/load.rs +18 -0
  43. package/rust/core/audio/interpreter/loop_.rs +67 -0
  44. package/rust/core/audio/interpreter/mod.rs +12 -0
  45. package/rust/core/audio/interpreter/sleep.rs +36 -0
  46. package/rust/core/audio/interpreter/spawn.rs +84 -0
  47. package/rust/core/audio/interpreter/tempo.rs +16 -0
  48. package/rust/core/audio/interpreter/trigger.rs +102 -0
  49. package/rust/core/audio/loader/mod.rs +1 -0
  50. package/rust/core/audio/loader/trigger.rs +64 -0
  51. package/rust/core/audio/mod.rs +6 -0
  52. package/rust/core/audio/player.rs +54 -0
  53. package/rust/core/audio/renderer.rs +54 -0
  54. package/rust/core/builder/mod.rs +70 -27
  55. package/rust/core/debugger/lexer.rs +27 -0
  56. package/rust/core/debugger/mod.rs +13 -49
  57. package/rust/core/debugger/preprocessor.rs +27 -0
  58. package/rust/core/debugger/store.rs +25 -0
  59. package/rust/core/error/mod.rs +60 -0
  60. package/rust/core/lexer/handler/arrow.rs +31 -0
  61. package/rust/core/lexer/handler/at.rs +21 -0
  62. package/rust/core/lexer/handler/brace.rs +41 -0
  63. package/rust/core/lexer/handler/colon.rs +21 -0
  64. package/rust/core/lexer/handler/comment.rs +30 -0
  65. package/rust/core/lexer/handler/dot.rs +21 -0
  66. package/rust/core/lexer/handler/driver.rs +241 -0
  67. package/rust/core/lexer/handler/identifier.rs +41 -0
  68. package/rust/core/lexer/handler/indent.rs +52 -0
  69. package/rust/core/lexer/handler/mod.rs +15 -0
  70. package/rust/core/lexer/handler/newline.rs +23 -0
  71. package/rust/core/lexer/handler/number.rs +31 -0
  72. package/rust/core/lexer/handler/operator.rs +44 -0
  73. package/rust/core/lexer/handler/slash.rs +21 -0
  74. package/rust/core/lexer/handler/string.rs +63 -0
  75. package/rust/core/lexer/mod.rs +37 -319
  76. package/rust/core/lexer/token.rs +87 -0
  77. package/rust/core/mod.rs +6 -2
  78. package/rust/core/parser/driver.rs +339 -0
  79. package/rust/core/parser/handler/arrow_call.rs +151 -0
  80. package/rust/core/parser/handler/at.rs +162 -0
  81. package/rust/core/parser/handler/bank.rs +41 -0
  82. package/rust/core/parser/handler/condition.rs +74 -0
  83. package/rust/core/parser/handler/dot.rs +178 -0
  84. package/rust/core/parser/handler/identifier/call.rs +41 -0
  85. package/rust/core/parser/handler/identifier/group.rs +75 -0
  86. package/rust/core/parser/handler/identifier/let_.rs +133 -0
  87. package/rust/core/parser/handler/identifier/mod.rs +51 -0
  88. package/rust/core/parser/handler/identifier/sleep.rs +33 -0
  89. package/rust/core/parser/handler/identifier/spawn.rs +41 -0
  90. package/rust/core/parser/handler/identifier/synth.rs +65 -0
  91. package/rust/core/parser/handler/loop_.rs +72 -0
  92. package/rust/core/parser/handler/mod.rs +8 -0
  93. package/rust/core/parser/handler/tempo.rs +47 -0
  94. package/rust/core/parser/mod.rs +3 -200
  95. package/rust/core/parser/statement.rs +96 -0
  96. package/rust/core/preprocessor/loader.rs +308 -0
  97. package/rust/core/preprocessor/mod.rs +2 -24
  98. package/rust/core/preprocessor/module.rs +42 -56
  99. package/rust/core/preprocessor/processor.rs +76 -0
  100. package/rust/core/preprocessor/resolver/bank.rs +41 -51
  101. package/rust/core/preprocessor/resolver/call.rs +123 -0
  102. package/rust/core/preprocessor/resolver/condition.rs +92 -0
  103. package/rust/core/preprocessor/resolver/driver.rs +232 -0
  104. package/rust/core/preprocessor/resolver/group.rs +61 -0
  105. package/rust/core/preprocessor/resolver/let_.rs +31 -0
  106. package/rust/core/preprocessor/resolver/loop_.rs +76 -67
  107. package/rust/core/preprocessor/resolver/mod.rs +12 -111
  108. package/rust/core/preprocessor/resolver/spawn.rs +58 -0
  109. package/rust/core/preprocessor/resolver/synth.rs +50 -0
  110. package/rust/core/preprocessor/resolver/tempo.rs +40 -61
  111. package/rust/core/preprocessor/resolver/trigger.rs +90 -154
  112. package/rust/core/preprocessor/resolver/value.rs +78 -0
  113. package/rust/core/shared/bank.rs +21 -0
  114. package/rust/core/shared/duration.rs +9 -0
  115. package/rust/core/shared/mod.rs +3 -0
  116. package/rust/core/shared/value.rs +29 -0
  117. package/rust/core/store/export.rs +28 -0
  118. package/rust/core/store/global.rs +39 -0
  119. package/rust/core/store/import.rs +28 -0
  120. package/rust/core/store/mod.rs +4 -0
  121. package/rust/core/store/variable.rs +28 -0
  122. package/rust/core/utils/mod.rs +2 -0
  123. package/rust/core/utils/path.rs +31 -0
  124. package/rust/core/utils/validation.rs +37 -0
  125. package/rust/installer/bank.rs +55 -0
  126. package/rust/installer/mod.rs +1 -0
  127. package/rust/lib.rs +162 -1
  128. package/rust/main.rs +104 -31
  129. package/rust/utils/file.rs +35 -0
  130. package/rust/utils/installer.rs +56 -0
  131. package/rust/utils/logger.rs +108 -34
  132. package/rust/utils/mod.rs +5 -3
  133. package/rust/utils/{loader.rs → spinner.rs} +2 -0
  134. package/rust/utils/watcher.rs +33 -0
  135. package/templates/minimal/.devalang +5 -0
  136. package/templates/minimal/README.md +202 -0
  137. package/templates/minimal/src/index.deva +2 -0
  138. package/templates/welcome/.devalang +5 -0
  139. package/templates/welcome/README.md +202 -0
  140. package/templates/welcome/samples/kick-808.wav +0 -0
  141. package/templates/welcome/src/index.deva +13 -0
  142. package/templates/welcome/src/variables.deva +5 -0
  143. package/typescript/scripts/version/fetch.ts +1 -6
  144. package/docs/COMMANDS.md +0 -31
  145. package/docs/SYNTAX.md +0 -148
  146. package/examples/exported.deva +0 -7
  147. package/rust/audio/mod.rs +0 -1
  148. package/rust/cli/new.rs +0 -1
  149. package/rust/core/parser/at.rs +0 -142
  150. package/rust/core/parser/bank.rs +0 -42
  151. package/rust/core/parser/dot.rs +0 -107
  152. package/rust/core/parser/identifer.rs +0 -91
  153. package/rust/core/parser/loop_.rs +0 -62
  154. package/rust/core/parser/tempo.rs +0 -42
  155. package/rust/core/parser/variable.rs +0 -129
  156. package/rust/core/preprocessor/dependencies.rs +0 -54
  157. package/rust/core/preprocessor/resolver/at.rs +0 -24
  158. package/rust/core/types/cli.rs +0 -160
  159. package/rust/core/types/mod.rs +0 -7
  160. package/rust/core/types/module.rs +0 -41
  161. package/rust/core/types/parser.rs +0 -73
  162. package/rust/core/types/statement.rs +0 -105
  163. package/rust/core/types/store.rs +0 -116
  164. package/rust/core/types/token.rs +0 -83
  165. package/rust/core/types/variable.rs +0 -32
  166. package/rust/runner/executer.rs +0 -44
  167. package/rust/runner/mod.rs +0 -1
  168. package/rust/utils/path.rs +0 -46
@@ -1,82 +1,91 @@
1
- use crate::core::{
2
- parser::parse_without_resolving_with_module,
3
- preprocessor::resolver::resolve_statement,
4
- types::{
5
- module::Module,
6
- statement::{
7
- Statement,
8
- StatementIterator,
9
- StatementKind,
10
- StatementResolved,
11
- StatementResolvedValue,
1
+ use std::collections::HashMap;
2
+
3
+ use crate::{
4
+ core::{
5
+ parser::statement::{ Statement, StatementKind },
6
+ preprocessor::{
7
+ module::Module,
8
+ resolver::{ driver::resolve_statement, value::resolve_value },
12
9
  },
13
- variable::VariableValue,
10
+ shared::value::Value,
11
+ store::global::GlobalStore,
14
12
  },
13
+ utils::logger::Logger,
15
14
  };
16
15
 
17
- pub fn resolve_loop_statement(
18
- loop_statement: &Statement,
19
- iterator: StatementIterator,
20
- module: &Module
21
- ) -> StatementResolved {
22
- let mut resolved_iterator = StatementIterator::Unknown;
16
+ pub fn resolve_loop(
17
+ stmt: &Statement,
18
+ module: &Module,
19
+ path: &str,
20
+ global_store: &mut GlobalStore
21
+ ) -> Statement {
22
+ let logger = Logger::new();
23
23
 
24
- match iterator.clone() {
25
- StatementIterator::Identifier(id) => {
26
- if let Some(value) = module.variable_table.variables.get(&id) {
27
- match value {
28
- VariableValue::Array(arr) => {
29
- resolved_iterator = StatementIterator::Array(
30
- parse_without_resolving_with_module(arr.clone(), module)
31
- );
32
- }
33
- VariableValue::Number(num) => {
34
- resolved_iterator = StatementIterator::Number(*num);
35
- }
36
- _ => {
37
- eprintln!("⚠️ Unsupported variable type for loop iterator: {:?}", value);
38
- resolved_iterator = StatementIterator::Unknown;
39
- }
40
- }
41
- } else {
42
- eprintln!("⚠️ Loop iterator variable '{}' not found", id);
43
- resolved_iterator = StatementIterator::Unknown;
44
- }
45
- }
46
- StatementIterator::Number(num) => {
47
- resolved_iterator = StatementIterator::Number(num);
48
- }
49
- _ => {
50
- resolved_iterator = iterator.clone();
51
- }
52
- }
24
+ let resolved_value = resolve_value(&stmt.value, module, global_store);
53
25
 
54
- let mut resolved_body: StatementResolvedValue = StatementResolvedValue::Unknown;
55
-
56
- match &loop_statement.value {
57
- VariableValue::Array(arr) => {
58
- let raw_statements = parse_without_resolving_with_module(arr.clone(), &module.clone());
26
+ let Value::Map(value_map) = &resolved_value else {
27
+ return error_stmt(&logger, module, stmt, "Expected a map for loop value");
28
+ };
59
29
 
60
- let mut resolved_statements = Vec::new();
30
+ let mut resolved_map: HashMap<String, Value> = HashMap::new();
31
+ for (key, val) in value_map {
32
+ resolved_map.insert(key.clone(), resolve_value(val, module, global_store));
33
+ }
61
34
 
62
- for raw_stmt in raw_statements {
63
- let resolved_stmt = resolve_statement(&raw_stmt, &mut module.clone());
64
- resolved_statements.push(resolved_stmt);
65
- }
35
+ let iterator_value = match resolved_map.get("iterator") {
36
+ Some(Value::Number(n)) => Value::Number(*n),
37
+ Some(other) => {
38
+ error_value(
39
+ &logger,
40
+ module,
41
+ stmt,
42
+ &format!("Loop iterator must be a number, found: {:?}", other)
43
+ );
44
+ Value::Number(1.0)
45
+ }
46
+ None => {
47
+ error_value(&logger, module, stmt, "Missing 'iterator' in loop");
48
+ Value::Number(1.0)
49
+ }
50
+ };
66
51
 
67
- resolved_body = StatementResolvedValue::Array(resolved_statements);
52
+ let body_value = match resolved_map.remove("body") {
53
+ Some(Value::Block(stmts)) => {
54
+ let resolved = stmts
55
+ .iter()
56
+ .map(|s| resolve_statement(s, module, path, global_store))
57
+ .collect();
58
+ Value::Block(resolved)
68
59
  }
69
60
  _ => {
70
- resolved_body = StatementResolvedValue::Unknown;
71
- eprintln!("⚠️ Unsupported value type for loop body: {:?}", loop_statement.value);
61
+ error_value(&logger, module, stmt, "Invalid or missing loop body");
62
+ Value::Block(vec![])
72
63
  }
64
+ };
65
+
66
+ let mut final_map = HashMap::new();
67
+ final_map.insert("iterator".to_string(), iterator_value);
68
+ final_map.insert("body".to_string(), body_value);
69
+
70
+ Statement {
71
+ kind: StatementKind::Loop,
72
+ value: Value::Map(final_map),
73
+ ..stmt.clone()
73
74
  }
75
+ }
74
76
 
75
- return StatementResolved {
76
- kind: StatementKind::Loop { iterator: resolved_iterator },
77
- value: resolved_body,
78
- indent: loop_statement.indent,
79
- line: loop_statement.line,
80
- column: loop_statement.column,
81
- };
77
+ fn error_value(logger: &Logger, module: &Module, stmt: &Statement, msg: &str) {
78
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
79
+ logger.log_error_with_stacktrace(msg, &stacktrace);
80
+ }
81
+
82
+ fn error_stmt(logger: &Logger, module: &Module, stmt: &Statement, msg: &str) -> Statement {
83
+ error_value(logger, module, stmt, msg);
84
+ Statement {
85
+ kind: StatementKind::Error {
86
+ message: msg.to_string(),
87
+ },
88
+ value: Value::Null,
89
+ ..stmt.clone()
90
+ }
82
91
  }
@@ -1,113 +1,14 @@
1
- pub mod bank;
2
- pub mod loop_;
3
- 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,
21
- },
22
- };
23
-
24
- pub fn resolve_exports(statements: &[Statement], parser: &Parser) -> ExportTable {
25
- let mut export_table = parser.export_table.clone();
26
-
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());
34
- } else {
35
- eprintln!("⚠️ Variable '{}' not found in scope, export skipped", var_name);
36
- }
37
- }
38
- } else {
39
- eprintln!("⚠️ Unexpected value type in export: {:?}", stmt.value);
40
- }
41
- }
42
- }
43
-
44
- export_table
45
- }
46
-
47
- pub fn resolve_imports(module: &mut Module, global_store: &GlobalStore) -> ImportTable {
48
- let mut import_table = ImportTable::default();
49
-
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);
59
- }
60
- }
61
- } else {
62
- eprintln!("⚠️ Module '{}' not found", source);
63
- }
64
- }
65
- }
66
-
67
- import_table
68
- }
1
+ pub mod driver;
69
2
 
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
- }
3
+ pub mod value;
75
4
 
76
- StatementKind::Trigger { entity, duration } => {
77
- resolve_trigger_statement(stmt, entity.clone(), duration.clone(), module)
78
- }
79
-
80
- StatementKind::Bank { .. } => { resolve_bank_statement(stmt, module) }
81
-
82
- StatementKind::Tempo { .. } => { resolve_tempo_statement(stmt, module) }
83
-
84
- StatementKind::Load { source, alias } => {
85
- resolve_load_statement(stmt, source, alias, module)
86
- }
87
-
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
- }
102
-
103
- _ => {
104
- StatementResolved {
105
- kind: StatementKind::Unknown,
106
- value: StatementResolvedValue::Unknown,
107
- indent: stmt.indent,
108
- line: stmt.line,
109
- column: stmt.column,
110
- }
111
- }
112
- }
113
- }
5
+ pub mod trigger;
6
+ pub mod loop_;
7
+ pub mod bank;
8
+ pub mod tempo;
9
+ pub mod group;
10
+ pub mod condition;
11
+ pub mod spawn;
12
+ pub mod call;
13
+ pub mod synth;
14
+ pub mod let_;
@@ -0,0 +1,58 @@
1
+ use crate::{
2
+ core::{
3
+ parser::statement::{ Statement, StatementKind },
4
+ preprocessor::{
5
+ module::Module,
6
+ resolver::driver::resolve_statement,
7
+ resolver::value::resolve_value,
8
+ },
9
+ shared::value::Value,
10
+ store::global::GlobalStore,
11
+ },
12
+ utils::logger::{ Logger, LogLevel },
13
+ };
14
+
15
+ pub fn resolve_spawn(
16
+ stmt: &Statement,
17
+ module: &Module,
18
+ path: &str,
19
+ global_store: &mut GlobalStore
20
+ ) -> Statement {
21
+ let logger = Logger::new();
22
+
23
+ let resolved_value = resolve_value(&stmt.value, module, global_store);
24
+
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
+ }
34
+
35
+ Statement {
36
+ kind: StatementKind::Spawn,
37
+ value: Value::Map(map),
38
+ ..stmt.clone()
39
+ }
40
+ }
41
+
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()
55
+ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,50 @@
1
+ use crate::{
2
+ core::{
3
+ parser::statement::{ Statement, StatementKind },
4
+ preprocessor::{ module::Module, resolver::driver::resolve_statement },
5
+ shared::value::Value,
6
+ store::global::GlobalStore,
7
+ },
8
+ utils::logger::{ LogLevel, Logger },
9
+ };
10
+
11
+ pub fn resolve_synth(
12
+ stmt: &Statement,
13
+ module: &Module,
14
+ path: &str,
15
+ global_store: &mut GlobalStore
16
+ ) -> Statement {
17
+ let logger = Logger::new();
18
+
19
+ let Value::Map(synth_map) = &stmt.value else {
20
+ return type_error(&logger, module, stmt, "Expected a map in synth statement".to_string());
21
+ };
22
+
23
+ let mut resolved_map = synth_map.clone();
24
+
25
+ if let Some(Value::Block(body)) = synth_map.get("body") {
26
+ let resolved_body = body.iter()
27
+ .map(|s| resolve_statement(s, module, path, global_store))
28
+ .collect::<Vec<_>>();
29
+ resolved_map.insert("body".to_string(), Value::Block(resolved_body));
30
+ } else {
31
+ logger.log_message(LogLevel::Warning, "synth without a body");
32
+ }
33
+
34
+ Statement {
35
+ kind: StatementKind::Synth,
36
+ value: Value::Map(resolved_map),
37
+ ..stmt.clone()
38
+ }
39
+ }
40
+
41
+ fn type_error(logger: &Logger, module: &Module, stmt: &Statement, message: String) -> Statement {
42
+ let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
43
+ logger.log_error_with_stacktrace(&message, &stacktrace);
44
+
45
+ Statement {
46
+ kind: StatementKind::Error { message },
47
+ value: Value::Null,
48
+ ..stmt.clone()
49
+ }
50
+ }
@@ -1,70 +1,49 @@
1
- use crate::core::types::{module::Module, statement::{Statement, StatementKind, StatementResolved, StatementResolvedValue}, variable::VariableValue};
1
+ use crate::{
2
+ core::{
3
+ parser::statement::{ Statement, StatementKind },
4
+ preprocessor::module::Module,
5
+ shared::value::Value,
6
+ store::global::GlobalStore,
7
+ },
8
+ utils::logger::Logger,
9
+ };
2
10
 
3
- pub fn resolve_tempo_statement(
4
- tempo_statement: &Statement,
5
- module: &Module
6
- ) -> StatementResolved {
7
- match &tempo_statement.value {
8
- VariableValue::Number(num) => {
9
- if *num > 0.0 {
10
- StatementResolved {
11
- kind: StatementKind::Tempo,
12
- value: StatementResolvedValue::Number(*num),
13
- indent: tempo_statement.indent,
14
- line: tempo_statement.line,
15
- column: tempo_statement.column,
16
- }
11
+ pub fn resolve_tempo(
12
+ stmt: &Statement,
13
+ module: &Module,
14
+ path: &str,
15
+ _global_store: &GlobalStore
16
+ ) -> Statement {
17
+ let mut new_stmt = stmt.clone();
18
+ let logger = Logger::new();
19
+
20
+ match &stmt.value {
21
+ Value::Identifier(ident) => {
22
+ if let Some(val) = module.variable_table.get(ident) {
23
+ new_stmt.value = val.clone();
17
24
  } else {
18
- eprintln!("⚠️ Invalid tempo value: {}", num);
19
- StatementResolved {
20
- kind: StatementKind::Tempo,
21
- value: StatementResolvedValue::Unknown,
22
- indent: tempo_statement.indent,
23
- line: tempo_statement.line,
24
- column: tempo_statement.column,
25
- }
25
+ let message = format!("Tempo identifier '{ident}' not found in variable table");
26
+ logger.log_error_with_stacktrace(&message, &module.path);
27
+ new_stmt.kind = StatementKind::Error {
28
+ message,
29
+ };
30
+ new_stmt.value = Value::Null;
26
31
  }
27
32
  }
28
- VariableValue::Text(text) => {
29
- if let Some(value) = module.variable_table.variables.get(text) {
30
- let variable_value: StatementResolvedValue = match value {
31
- VariableValue::Number(num) if *num > 0.0 => {
32
- StatementResolvedValue::Number(*num)
33
- }
34
- VariableValue::Text(t) => StatementResolvedValue::String(t.clone()),
35
- _ => {
36
- eprintln!("⚠️ Unsupported variable type for Tempo: {:?}", value);
37
- StatementResolvedValue::Unknown
38
- }
39
- };
40
33
 
41
- StatementResolved {
42
- kind: StatementKind::Tempo,
43
- value: variable_value,
44
- indent: tempo_statement.indent,
45
- line: tempo_statement.line,
46
- column: tempo_statement.column,
47
- }
48
- } else {
49
- eprintln!("⚠️ Tempo variable '{}' not found", text);
50
- StatementResolved {
51
- kind: StatementKind::Tempo,
52
- value: StatementResolvedValue::Unknown,
53
- indent: tempo_statement.indent,
54
- line: tempo_statement.line,
55
- column: tempo_statement.column,
56
- }
57
- }
34
+ Value::Number(_) => {
35
+ // Already resolved, no modification needed
58
36
  }
59
- _ => {
60
- eprintln!("⚠️ Invalid value type for Tempo statement: {:?}", tempo_statement.value);
61
- StatementResolved {
62
- kind: StatementKind::Tempo,
63
- value: StatementResolvedValue::Unknown,
64
- indent: tempo_statement.indent,
65
- line: tempo_statement.line,
66
- column: tempo_statement.column,
67
- }
37
+
38
+ other => {
39
+ let message = format!("Expected a number or identifier for tempo, found {:?}", other);
40
+ logger.log_error_with_stacktrace(&message, &module.path);
41
+ new_stmt.kind = StatementKind::Error {
42
+ message: "Expected a number or identifier for tempo".to_string(),
43
+ };
44
+ new_stmt.value = Value::Null;
68
45
  }
69
46
  }
47
+
48
+ new_stmt
70
49
  }