@devaloop/devalang 0.0.1-alpha.1

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 (72) hide show
  1. package/Cargo.toml +45 -0
  2. package/LICENSE +21 -0
  3. package/README.md +161 -0
  4. package/docs/COMMANDS.md +31 -0
  5. package/docs/ROADMAP.md +27 -0
  6. package/docs/SYNTAX.md +148 -0
  7. package/docs/TODO.md +66 -0
  8. package/examples/exported.deva +7 -0
  9. package/examples/index.deva +9 -0
  10. package/examples/samples/kick-808.wav +0 -0
  11. package/out-tsc/bin/devalang.exe +0 -0
  12. package/out-tsc/bin/index.js +13 -0
  13. package/out-tsc/index.js +2 -0
  14. package/out-tsc/scripts/postbuild.js +11 -0
  15. package/out-tsc/scripts/version/bump.js +52 -0
  16. package/out-tsc/scripts/version/fetch.js +34 -0
  17. package/out-tsc/scripts/version/index.js +32 -0
  18. package/out-tsc/scripts/version/sync.js +32 -0
  19. package/package.json +43 -0
  20. package/project-version.json +6 -0
  21. package/rust/audio/mod.rs +1 -0
  22. package/rust/cli/build.rs +51 -0
  23. package/rust/cli/check.rs +124 -0
  24. package/rust/cli/mod.rs +3 -0
  25. package/rust/cli/new.rs +1 -0
  26. package/rust/core/builder/mod.rs +37 -0
  27. package/rust/core/debugger/mod.rs +57 -0
  28. package/rust/core/lexer/mod.rs +333 -0
  29. package/rust/core/mod.rs +6 -0
  30. package/rust/core/parser/at.rs +142 -0
  31. package/rust/core/parser/bank.rs +42 -0
  32. package/rust/core/parser/dot.rs +107 -0
  33. package/rust/core/parser/identifer.rs +91 -0
  34. package/rust/core/parser/loop_.rs +62 -0
  35. package/rust/core/parser/mod.rs +201 -0
  36. package/rust/core/parser/tempo.rs +42 -0
  37. package/rust/core/parser/variable.rs +129 -0
  38. package/rust/core/preprocessor/dependencies.rs +54 -0
  39. package/rust/core/preprocessor/mod.rs +26 -0
  40. package/rust/core/preprocessor/module.rs +70 -0
  41. package/rust/core/preprocessor/resolver/at.rs +24 -0
  42. package/rust/core/preprocessor/resolver/bank.rs +59 -0
  43. package/rust/core/preprocessor/resolver/loop_.rs +82 -0
  44. package/rust/core/preprocessor/resolver/mod.rs +113 -0
  45. package/rust/core/preprocessor/resolver/tempo.rs +70 -0
  46. package/rust/core/preprocessor/resolver/trigger.rs +176 -0
  47. package/rust/core/types/cli.rs +160 -0
  48. package/rust/core/types/mod.rs +7 -0
  49. package/rust/core/types/module.rs +41 -0
  50. package/rust/core/types/parser.rs +73 -0
  51. package/rust/core/types/statement.rs +105 -0
  52. package/rust/core/types/store.rs +116 -0
  53. package/rust/core/types/token.rs +83 -0
  54. package/rust/core/types/variable.rs +32 -0
  55. package/rust/lib.rs +1 -0
  56. package/rust/main.rs +49 -0
  57. package/rust/runner/executer.rs +44 -0
  58. package/rust/runner/mod.rs +1 -0
  59. package/rust/utils/loader.rs +19 -0
  60. package/rust/utils/logger.rs +49 -0
  61. package/rust/utils/mod.rs +5 -0
  62. package/rust/utils/path.rs +46 -0
  63. package/rust/utils/signature.rs +17 -0
  64. package/rust/utils/version.rs +15 -0
  65. package/tsconfig.json +113 -0
  66. package/typescript/bin/index.ts +14 -0
  67. package/typescript/index.ts +1 -0
  68. package/typescript/scripts/postbuild.ts +8 -0
  69. package/typescript/scripts/version/bump.ts +45 -0
  70. package/typescript/scripts/version/fetch.ts +23 -0
  71. package/typescript/scripts/version/index.ts +26 -0
  72. package/typescript/scripts/version/sync.ts +24 -0
