@devaloop/devalang 0.0.1-alpha.1 → 0.0.1-alpha.3
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/.devalang +4 -0
- package/Cargo.toml +46 -45
- package/README.md +35 -10
- package/docs/CHANGELOG.md +58 -0
- package/docs/COMMANDS.md +29 -6
- package/docs/CONFIG.md +28 -0
- package/docs/ROADMAP.md +6 -2
- package/docs/TODO.md +21 -18
- package/examples/exported.deva +1 -1
- package/examples/index.deva +2 -1
- package/out-tsc/bin/devalang.exe +0 -0
- package/package.json +2 -3
- package/project-version.json +4 -4
- package/rust/cli/build.rs +99 -29
- package/rust/cli/check.rs +95 -103
- package/rust/cli/init.rs +77 -0
- package/rust/cli/mod.rs +174 -1
- package/rust/cli/template.rs +56 -0
- package/rust/config/loader.rs +14 -0
- package/rust/config/mod.rs +15 -0
- package/rust/core/builder/mod.rs +21 -27
- package/rust/core/debugger/lexer.rs +12 -0
- package/rust/core/debugger/mod.rs +12 -49
- package/rust/core/debugger/preprocessor.rs +23 -0
- package/rust/core/error/mod.rs +60 -0
- package/rust/core/lexer/handler/at.rs +21 -0
- package/rust/core/lexer/handler/brace.rs +41 -0
- package/rust/core/lexer/handler/colon.rs +21 -0
- package/rust/core/lexer/handler/comment.rs +30 -0
- package/rust/core/lexer/handler/dot.rs +21 -0
- package/rust/core/lexer/handler/equal.rs +32 -0
- package/rust/core/lexer/handler/identifier.rs +38 -0
- package/rust/core/lexer/handler/indent.rs +52 -0
- package/rust/core/lexer/handler/mod.rs +238 -0
- package/rust/core/lexer/handler/newline.rs +19 -0
- package/rust/core/lexer/handler/number.rs +31 -0
- package/rust/core/lexer/handler/string.rs +66 -0
- package/rust/core/lexer/mod.rs +16 -324
- package/rust/core/lexer/token.rs +55 -0
- package/rust/core/mod.rs +5 -2
- package/rust/core/parser/handler/at.rs +166 -0
- package/rust/core/parser/handler/bank.rs +38 -0
- package/rust/core/parser/handler/dot.rs +112 -0
- package/rust/core/parser/handler/identifier.rs +134 -0
- package/rust/core/parser/handler/loop_.rs +55 -0
- package/rust/core/parser/handler/mod.rs +6 -0
- package/rust/core/parser/handler/tempo.rs +47 -0
- package/rust/core/parser/mod.rs +204 -166
- package/rust/core/parser/statement.rs +91 -0
- package/rust/core/preprocessor/loader.rs +105 -0
- package/rust/core/preprocessor/mod.rs +2 -24
- package/rust/core/preprocessor/module.rs +37 -56
- package/rust/core/preprocessor/processor.rs +41 -0
- package/rust/core/preprocessor/resolver.rs +372 -0
- package/rust/core/shared/duration.rs +8 -0
- package/rust/core/shared/mod.rs +2 -0
- package/rust/core/shared/value.rs +18 -0
- package/rust/core/store/export.rs +28 -0
- package/rust/core/store/global.rs +39 -0
- package/rust/core/store/import.rs +28 -0
- package/rust/core/store/mod.rs +4 -0
- package/rust/core/store/variable.rs +28 -0
- package/rust/core/utils/mod.rs +2 -0
- package/rust/core/utils/validation.rs +35 -0
- package/rust/lib.rs +0 -1
- package/rust/main.rs +39 -30
- package/rust/utils/file.rs +35 -0
- package/rust/utils/logger.rs +69 -34
- package/rust/utils/mod.rs +3 -2
- package/rust/utils/watcher.rs +25 -0
- package/templates/minimal/.devalang +4 -0
- package/templates/minimal/src/index.deva +2 -0
- package/templates/welcome/.devalang +4 -0
- package/templates/welcome/README.md +185 -0
- package/templates/welcome/samples/kick-808.wav +0 -0
- package/templates/welcome/src/index.deva +13 -0
- package/templates/welcome/src/variables.deva +5 -0
- package/rust/audio/mod.rs +0 -1
- package/rust/cli/new.rs +0 -1
- package/rust/core/parser/at.rs +0 -142
- package/rust/core/parser/bank.rs +0 -42
- package/rust/core/parser/dot.rs +0 -107
- package/rust/core/parser/identifer.rs +0 -91
- package/rust/core/parser/loop_.rs +0 -62
- package/rust/core/parser/tempo.rs +0 -42
- package/rust/core/parser/variable.rs +0 -129
- package/rust/core/preprocessor/dependencies.rs +0 -54
- package/rust/core/preprocessor/resolver/at.rs +0 -24
- package/rust/core/preprocessor/resolver/bank.rs +0 -59
- package/rust/core/preprocessor/resolver/loop_.rs +0 -82
- package/rust/core/preprocessor/resolver/mod.rs +0 -113
- package/rust/core/preprocessor/resolver/tempo.rs +0 -70
- package/rust/core/preprocessor/resolver/trigger.rs +0 -176
- package/rust/core/types/cli.rs +0 -160
- package/rust/core/types/mod.rs +0 -7
- package/rust/core/types/module.rs +0 -41
- package/rust/core/types/parser.rs +0 -73
- package/rust/core/types/statement.rs +0 -105
- package/rust/core/types/store.rs +0 -116
- package/rust/core/types/token.rs +0 -83
- package/rust/core/types/variable.rs +0 -32
- package/rust/runner/executer.rs +0 -44
- package/rust/runner/mod.rs +0 -1
- /package/rust/{utils → core/utils}/path.rs +0 -0
- /package/rust/utils/{loader.rs → spinner.rs} +0 -0
package/rust/core/parser/at.rs
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
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
|
-
}
|
package/rust/core/parser/bank.rs
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
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
|
-
}
|
package/rust/core/parser/dot.rs
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
use std::collections::HashMap;
|
|
2
|
-
|
|
3
|
-
use crate::core::{
|
|
4
|
-
parser::Parser,
|
|
5
|
-
types::{
|
|
6
|
-
statement::{ Statement, StatementKind },
|
|
7
|
-
token::{ Token, TokenKind, TokenParamValue },
|
|
8
|
-
variable::VariableValue,
|
|
9
|
-
},
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
pub fn parse_let_statement(parser: &mut Parser) -> Result<Statement, String> {
|
|
13
|
-
let name_token = parser.next().ok_or("Expected variable name after 'let'")?.clone();
|
|
14
|
-
if name_token.kind != TokenKind::Identifier {
|
|
15
|
-
return Err(format!("Expected variable name, found {:?}", name_token.kind));
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
let variable_name = name_token.lexeme.clone();
|
|
19
|
-
|
|
20
|
-
let equal_token = parser.next().ok_or("Expected '=' after variable name")?.clone();
|
|
21
|
-
if equal_token.kind != TokenKind::Equals {
|
|
22
|
-
return Err(format!("Expected '=', found {:?} after variable name", equal_token.kind));
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
let value_token = parser.next().ok_or("Expected value after '='")?.clone();
|
|
26
|
-
let value = match value_token.kind {
|
|
27
|
-
TokenKind::String => VariableValue::Text(value_token.lexeme.clone()),
|
|
28
|
-
TokenKind::Number =>
|
|
29
|
-
value_token.lexeme
|
|
30
|
-
.parse::<f32>()
|
|
31
|
-
.map(VariableValue::Number)
|
|
32
|
-
.map_err(|_| "Invalid number value".to_string())?,
|
|
33
|
-
TokenKind::Boolean =>
|
|
34
|
-
value_token.lexeme
|
|
35
|
-
.parse::<bool>()
|
|
36
|
-
.map(VariableValue::Boolean)
|
|
37
|
-
.map_err(|_| "Invalid boolean value".to_string())?,
|
|
38
|
-
TokenKind::Identifier => VariableValue::Text(value_token.lexeme.clone()),
|
|
39
|
-
TokenKind::LBrace => {
|
|
40
|
-
let mut object: HashMap<String, VariableValue> = HashMap::new();
|
|
41
|
-
while let Some(next_token) = parser.next() {
|
|
42
|
-
if next_token.kind == TokenKind::RBrace {
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
if next_token.kind != TokenKind::Identifier {
|
|
46
|
-
return Err(
|
|
47
|
-
format!("Expected identifier in object, found {:?}", next_token.kind)
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
let key = next_token.lexeme.clone();
|
|
51
|
-
|
|
52
|
-
let colon_token = parser.next().ok_or("Expected ':' after object key")?.clone();
|
|
53
|
-
if colon_token.kind != TokenKind::Colon {
|
|
54
|
-
return Err(format!("Expected ':', found {:?}", colon_token.kind));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
let value_token = parser.next().ok_or("Expected value after ':'")?.clone();
|
|
58
|
-
let value = match value_token.kind {
|
|
59
|
-
TokenKind::String => VariableValue::Text(value_token.lexeme.clone()),
|
|
60
|
-
TokenKind::Number =>
|
|
61
|
-
value_token.lexeme
|
|
62
|
-
.parse::<f32>()
|
|
63
|
-
.map(VariableValue::Number)
|
|
64
|
-
.map_err(|_| "Invalid number value".to_string())?,
|
|
65
|
-
TokenKind::Boolean =>
|
|
66
|
-
value_token.lexeme
|
|
67
|
-
.parse::<bool>()
|
|
68
|
-
.map(VariableValue::Boolean)
|
|
69
|
-
.map_err(|_| "Invalid boolean value".to_string())?,
|
|
70
|
-
_ => {
|
|
71
|
-
return Err(format!("Invalid object value token: {:?}", value_token.kind));
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
object.insert(key, value);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
let mut variable_object_map: HashMap<String, TokenParamValue> = HashMap::new();
|
|
78
|
-
|
|
79
|
-
for (key, value) in object {
|
|
80
|
-
let token_value = match value {
|
|
81
|
-
VariableValue::Text(s) => TokenParamValue::String(s),
|
|
82
|
-
VariableValue::Number(n) => TokenParamValue::Number(n),
|
|
83
|
-
VariableValue::Boolean(b) => TokenParamValue::Boolean(b),
|
|
84
|
-
_ => {
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
variable_object_map.insert(key, token_value);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
VariableValue::Map(variable_object_map)
|
|
92
|
-
}
|
|
93
|
-
_ => {
|
|
94
|
-
return Err(format!("Invalid value token: {:?}", value_token.kind));
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
parser.variable_table.variables.insert(variable_name.clone(), value.clone());
|
|
99
|
-
|
|
100
|
-
Ok(Statement {
|
|
101
|
-
kind: StatementKind::Let {
|
|
102
|
-
name: variable_name,
|
|
103
|
-
},
|
|
104
|
-
value: value,
|
|
105
|
-
indent: name_token.indent,
|
|
106
|
-
line: name_token.line,
|
|
107
|
-
column: name_token.column,
|
|
108
|
-
})
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
pub fn parse_variable_value(parser: &mut Parser, token: &Token) -> Result<VariableValue, String> {
|
|
112
|
-
match token.kind {
|
|
113
|
-
TokenKind::String => Ok(VariableValue::Text(token.lexeme.clone())),
|
|
114
|
-
TokenKind::Number => {
|
|
115
|
-
token.lexeme
|
|
116
|
-
.parse::<f32>()
|
|
117
|
-
.map(VariableValue::Number)
|
|
118
|
-
.map_err(|_| "Invalid number value".to_string())
|
|
119
|
-
}
|
|
120
|
-
TokenKind::Boolean => {
|
|
121
|
-
token.lexeme
|
|
122
|
-
.parse::<bool>()
|
|
123
|
-
.map(VariableValue::Boolean)
|
|
124
|
-
.map_err(|_| "Invalid boolean value".to_string())
|
|
125
|
-
}
|
|
126
|
-
TokenKind::Identifier => Ok(VariableValue::Text(token.lexeme.clone())),
|
|
127
|
-
_ => Err(format!("Invalid variable value token: {:?}", token.kind)),
|
|
128
|
-
}
|
|
129
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
use std::{ collections::{ HashSet, VecDeque }, fs };
|
|
2
|
-
|
|
3
|
-
pub fn collect_dependencies_recursively(entry_file: &str) -> Vec<String> {
|
|
4
|
-
let mut queue = VecDeque::new();
|
|
5
|
-
let mut loaded = HashSet::new();
|
|
6
|
-
|
|
7
|
-
queue.push_back(entry_file.to_string());
|
|
8
|
-
|
|
9
|
-
while let Some(file_ref) = queue.pop_front() {
|
|
10
|
-
if loaded.contains(&file_ref) {
|
|
11
|
-
continue;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
let deps = get_direct_dependencies(&file_ref);
|
|
15
|
-
for dep in deps {
|
|
16
|
-
queue.push_back(dep.clone());
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
loaded.insert(file_ref);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
loaded.into_iter().collect()
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
fn get_direct_dependencies(file: &str) -> Vec<String> {
|
|
26
|
-
let content = match fs::read_to_string(file) {
|
|
27
|
-
Ok(c) => c,
|
|
28
|
-
Err(_) => {
|
|
29
|
-
eprintln!("⚠️ Unable to read file: {}", file);
|
|
30
|
-
return vec![];
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
let mut deps = Vec::new();
|
|
35
|
-
|
|
36
|
-
for line in content.lines() {
|
|
37
|
-
let line = line.trim();
|
|
38
|
-
|
|
39
|
-
if line.starts_with("@import") {
|
|
40
|
-
if let Some(from_index) = line.find("from") {
|
|
41
|
-
let after_from = line[from_index + 4..].trim();
|
|
42
|
-
if after_from.starts_with('"') || after_from.starts_with('\'') {
|
|
43
|
-
let delimiter = after_from.chars().next().unwrap();
|
|
44
|
-
if let Some(end_quote) = after_from[1..].find(delimiter) {
|
|
45
|
-
let path = &after_from[1..=end_quote];
|
|
46
|
-
deps.push(path.to_string());
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
deps
|
|
54
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
use crate::core::types::{
|
|
2
|
-
module::Module,
|
|
3
|
-
statement::{ Statement, StatementResolved, StatementResolvedValue },
|
|
4
|
-
variable::VariableValue,
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
pub fn resolve_load_statement(
|
|
8
|
-
stmt: &Statement,
|
|
9
|
-
source: &str,
|
|
10
|
-
alias: &str,
|
|
11
|
-
module: &mut Module
|
|
12
|
-
) -> StatementResolved {
|
|
13
|
-
let source_string = source.to_string();
|
|
14
|
-
|
|
15
|
-
module.set_variable(alias.to_string(), VariableValue::Sample(source_string.clone()));
|
|
16
|
-
|
|
17
|
-
StatementResolved {
|
|
18
|
-
kind: stmt.kind.clone(),
|
|
19
|
-
value: StatementResolvedValue::Null,
|
|
20
|
-
indent: stmt.indent,
|
|
21
|
-
line: stmt.line,
|
|
22
|
-
column: stmt.column,
|
|
23
|
-
}
|
|
24
|
-
}
|