@devaloop/devalang 0.0.1-alpha.2 → 0.0.1-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devalang +1 -1
- package/Cargo.toml +46 -46
- package/README.md +48 -30
- package/docs/CHANGELOG.md +28 -6
- package/docs/COMMANDS.md +31 -0
- package/docs/CONFIG.md +6 -4
- package/docs/ROADMAP.md +5 -1
- package/docs/TODO.md +10 -35
- package/examples/exported.deva +1 -1
- package/examples/index.deva +8 -1
- package/examples/samples/hat-808.wav +0 -0
- package/out-tsc/bin/devalang.exe +0 -0
- package/package.json +41 -42
- package/project-version.json +5 -5
- package/rust/audio/engine.rs +130 -0
- package/rust/audio/interpreter.rs +143 -0
- package/rust/audio/loader.rs +46 -0
- package/rust/audio/mod.rs +5 -1
- package/rust/audio/player.rs +54 -0
- package/rust/audio/render.rs +57 -0
- package/rust/cli/build.rs +73 -45
- package/rust/cli/check.rs +47 -111
- package/rust/cli/init.rs +1 -1
- package/rust/cli/mod.rs +203 -2
- package/rust/cli/play.rs +191 -0
- package/rust/{utils/config.rs → config/loader.rs} +3 -2
- package/rust/config/mod.rs +16 -0
- package/rust/core/builder/mod.rs +69 -27
- package/rust/core/debugger/lexer.rs +27 -0
- package/rust/core/debugger/mod.rs +12 -49
- package/rust/core/debugger/preprocessor.rs +27 -0
- package/rust/core/error/mod.rs +60 -0
- package/rust/core/lexer/{at.rs → handler/at.rs} +1 -1
- package/rust/core/lexer/{brace.rs → handler/brace.rs} +1 -1
- package/rust/core/lexer/{colon.rs → handler/colon.rs} +1 -1
- package/rust/core/lexer/{comment.rs → handler/comment.rs} +3 -3
- package/rust/core/lexer/{dot.rs → handler/dot.rs} +1 -1
- package/rust/core/lexer/{equal.rs → handler/equal.rs} +1 -1
- package/rust/core/lexer/{identifier.rs → handler/identifier.rs} +1 -1
- package/rust/core/lexer/{indent.rs → handler/indent.rs} +10 -5
- package/rust/core/lexer/handler/mod.rs +238 -0
- package/rust/core/lexer/{newline.rs → handler/newline.rs} +6 -10
- package/rust/core/lexer/{number.rs → handler/number.rs} +1 -1
- package/rust/core/lexer/handler/string.rs +66 -0
- package/rust/core/lexer/mod.rs +25 -14
- 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 +116 -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/bank.rs +38 -51
- package/rust/core/preprocessor/resolver/loop_.rs +126 -65
- package/rust/core/preprocessor/resolver/mod.rs +119 -80
- package/rust/core/preprocessor/resolver/tempo.rs +40 -61
- package/rust/core/preprocessor/resolver/trigger.rs +93 -155
- 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 +22 -18
- package/rust/utils/logger.rs +69 -34
- package/rust/utils/mod.rs +3 -5
- package/rust/utils/watcher.rs +10 -2
- package/templates/minimal/.devalang +1 -1
- package/templates/welcome/.devalang +1 -1
- package/rust/core/lexer/bracket.rs +0 -41
- package/rust/core/lexer/driver.rs +0 -286
- package/rust/core/lexer/quote.rs +0 -61
- package/rust/core/parser/at.rs +0 -142
- package/rust/core/parser/bank.rs +0 -42
- package/rust/core/parser/dot.rs +0 -137
- 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/types/cli.rs +0 -182
- package/rust/core/types/config.rs +0 -15
- package/rust/core/types/mod.rs +0 -8
- 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
|
@@ -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
|
-
}
|
package/rust/core/types/cli.rs
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
use clap::{ Parser, Subcommand };
|
|
2
|
-
use crate::utils::version::get_version;
|
|
3
|
-
|
|
4
|
-
#[derive(Parser)]
|
|
5
|
-
#[command(name = "devalang")]
|
|
6
|
-
#[command(author = "Devaloop")]
|
|
7
|
-
#[command(version = get_version())]
|
|
8
|
-
#[command(about = "🦊 Devalang – A programming language for music and sound.")]
|
|
9
|
-
pub struct Cli {
|
|
10
|
-
#[arg(long, global = true)]
|
|
11
|
-
/// Skips loading the configuration file.
|
|
12
|
-
pub no_config: bool,
|
|
13
|
-
|
|
14
|
-
#[command(subcommand)]
|
|
15
|
-
pub command: CliCommands,
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
#[derive(Subcommand)]
|
|
19
|
-
pub enum CliTemplateCommand {
|
|
20
|
-
/// Lists all available templates for Devalang projects.
|
|
21
|
-
List,
|
|
22
|
-
/// Displays information about a specific template.
|
|
23
|
-
Info {
|
|
24
|
-
name: String,
|
|
25
|
-
},
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
pub enum CompilationMode {
|
|
29
|
-
/// Real-time compilation mode, for compiling files as soon as possible.
|
|
30
|
-
RealTime,
|
|
31
|
-
|
|
32
|
-
/// Batch compilation mode, for compiling files one by one.
|
|
33
|
-
Batch,
|
|
34
|
-
|
|
35
|
-
/// Check mode, used for analyzing the code without compiling it.
|
|
36
|
-
Check,
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
#[derive(Subcommand)]
|
|
40
|
-
pub enum CliCommands {
|
|
41
|
-
/// Create a new Devalang project.
|
|
42
|
-
///
|
|
43
|
-
/// ### Arguments
|
|
44
|
-
/// - `name` - The name of the project to create.
|
|
45
|
-
/// - `template` - The template to use for the project. Defaults to "default".
|
|
46
|
-
///
|
|
47
|
-
/// ### Example
|
|
48
|
-
/// ```bash
|
|
49
|
-
/// devalang init --name my_project --template default
|
|
50
|
-
///
|
|
51
|
-
Init {
|
|
52
|
-
#[arg(short, long)]
|
|
53
|
-
/// The optional name (directory) of the project to create.
|
|
54
|
-
name: Option<String>,
|
|
55
|
-
|
|
56
|
-
#[arg(short, long)]
|
|
57
|
-
/// The template to use for the project.
|
|
58
|
-
///
|
|
59
|
-
/// ### Default value
|
|
60
|
-
/// - `default`
|
|
61
|
-
///
|
|
62
|
-
template: Option<String>,
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
Template {
|
|
66
|
-
#[command(subcommand)]
|
|
67
|
-
/// The template command to execute.
|
|
68
|
-
command: CliTemplateCommand,
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
/// Build the program and generate output files.
|
|
72
|
-
///
|
|
73
|
-
/// ### Arguments
|
|
74
|
-
/// - `entry` - The entry point of the program to build. Defaults to "./src".
|
|
75
|
-
/// - `output` - The directory where the output files will be generated. Defaults to "./output".
|
|
76
|
-
/// - `watch` - Whether to watch for changes and rebuild. Defaults to "true".
|
|
77
|
-
///
|
|
78
|
-
/// ### Example
|
|
79
|
-
/// ```bash
|
|
80
|
-
/// devalang build --entry ./src --output ./output --watch true
|
|
81
|
-
/// ```
|
|
82
|
-
///
|
|
83
|
-
Build {
|
|
84
|
-
#[arg(short, long)]
|
|
85
|
-
/// The entry point of the program to build.
|
|
86
|
-
///
|
|
87
|
-
entry: Option<String>,
|
|
88
|
-
|
|
89
|
-
#[arg(short, long)]
|
|
90
|
-
/// The directory where the output files will be generated.
|
|
91
|
-
///
|
|
92
|
-
output: Option<String>,
|
|
93
|
-
|
|
94
|
-
#[arg(long, default_value_t = false)]
|
|
95
|
-
/// Whether to watch for changes and rebuild.
|
|
96
|
-
///
|
|
97
|
-
/// ### Default value
|
|
98
|
-
/// - `false`
|
|
99
|
-
///
|
|
100
|
-
watch: bool,
|
|
101
|
-
|
|
102
|
-
#[arg(long, default_value = "real-time")]
|
|
103
|
-
/// The mode of compilation.
|
|
104
|
-
///
|
|
105
|
-
/// ### Default value
|
|
106
|
-
/// - `real-time`
|
|
107
|
-
///
|
|
108
|
-
/// ### Possible values
|
|
109
|
-
/// - `real-time` - Compiles files as soon as possible.
|
|
110
|
-
/// - `batch` - Compiles files one by one.
|
|
111
|
-
/// - `check` - Analyzes the code without compiling it.
|
|
112
|
-
///
|
|
113
|
-
compilation_mode: String,
|
|
114
|
-
|
|
115
|
-
#[arg(short, long, default_value_t = false)]
|
|
116
|
-
/// Whether to print debug information.
|
|
117
|
-
///
|
|
118
|
-
/// ### Default value
|
|
119
|
-
/// - `false`
|
|
120
|
-
///
|
|
121
|
-
debug: bool,
|
|
122
|
-
|
|
123
|
-
#[arg(short, long, default_value_t = false)]
|
|
124
|
-
/// Whether to compress the output files.
|
|
125
|
-
///
|
|
126
|
-
/// ### Default value
|
|
127
|
-
/// - `false`
|
|
128
|
-
///
|
|
129
|
-
compress: bool,
|
|
130
|
-
},
|
|
131
|
-
|
|
132
|
-
/// Analyze the program for errors and warnings.
|
|
133
|
-
///
|
|
134
|
-
/// ### Arguments
|
|
135
|
-
/// - `entry` - The entry point of the program to analyze. Defaults to "./src".
|
|
136
|
-
/// - `watch` - Whether to watch for changes and re-analyze. Defaults to "true".
|
|
137
|
-
///
|
|
138
|
-
/// ### Example
|
|
139
|
-
/// ```bash
|
|
140
|
-
/// devalang check --entry ./src --watch true --compilation-mode real-time
|
|
141
|
-
/// ```
|
|
142
|
-
Check {
|
|
143
|
-
#[arg(short, long)]
|
|
144
|
-
/// The entry point of the program to analyze.
|
|
145
|
-
///
|
|
146
|
-
entry: Option<String>,
|
|
147
|
-
|
|
148
|
-
#[arg(short, long)]
|
|
149
|
-
/// The directory where the output files will be generated.
|
|
150
|
-
///
|
|
151
|
-
output: Option<String>,
|
|
152
|
-
|
|
153
|
-
#[arg(long, default_value_t = false)]
|
|
154
|
-
/// Whether to watch for changes and re-analyze.
|
|
155
|
-
///
|
|
156
|
-
/// ### Default value
|
|
157
|
-
/// - `false`
|
|
158
|
-
///
|
|
159
|
-
watch: bool,
|
|
160
|
-
|
|
161
|
-
#[arg(short, long, default_value = "real-time")]
|
|
162
|
-
/// The mode of compilation.
|
|
163
|
-
///
|
|
164
|
-
/// ### Default value
|
|
165
|
-
/// - `real-time`
|
|
166
|
-
///
|
|
167
|
-
/// ### Possible values
|
|
168
|
-
/// - `real-time` - Analyzes files as soon as possible.
|
|
169
|
-
/// - `batch` - Analyzes files one by one.
|
|
170
|
-
/// - `check` - Analyzes the code without compiling it.
|
|
171
|
-
///
|
|
172
|
-
compilation_mode: String,
|
|
173
|
-
|
|
174
|
-
#[arg(short, long, default_value_t = false)]
|
|
175
|
-
/// Whether to print debug information.
|
|
176
|
-
///
|
|
177
|
-
/// ### Default value
|
|
178
|
-
/// - `false`
|
|
179
|
-
///
|
|
180
|
-
debug: bool,
|
|
181
|
-
},
|
|
182
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
use serde::Deserialize;
|
|
2
|
-
|
|
3
|
-
#[derive(Debug, Deserialize)]
|
|
4
|
-
pub struct DevalangConfig {
|
|
5
|
-
pub defaults: Defaults,
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
#[derive(Debug, Deserialize)]
|
|
9
|
-
pub struct Defaults {
|
|
10
|
-
pub entry: Option<String>,
|
|
11
|
-
|
|
12
|
-
pub output: Option<String>,
|
|
13
|
-
|
|
14
|
-
pub watch: Option<bool>,
|
|
15
|
-
}
|
package/rust/core/types/mod.rs
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
use crate::core::types::{
|
|
2
|
-
statement::Statement,
|
|
3
|
-
store::{ ExportTable, ImportTable, VariableTable },
|
|
4
|
-
token::Token,
|
|
5
|
-
variable::VariableValue,
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
#[derive(Debug, Clone)]
|
|
9
|
-
pub struct Module {
|
|
10
|
-
pub path: String,
|
|
11
|
-
pub tokens: Vec<Token>,
|
|
12
|
-
pub statements: Vec<Statement>,
|
|
13
|
-
pub variable_table: VariableTable,
|
|
14
|
-
pub export_table: ExportTable,
|
|
15
|
-
pub import_table: ImportTable,
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
impl Module {
|
|
19
|
-
pub fn new(path: String) -> Self {
|
|
20
|
-
Module {
|
|
21
|
-
path,
|
|
22
|
-
tokens: Vec::new(),
|
|
23
|
-
statements: Vec::new(),
|
|
24
|
-
variable_table: VariableTable::new(),
|
|
25
|
-
export_table: ExportTable::new(),
|
|
26
|
-
import_table: ImportTable::new(),
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
pub fn add_statement(&mut self, statement: Statement) {
|
|
31
|
-
self.statements.push(statement);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
pub fn set_variable(&mut self, name: String, value: VariableValue) {
|
|
35
|
-
self.variable_table.set(name, value);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
pub fn get_variable(&self, name: &str) -> Option<&VariableValue> {
|
|
39
|
-
self.variable_table.get(name)
|
|
40
|
-
}
|
|
41
|
-
}
|