@@ -0,0 +1,6 @@
1
+ pub mod lexer;
2
+ pub mod parser;
3
+ pub mod preprocessor;
4
+ pub mod debugger;
5
+ pub mod builder;
6
+ pub mod types;
@@ -0,0 +1,142 @@
1
+ use crate::core::types::{
2
+ parser::Parser,
3
+ statement::{ Statement, StatementKind },
4
+ token::TokenKind,
5
+ variable::VariableValue,
6
+ };
7
+
8
+ pub fn parse_at(parser: &mut Parser) -> Result<Statement, String> {
9
+ let token = parser.peek().ok_or("Unexpected EOF")?.clone();
10
+
11
+ if token.kind != TokenKind::At {
12
+ return Err(format!("Expected '@', found {:?}", token.kind));
13
+ }
14
+
15
+ parser.next();
16
+
17
+ let identifier_token = parser.peek().ok_or("Expected identifier after '@'")?.clone();
18
+ if identifier_token.kind != TokenKind::Identifier {
19
+ return Err(format!("Expected Identifier, found {:?}", identifier_token.kind));
20
+ }
21
+
22
+ match identifier_token.lexeme.as_str() {
23
+ "export" => {
24
+ parser.next();
25
+
26
+ if let Some(next_token) = parser.peek() {
27
+ if next_token.kind == TokenKind::LBrace {
28
+ parser.next(); // Consomme le LBrace
29
+ }
30
+ }
31
+
32
+ let exportable_tokens = parser.collect_until(|t| { t.kind == TokenKind::RBrace });
33
+
34
+ exportable_tokens.iter().for_each(|t| {
35
+ let variable_value = parser.variable_table
36
+ .get(&t.lexeme)
37
+ .cloned()
38
+ .unwrap_or_else(|| VariableValue::Text(t.lexeme.clone()));
39
+
40
+ parser.export_table.exports.insert(t.lexeme.clone(), variable_value);
41
+ });
42
+
43
+ return Ok(Statement {
44
+ kind: StatementKind::Export,
45
+ value: VariableValue::Array(exportable_tokens),
46
+ indent: token.indent,
47
+ line: token.line,
48
+ column: token.column,
49
+ });
50
+ }
51
+ "import" => {
52
+ parser.next();
53
+
54
+ if let Some(next_token) = parser.peek() {
55
+ if next_token.kind == TokenKind::LBrace {
56
+ parser.next();
57
+ }
58
+ }
59
+
60
+ let importable_tokens = parser.collect_until(|t| { t.kind == TokenKind::RBrace });
61
+
62
+ parser.next();
63
+
64
+ if let Some(from_token) = parser.peek() {
65
+ if from_token.kind == TokenKind::Identifier && from_token.lexeme == "from" {
66
+ parser.next();
67
+ } else {
68
+ return Err(format!("Expected 'from', found {:?}", from_token.kind));
69
+ }
70
+ } else {
71
+ return Err("Expected 'from' after import declaration".into());
72
+ }
73
+
74
+ let source_token = parser.peek().ok_or("Expected source after 'from'")?.clone();
75
+ if source_token.kind != TokenKind::String {
76
+ return Err(format!("Expected String, found {:?}", source_token.kind));
77
+ }
78
+
79
+ let statement = Statement {
80
+ kind: StatementKind::Import {
81
+ names: importable_tokens
82
+ .iter()
83
+ .map(|t| t.lexeme.clone())
84
+ .collect(),
85
+ source: source_token.lexeme.clone(),
86
+ },
87
+ value: VariableValue::Array(importable_tokens),
88
+ indent: token.indent,
89
+ line: token.line,
90
+ column: token.column,
91
+ };
92
+
93
+ return Ok(statement);
94
+ }
95
+ "load" => {
96
+ parser.next();
97
+
98
+ let source_token = parser.peek().ok_or("Expected source after load")?.clone();
99
+ if source_token.kind != TokenKind::String {
100
+ return Err(format!("Expected String, found {:?}", source_token.kind));
101
+ }
102
+
103
+ parser.next();
104
+
105
+ let as_token = parser.peek().ok_or("Expected 'as' after load")?.clone();
106
+ if as_token.kind != TokenKind::Identifier || as_token.lexeme != "as" {
107
+ return Err(format!("Expected 'as', found {:?}", as_token.kind));
108
+ }
109
+
110
+ parser.next();
111
+
112
+ let alias_token = parser.peek().ok_or("Expected alias after load")?.clone();
113
+ if alias_token.kind != TokenKind::Identifier {
114
+ return Err(format!("Expected Identifier, found {:?}", alias_token.kind));
115
+ }
116
+
117
+ parser.next();
118
+
119
+ let statement = Statement {
120
+ kind: StatementKind::Load {
121
+ source: source_token.lexeme.clone(),
122
+ alias: alias_token.lexeme.clone(),
123
+ },
124
+ value: VariableValue::Text(alias_token.lexeme.clone()),
125
+ indent: token.indent,
126
+ line: token.line,
127
+ column: token.column,
128
+ };
129
+
130
+ return Ok(statement);
131
+ }
132
+
133
+ _ => {
134
+ return Err(
135
+ format!(
136
+ "Expected 'export', 'import' or 'load', found '{}'",
137
+ identifier_token.lexeme
138
+ )
139
+ );
140
+ }
141
+ }
142
+ }
@@ -0,0 +1,42 @@
1
+ use crate::core::types::{
2
+ parser::Parser,
3
+ statement::{ Statement, StatementKind },
4
+ store::GlobalStore,
5
+ token::TokenKind,
6
+ variable::VariableValue,
7
+ };
8
+
9
+ pub fn parse_bank(
10
+ parser: &mut Parser,
11
+ global_store: &mut GlobalStore
12
+ ) -> Result<Statement, String> {
13
+ let token = parser.peek().ok_or("Unexpected EOF")?.clone();
14
+
15
+ let mut bank_name = String::new();
16
+
17
+ if parser.next().map(|t| t.kind.clone()) != Some(TokenKind::Bank) {
18
+ return Err("Expected 'bank' keyword".to_string());
19
+ }
20
+
21
+ if let Some(token) = parser.next() {
22
+ if token.kind == TokenKind::Identifier {
23
+ bank_name = token.lexeme.clone();
24
+ } else if token.kind == TokenKind::String {
25
+ bank_name = token.lexeme.trim_matches('"').to_string();
26
+ } else if token.kind == TokenKind::Number {
27
+ bank_name = token.lexeme.clone();
28
+ } else {
29
+ return Err(format!("Expected bank name, found {:?}", token.kind));
30
+ }
31
+ } else {
32
+ return Err("Expected bank name after 'bank' keyword".to_string());
33
+ }
34
+
35
+ Ok(Statement {
36
+ kind: StatementKind::Bank,
37
+ value: VariableValue::Text(bank_name.clone()),
38
+ indent: token.indent,
39
+ line: token.line,
40
+ column: token.column,
41
+ })
42
+ }
@@ -0,0 +1,107 @@
1
+ use std::{ collections::HashMap, hash::Hash };
2
+
3
+ use crate::core::types::{
4
+ statement::{ Statement, StatementKind },
5
+ token::{ Token, TokenDuration, TokenKind, TokenParamValue },
6
+ variable::{ Variable, VariableValue },
7
+ };
8
+
9
+ pub fn parse_dot(
10
+ parser: &mut crate::core::parser::Parser,
11
+ global_store: &mut crate::core::types::store::GlobalStore
12
+ ) -> Result<crate::core::types::statement::Statement, String> {
13
+ let token = parser.peek().ok_or("Unexpected EOF")?.clone();
14
+ let mut trigger_value: String = String::from("Unknown Trigger");
15
+
16
+ if token.kind != crate::core::types::token::TokenKind::Dot {
17
+ return Err(format!("Expected Dot, found {:?}", token.kind));
18
+ }
19
+
20
+ parser.next();
21
+
22
+ let next_token = parser.peek().ok_or("Expected identifier after dot")?.clone();
23
+ if next_token.kind != crate::core::types::token::TokenKind::Identifier {
24
+ return Err(format!("Expected Identifier after Dot, found {:?}", next_token.kind));
25
+ }
26
+
27
+ parser.next();
28
+
29
+ let duration_token = parser.peek().ok_or("Expected duration after identifier")?.clone();
30
+ let mut duration = TokenDuration::Unknown;
31
+
32
+ match duration_token.lexeme.as_str() {
33
+ "auto" => {
34
+ duration = TokenDuration::Auto;
35
+ }
36
+ "infinite" => {
37
+ duration = TokenDuration::Infinite;
38
+ }
39
+ _ => {
40
+ if let Ok(num) = duration_token.lexeme.parse::<f32>() {
41
+ duration = TokenDuration::Number(num);
42
+ } else if let Ok(boolean) = duration_token.lexeme.parse::<bool>() {
43
+ duration = TokenDuration::Unknown;
44
+ } else if duration_token.kind == TokenKind::Identifier {
45
+ duration = TokenDuration::Identifier(duration_token.lexeme.clone());
46
+ } else {
47
+ return Err(format!("Invalid duration format: {}", duration_token.lexeme));
48
+ }
49
+ }
50
+ }
51
+
52
+ parser.next();
53
+
54
+ let dot_params: Vec<Token> = parser.collect_until(|t| {
55
+ t.kind == TokenKind::Newline
56
+ });
57
+
58
+ let mut params_value: VariableValue = VariableValue::Null;
59
+
60
+ for param in dot_params {
61
+ let token_value = match param.kind {
62
+ TokenKind::String => VariableValue::Text(param.lexeme),
63
+ TokenKind::Number => VariableValue::Number(param.lexeme.parse().unwrap_or(0.0)),
64
+ TokenKind::Boolean => VariableValue::Boolean(param.lexeme.parse().unwrap_or(false)),
65
+ TokenKind::Map => {
66
+ let mut map: HashMap<String, TokenParamValue> = HashMap::new();
67
+ let entries: Vec<&str> = param.lexeme.split(',').collect();
68
+ for entry in entries {
69
+ let parts: Vec<&str> = entry.split(':').collect();
70
+ if parts.len() == 2 {
71
+ let key = parts[0].trim().to_string();
72
+ let value = match parts[1].trim() {
73
+ "true" => TokenParamValue::Boolean(true),
74
+ "false" => TokenParamValue::Boolean(false),
75
+ _ => TokenParamValue::String(parts[1].trim().to_string()),
76
+ };
77
+ map.insert(key, value);
78
+ }
79
+ }
80
+ VariableValue::Map(map)
81
+ }
82
+ TokenKind::Identifier => {
83
+ VariableValue::Text(param.lexeme.clone())
84
+ }
85
+ TokenKind::Unknown => {
86
+ Err(format!("Unsupported token type in dot parameters: {:?}", param.kind))?;
87
+ VariableValue::Null
88
+ },
89
+ _ => {
90
+ Err(format!("Unsupported token type in dot parameters: {:?}", param.kind))?;
91
+ VariableValue::Unknown
92
+ },
93
+ };
94
+ params_value = token_value;
95
+ }
96
+
97
+ Ok(Statement {
98
+ kind: StatementKind::Trigger {
99
+ entity: next_token.lexeme.clone(),
100
+ duration: duration.clone(),
101
+ },
102
+ value: params_value,
103
+ indent: token.indent,
104
+ line: token.line,
105
+ column: token.column,
106
+ })
107
+ }
@@ -0,0 +1,91 @@
1
+ use crate::core::{
2
+ parser::{ bank::parse_bank, variable::parse_let_statement, Parser },
3
+ types::{
4
+ statement::{ Statement, StatementKind },
5
+ store::GlobalStore,
6
+ token::{ Token, TokenKind },
7
+ variable::VariableValue,
8
+ },
9
+ };
10
+
11
+ pub fn parse_identifier(
12
+ parser: &mut Parser,
13
+ global_store: &mut GlobalStore
14
+ ) -> Result<Statement, String> {
15
+ let token = parser.peek().ok_or("Unexpected EOF")?.clone();
16
+
17
+ if token.kind != TokenKind::Identifier {
18
+ return Err(format!("Expected Identifier, found {:?}", token.kind));
19
+ }
20
+
21
+ match token.lexeme.as_str() {
22
+ "let" => {
23
+ parser.next();
24
+ return parse_let_statement(parser);
25
+ }
26
+ "bank" => {
27
+ parser.next();
28
+ return parse_bank(parser, global_store);
29
+ }
30
+ _ => {
31
+ parser.next();
32
+ }
33
+ }
34
+
35
+ let statment_value = match token.kind {
36
+ TokenKind::Identifier => {
37
+ let var_name = &token.lexeme;
38
+ let current_module = global_store.modules
39
+ .get(&parser.current_module);
40
+ let mut variable_value = VariableValue::Unknown;
41
+
42
+ if current_module.is_none() {
43
+ return Err(format!("Module '{}' not found", parser.current_module));
44
+ } else {
45
+ variable_value = current_module.unwrap()
46
+ .variable_table
47
+ .variables
48
+ .get(var_name)
49
+ .cloned()
50
+ .unwrap_or(VariableValue::Unknown);
51
+ }
52
+
53
+ println!("Trying to get variable '{}' in module '{}'", var_name, parser.current_module);
54
+
55
+ variable_value
56
+ }
57
+ TokenKind::Number => VariableValue::Number(token.lexeme.parse().unwrap_or(0.0)),
58
+ TokenKind::String => {
59
+ let var_name = &token.lexeme;
60
+ let current_module = global_store.modules
61
+ .get(&parser.current_module);
62
+ let mut variable_value = VariableValue::Unknown;
63
+
64
+ if current_module.is_none() {
65
+ return Err(format!("Module '{}' not found", parser.current_module));
66
+ } else {
67
+ variable_value = current_module.unwrap()
68
+ .variable_table
69
+ .variables
70
+ .get(var_name)
71
+ .cloned()
72
+ .unwrap_or(VariableValue::Unknown);
73
+ }
74
+
75
+ println!("Trying to get variable '{}' in module '{}'", var_name, parser.current_module);
76
+
77
+ variable_value
78
+ }
79
+ _ => VariableValue::Unknown,
80
+ };
81
+
82
+ println!("Trying get variable : {:?}", global_store.modules);
83
+
84
+ Ok(Statement {
85
+ kind: StatementKind::Unknown,
86
+ value: statment_value,
87
+ indent: token.indent,
88
+ line: token.line,
89
+ column: token.column,
90
+ })
91
+ }
@@ -0,0 +1,62 @@
1
+ use std::{ collections::HashMap, iter };
2
+
3
+ use crate::core::types::{
4
+ statement::{ Statement, StatementIterator, StatementKind },
5
+ token::{ Token, TokenDuration, TokenKind, TokenParamValue },
6
+ variable::VariableValue,
7
+ };
8
+
9
+ pub fn parse_loop(
10
+ parser: &mut crate::core::parser::Parser,
11
+ global_store: &mut crate::core::types::store::GlobalStore
12
+ ) -> Result<crate::core::types::statement::Statement, String> {
13
+ let token = parser.peek().ok_or("Unexpected EOF")?.clone();
14
+
15
+ parser.next();
16
+
17
+ let mut iterator = StatementIterator::Unknown;
18
+
19
+ let iterable_tokens: Vec<Token> = parser.collect_until(|t| { t.kind == TokenKind::Colon });
20
+
21
+ iterable_tokens.iter().for_each(|t| {
22
+ match t.kind {
23
+ TokenKind::Identifier => {
24
+ iterator = StatementIterator::Identifier(t.lexeme.clone());
25
+ }
26
+ TokenKind::Number => {
27
+ if let Ok(num) = t.lexeme.parse::<f32>() {
28
+ iterator = StatementIterator::Number(num);
29
+ } else {
30
+ eprintln!("⚠️ Invalid number in loop iterator: {}", t.lexeme);
31
+ }
32
+ }
33
+ TokenKind::Array => {
34
+ println!("🔍 Parsing array in loop iterator: {:?}", t.lexeme);
35
+ iterator = StatementIterator::Array(vec![]);
36
+ }
37
+ TokenKind::Map => {
38
+ println!("🔍 Parsing map in loop iterator: {:?}", t.lexeme);
39
+ iterator = StatementIterator::Map(HashMap::new());
40
+ }
41
+ _ => {
42
+ eprintln!("⚠️ Unsupported token type in loop iterator: {:?}", t.kind);
43
+ }
44
+ }
45
+ });
46
+
47
+ parser.next();
48
+
49
+ let loop_body_tokens: Vec<Token> = parser.collect_until(|t| { t.kind == TokenKind::Dedent });
50
+
51
+ let loop_statement = Statement {
52
+ kind: StatementKind::Loop {
53
+ iterator,
54
+ },
55
+ value: VariableValue::Array(loop_body_tokens),
56
+ line: token.line,
57
+ column: token.column,
58
+ indent: token.indent,
59
+ };
60
+
61
+ Ok(loop_statement)
62
+ }
@@ -0,0 +1,201 @@
1
+ pub mod identifer;
2
+ pub mod variable;
3
+ pub mod at;
4
+ pub mod dot;
5
+ pub mod bank;
6
+ pub mod loop_;
7
+ pub mod tempo;
8
+
9
+ use crate::{
10
+ core::{
11
+ parser::{
12
+ at::parse_at,
13
+ bank::parse_bank,
14
+ dot::parse_dot,
15
+ identifer::parse_identifier,
16
+ loop_::parse_loop,
17
+ tempo::parse_tempo,
18
+ },
19
+ preprocessor::resolver::resolve_statement,
20
+ types::{
21
+ module::Module,
22
+ parser::Parser,
23
+ statement::{ Statement, StatementKind, StatementResolved },
24
+ store::{ GlobalStore },
25
+ token::{ Token, TokenKind },
26
+ variable::VariableValue,
27
+ },
28
+ },
29
+ utils::logger::log_message,
30
+ };
31
+
32
+ pub fn parse_without_resolving(
33
+ tokens: Vec<Token>,
34
+ mut parser: &mut Parser,
35
+ global_store: &mut GlobalStore
36
+ ) -> Vec<Statement> {
37
+ let mut statements = Vec::new();
38
+
39
+ while !parser.is_eof() {
40
+ let mut error_statement = Statement {
41
+ kind: StatementKind::Error,
42
+ value: VariableValue::Null,
43
+ line: parser.peek().map_or(0, |t| t.line),
44
+ column: parser.peek().map_or(0, |t| t.column),
45
+ indent: parser.peek().map_or(0, |t| t.indent),
46
+ };
47
+
48
+ match parser.peek().map(|t| t.kind.clone()) {
49
+ Some(TokenKind::Identifier) => {
50
+ match parse_identifier(&mut parser, global_store) {
51
+ Ok(statement) => statements.push(statement),
52
+ Err(e) => {
53
+ error_statement.value = VariableValue::Text(e.to_string());
54
+ statements.push(error_statement);
55
+ }
56
+ }
57
+ }
58
+
59
+ Some(TokenKind::Bank) => {
60
+ match parse_bank(&mut parser, global_store) {
61
+ Ok(statement) => statements.push(statement),
62
+ Err(e) => {
63
+ error_statement.value = VariableValue::Text(e.to_string());
64
+ statements.push(error_statement);
65
+ }
66
+ }
67
+ }
68
+
69
+ Some(TokenKind::At) => {
70
+ match parse_at(&mut parser) {
71
+ Ok(statement) => statements.push(statement),
72
+ Err(e) => {
73
+ error_statement.value = VariableValue::Text(e.to_string());
74
+ statements.push(error_statement);
75
+ }
76
+ }
77
+ }
78
+
79
+ Some(TokenKind::Dot) => {
80
+ match parse_dot(&mut parser, global_store) {
81
+ Ok(statement) => statements.push(statement),
82
+ Err(e) => {
83
+ error_statement.value = VariableValue::Text(e.to_string());
84
+ statements.push(error_statement);
85
+ }
86
+ }
87
+ }
88
+
89
+ Some(TokenKind::Loop) => {
90
+ match parse_loop(&mut parser, global_store) {
91
+ Ok(statement) => statements.push(statement),
92
+ Err(e) => {
93
+ error_statement.value = VariableValue::Text(e.to_string());
94
+ statements.push(error_statement);
95
+ }
96
+ }
97
+ }
98
+
99
+ Some(TokenKind::Tempo) => {
100
+ match parse_tempo(&mut parser, global_store) {
101
+ Ok(statement) => statements.push(statement),
102
+ Err(e) => {
103
+ error_statement.value = VariableValue::Text(e.to_string());
104
+ statements.push(error_statement);
105
+ }
106
+ }
107
+ }
108
+
109
+ | Some(TokenKind::LBrace)
110
+ | Some(TokenKind::RBrace)
111
+ | Some(TokenKind::LBracket)
112
+ | Some(TokenKind::RBracket)
113
+ | Some(TokenKind::DbQuote)
114
+ | Some(TokenKind::Quote)
115
+ | Some(TokenKind::Number)
116
+ | Some(TokenKind::String)
117
+ | Some(TokenKind::Newline)
118
+ | Some(TokenKind::Indent)
119
+ | Some(TokenKind::Dedent) => {
120
+ parser.next();
121
+ }
122
+ Some(_) => {
123
+ parser.next();
124
+ }
125
+ None => {
126
+ break;
127
+ }
128
+ }
129
+ }
130
+
131
+ statements
132
+ }
133
+
134
+ pub fn parse_without_resolving_with_module(tokens: Vec<Token>, module: &Module) -> Vec<Statement> {
135
+ let mut parser = Parser::new(tokens.clone());
136
+
137
+ parser.current_module = module.path.clone();
138
+
139
+ let mut global_store = GlobalStore::new();
140
+ global_store.insert_module(module.path.clone(), module.clone());
141
+
142
+ let statements = parse_without_resolving(tokens, &mut parser, &mut global_store);
143
+
144
+ let mut updated_module = module.clone();
145
+ updated_module.statements = statements.clone();
146
+
147
+ let mut errors: Vec<String> = Vec::new();
148
+
149
+ statements.iter().for_each(|statement| {
150
+ match &statement.kind {
151
+ StatementKind::Error => {
152
+ let error_message = match &statement.value {
153
+ VariableValue::Text(text) => text.clone(),
154
+ _ => "Unknown error".to_string(),
155
+ };
156
+
157
+ errors.push(format!(
158
+ "Error in module '{}': {} at line {}, column {}",
159
+ updated_module.path,
160
+ error_message,
161
+ statement.line,
162
+ statement.column
163
+ ));
164
+
165
+ log_message(&format!("Error: {}", error_message), "ERROR");
166
+ }
167
+ _ => {}
168
+ }
169
+ });
170
+
171
+ if errors.len() > 0 {
172
+ log_message(&format!("{} error(s) found. Parsing stopped.", errors.len()), "INFO");
173
+
174
+ statements
175
+ } else {
176
+ statements
177
+ }
178
+ }
179
+
180
+ pub fn parse_with_resolving_with_module(
181
+ tokens: Vec<Token>,
182
+ module: &Module
183
+ ) -> Vec<StatementResolved> {
184
+ let mut parser = Parser::new(tokens.clone());
185
+
186
+ parser.current_module = module.path.clone();
187
+
188
+ let mut global_store = GlobalStore::new();
189
+ global_store.insert_module(module.path.clone(), module.clone());
190
+
191
+ let statements = parse_without_resolving(tokens, &mut parser, &mut global_store);
192
+
193
+ let mut resolved_statements = Vec::new();
194
+
195
+ for statement in statements {
196
+ let resolved_statement = resolve_statement(&statement, &mut module.clone());
197
+ resolved_statements.push(resolved_statement);
198
+ }
199
+
200
+ return resolved_statements;
201
+ }
@@ -0,0 +1,42 @@
1
+ use crate::core::types::{
2
+ parser::Parser,
3
+ statement::{ Statement, StatementKind },
4
+ store::GlobalStore,
5
+ token::TokenKind,
6
+ variable::VariableValue,
7
+ };
8
+
9
+ pub fn parse_tempo(
10
+ parser: &mut Parser,
11
+ global_store: &mut GlobalStore
12
+ ) -> Result<Statement, String> {
13
+ let token = parser.peek().ok_or("Unexpected EOF")?.clone();
14
+
15
+ parser.next();
16
+
17
+ if let Some(token) = parser.next() {
18
+
19
+ if token.kind == TokenKind::Number {
20
+ let value = token.lexeme.parse::<f32>().map_err(|_| "Invalid tempo value".to_string())?;
21
+ return Ok(Statement {
22
+ kind: StatementKind::Tempo,
23
+ value: VariableValue::Number(value as f32),
24
+ indent: token.indent,
25
+ line: token.line,
26
+ column: token.column,
27
+ });
28
+ } else if token.kind == TokenKind::Identifier {
29
+ let value = token.lexeme.clone();
30
+
31
+ return Ok(Statement {
32
+ kind: StatementKind::Tempo,
33
+ value: VariableValue::Text(value),
34
+ indent: token.indent,
35
+ line: token.line,
36
+ column: token.column,
37
+ });
38
+ }
39
+ }
40
+
41
+ Err(format!("Expected a number after tempo keyword, found {}", token.lexeme))
42
+ }