@devaloop/devalang 0.0.1-alpha.14 → 0.0.1-alpha.16
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 +10 -8
- package/.github/workflows/ci.yml +92 -0
- package/Cargo.toml +60 -58
- package/README.md +32 -15
- package/docs/CHANGELOG.md +93 -1
- package/docs/CONTRIBUTING.md +101 -1
- package/docs/ROADMAP.md +2 -2
- package/docs/TODO.md +1 -1
- package/examples/automation.deva +42 -0
- package/examples/bank.deva +4 -4
- package/examples/events.deva +12 -0
- package/examples/function.deva +4 -4
- package/examples/index.deva +39 -25
- package/examples/loop.deva +5 -11
- package/examples/pattern.deva +8 -0
- package/examples/plugin.deva +16 -0
- package/examples/variables.deva +1 -1
- package/out-tsc/bin/index.js +51 -7
- package/out-tsc/index.js +3 -1
- package/out-tsc/scripts/postbuild.js +9 -10
- package/out-tsc/scripts/postinstall.js +49 -0
- package/package.json +12 -4
- package/project-version.json +3 -3
- package/rust/cli/bank.rs +462 -456
- package/rust/cli/build.rs +252 -199
- package/rust/cli/check.rs +221 -180
- package/rust/cli/driver.rs +297 -292
- package/rust/cli/generator.rs +1 -0
- package/rust/cli/init.rs +87 -79
- package/rust/cli/install.rs +35 -32
- package/rust/cli/login.rs +127 -134
- package/rust/cli/mod.rs +13 -11
- package/rust/cli/play.rs +1123 -218
- package/rust/cli/telemetry.rs +19 -0
- package/rust/cli/template.rs +69 -57
- package/rust/cli/update.rs +6 -4
- package/rust/common/api.rs +5 -8
- package/rust/common/cdn.rs +3 -6
- package/rust/common/mod.rs +3 -3
- package/rust/common/sso.rs +3 -6
- package/rust/config/driver.rs +118 -94
- package/rust/config/loader.rs +165 -156
- package/rust/config/mod.rs +4 -2
- package/rust/config/settings.rs +91 -0
- package/rust/config/stats.rs +257 -0
- package/rust/core/audio/engine.rs +696 -518
- package/rust/core/audio/evaluator.rs +263 -31
- package/rust/core/audio/interpreter/arrow_call.rs +198 -161
- package/rust/core/audio/interpreter/automate.rs +18 -0
- package/rust/core/audio/interpreter/call.rs +98 -95
- package/rust/core/audio/interpreter/condition.rs +70 -71
- package/rust/core/audio/interpreter/driver.rs +487 -198
- package/rust/core/audio/interpreter/function.rs +26 -21
- package/rust/core/audio/interpreter/let_.rs +38 -19
- package/rust/core/audio/interpreter/load.rs +18 -18
- package/rust/core/audio/interpreter/loop_.rs +113 -73
- package/rust/core/audio/interpreter/mod.rs +14 -13
- package/rust/core/audio/interpreter/sleep.rs +27 -30
- package/rust/core/audio/interpreter/spawn.rs +105 -102
- package/rust/core/audio/interpreter/tempo.rs +19 -16
- package/rust/core/audio/interpreter/trigger.rs +239 -210
- package/rust/core/audio/loader/mod.rs +1 -1
- package/rust/core/audio/loader/trigger.rs +100 -97
- package/rust/core/audio/mod.rs +7 -6
- package/rust/core/audio/player.rs +64 -64
- package/rust/core/audio/renderer.rs +56 -53
- package/rust/core/audio/special/easing.rs +189 -0
- package/rust/core/audio/special/env.rs +43 -0
- package/rust/core/audio/special/math.rs +102 -0
- package/rust/core/audio/special/mod.rs +9 -0
- package/rust/core/audio/special/modulator.rs +143 -0
- package/rust/core/builder/mod.rs +80 -85
- package/rust/core/debugger/lexer.rs +27 -27
- package/rust/core/debugger/mod.rs +24 -23
- package/rust/core/debugger/module.rs +55 -47
- package/rust/core/debugger/preprocessor.rs +27 -27
- package/rust/core/debugger/store.rs +40 -39
- package/rust/core/error/mod.rs +80 -66
- package/rust/core/lexer/handler/arrow.rs +82 -31
- package/rust/core/lexer/handler/at.rs +21 -21
- package/rust/core/lexer/handler/brace.rs +41 -41
- package/rust/core/lexer/handler/colon.rs +21 -21
- package/rust/core/lexer/handler/comment.rs +30 -30
- package/rust/core/lexer/handler/dot.rs +21 -21
- package/rust/core/lexer/handler/driver.rs +337 -263
- package/rust/core/lexer/handler/identifier.rs +46 -42
- package/rust/core/lexer/handler/indent.rs +66 -66
- package/rust/core/lexer/handler/mod.rs +16 -16
- package/rust/core/lexer/handler/newline.rs +23 -23
- package/rust/core/lexer/handler/number.rs +31 -31
- package/rust/core/lexer/handler/operator.rs +46 -44
- package/rust/core/lexer/handler/parenthesis.rs +41 -41
- package/rust/core/lexer/handler/slash.rs +21 -21
- package/rust/core/lexer/handler/string.rs +63 -63
- package/rust/core/lexer/mod.rs +54 -51
- package/rust/core/lexer/token.rs +97 -91
- package/rust/core/mod.rs +11 -11
- package/rust/core/parser/driver.rs +513 -408
- package/rust/core/parser/handler/arrow_call.rs +233 -211
- package/rust/core/parser/handler/at.rs +245 -162
- package/rust/core/parser/handler/bank.rs +94 -69
- package/rust/core/parser/handler/condition.rs +80 -74
- package/rust/core/parser/handler/dot.rs +143 -135
- package/rust/core/parser/handler/identifier/automate.rs +257 -0
- package/rust/core/parser/handler/identifier/call.rs +91 -88
- package/rust/core/parser/handler/identifier/emit.rs +66 -0
- package/rust/core/parser/handler/identifier/function.rs +100 -92
- package/rust/core/parser/handler/identifier/group.rs +85 -75
- package/rust/core/parser/handler/identifier/let_.rs +158 -127
- package/rust/core/parser/handler/identifier/mod.rs +54 -52
- package/rust/core/parser/handler/identifier/on.rs +98 -0
- package/rust/core/parser/handler/identifier/print.rs +52 -0
- package/rust/core/parser/handler/identifier/sleep.rs +36 -33
- package/rust/core/parser/handler/identifier/spawn.rs +91 -88
- package/rust/core/parser/handler/identifier/synth.rs +65 -65
- package/rust/core/parser/handler/loop_.rs +170 -72
- package/rust/core/parser/handler/mod.rs +8 -8
- package/rust/core/parser/handler/tempo.rs +53 -47
- package/rust/core/parser/mod.rs +4 -4
- package/rust/core/parser/statement.rs +142 -108
- package/rust/core/plugin/loader.rs +123 -48
- package/rust/core/plugin/mod.rs +2 -1
- package/rust/core/plugin/runner.rs +296 -0
- package/rust/core/preprocessor/loader.rs +515 -326
- package/rust/core/preprocessor/mod.rs +4 -4
- package/rust/core/preprocessor/module.rs +60 -58
- package/rust/core/preprocessor/processor.rs +99 -101
- package/rust/core/preprocessor/resolver/bank.rs +51 -49
- package/rust/core/preprocessor/resolver/call.rs +100 -100
- package/rust/core/preprocessor/resolver/condition.rs +97 -97
- package/rust/core/preprocessor/resolver/driver.rs +310 -278
- package/rust/core/preprocessor/resolver/function.rs +69 -78
- package/rust/core/preprocessor/resolver/group.rs +96 -91
- package/rust/core/preprocessor/resolver/let_.rs +32 -28
- package/rust/core/preprocessor/resolver/loop_.rs +320 -91
- package/rust/core/preprocessor/resolver/mod.rs +15 -15
- package/rust/core/preprocessor/resolver/spawn.rs +76 -92
- package/rust/core/preprocessor/resolver/synth.rs +56 -50
- package/rust/core/preprocessor/resolver/tempo.rs +50 -49
- package/rust/core/preprocessor/resolver/trigger.rs +113 -116
- package/rust/core/preprocessor/resolver/value.rs +81 -87
- package/rust/core/shared/bank.rs +1 -1
- package/rust/core/shared/duration.rs +9 -9
- package/rust/core/shared/mod.rs +3 -3
- package/rust/core/shared/value.rs +35 -32
- package/rust/core/store/function.rs +34 -34
- package/rust/core/store/global.rs +55 -38
- package/rust/core/store/mod.rs +5 -5
- package/rust/core/store/variable.rs +37 -34
- package/rust/core/utils/mod.rs +2 -2
- package/rust/core/utils/path.rs +37 -31
- package/rust/core/utils/validation.rs +35 -37
- package/rust/installer/addon.rs +84 -80
- package/rust/installer/bank.rs +62 -65
- package/rust/installer/mod.rs +5 -5
- package/rust/installer/plugin.rs +54 -55
- package/rust/installer/utils.rs +56 -56
- package/rust/lib.rs +156 -164
- package/rust/main.rs +250 -145
- package/rust/utils/error.rs +200 -0
- package/rust/utils/file.rs +38 -35
- package/rust/utils/first_usage.rs +76 -0
- package/rust/utils/logger.rs +195 -139
- package/rust/utils/mod.rs +9 -50
- package/rust/utils/signature.rs +19 -17
- package/rust/utils/spinner.rs +22 -19
- package/rust/utils/telemetry.rs +292 -0
- package/rust/utils/watcher.rs +34 -33
- package/templates/minimal/README.md +97 -121
- package/templates/welcome/README.md +97 -121
- package/typescript/bin/index.ts +19 -5
- package/typescript/index.ts +3 -1
- package/typescript/scripts/postbuild.ts +10 -6
- package/typescript/scripts/postinstall.ts +56 -0
- package/typescript/scripts/version/bump.ts +0 -1
- package/typescript/scripts/version/index.ts +0 -1
- package/out-tsc/bin/devalang.exe +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
use crate::core::store::variable::VariableTable;
|
|
2
|
+
|
|
3
|
+
fn lfo_sine(rate_per_beat: f32, beat: f32) -> f32 {
|
|
4
|
+
// Output in [-1,1]
|
|
5
|
+
(2.0 * std::f32::consts::PI * rate_per_beat * beat).sin()
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
fn lfo_triangle(rate_per_beat: f32, beat: f32) -> f32 {
|
|
9
|
+
// Triangle in [-1,1]
|
|
10
|
+
let phase = (rate_per_beat * beat).fract();
|
|
11
|
+
// Map [0,1]->[-1,1] tri
|
|
12
|
+
4.0 * (phase - 0.5).abs() - 1.0
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
fn adsr_envelope_value_t(attack: f32, decay: f32, sustain: f32, release: f32, t: f32) -> f32 {
|
|
16
|
+
let a = attack.max(0.0);
|
|
17
|
+
let d = decay.max(0.0);
|
|
18
|
+
let r = release.max(0.0);
|
|
19
|
+
let s = sustain.clamp(0.0, 1.0);
|
|
20
|
+
|
|
21
|
+
// Normalize phases so that the whole ADSR spans t in [0,1]
|
|
22
|
+
let total = (a + d + r).max(1e-6);
|
|
23
|
+
let ap = a / total;
|
|
24
|
+
let dp = d / total;
|
|
25
|
+
let rp = r / total;
|
|
26
|
+
|
|
27
|
+
if t < ap {
|
|
28
|
+
// attack (0->1)
|
|
29
|
+
if ap > 0.0 { t / ap } else { 1.0 }
|
|
30
|
+
} else if t < ap + dp {
|
|
31
|
+
// decay (1->sustain)
|
|
32
|
+
let u = (t - ap) / dp.max(1e-6);
|
|
33
|
+
1.0 - (1.0 - s) * u
|
|
34
|
+
} else if t < 1.0 - rp {
|
|
35
|
+
// sustain
|
|
36
|
+
s
|
|
37
|
+
} else {
|
|
38
|
+
// release (sustain->0)
|
|
39
|
+
let u = (t - (1.0 - rp)) / rp.max(1e-6);
|
|
40
|
+
s * (1.0 - u)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fn eval_mod_func(func: &str, args: &[f32], beat: f32) -> Option<f32> {
|
|
45
|
+
match func {
|
|
46
|
+
"lfo.sine" => {
|
|
47
|
+
let rate = args.get(0).copied().unwrap_or(1.0);
|
|
48
|
+
Some(lfo_sine(rate, beat))
|
|
49
|
+
}
|
|
50
|
+
"lfo.tri" | "lfo.triangle" => {
|
|
51
|
+
let rate = args.get(0).copied().unwrap_or(1.0);
|
|
52
|
+
Some(lfo_triangle(rate, beat))
|
|
53
|
+
}
|
|
54
|
+
// ADSR envelope normalized over t in [0,1]
|
|
55
|
+
// $mod.envelope(attack, decay, sustain, release, t)
|
|
56
|
+
"envelope" | "mod.envelope" => {
|
|
57
|
+
if args.len() >= 5 {
|
|
58
|
+
Some(adsr_envelope_value_t(
|
|
59
|
+
args[0],
|
|
60
|
+
args[1],
|
|
61
|
+
args[2],
|
|
62
|
+
args[3],
|
|
63
|
+
args[4].clamp(0.0, 1.0),
|
|
64
|
+
))
|
|
65
|
+
} else {
|
|
66
|
+
None
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
_ => None,
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
fn parse_top_level_args(s: &str) -> Vec<&str> {
|
|
74
|
+
let mut args = Vec::new();
|
|
75
|
+
let mut depth = 0i32;
|
|
76
|
+
let mut start = 0usize;
|
|
77
|
+
for (i, ch) in s.char_indices() {
|
|
78
|
+
match ch {
|
|
79
|
+
'(' => depth += 1,
|
|
80
|
+
')' => depth -= 1,
|
|
81
|
+
',' if depth == 0 => {
|
|
82
|
+
args.push(s[start..i].trim());
|
|
83
|
+
start = i + 1;
|
|
84
|
+
}
|
|
85
|
+
_ => {}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
let last = s[start..].trim();
|
|
89
|
+
if !last.is_empty() {
|
|
90
|
+
args.push(last);
|
|
91
|
+
}
|
|
92
|
+
args
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Find and evaluate the first $mod.<fn>(...) occurrence in the string.
|
|
96
|
+
pub fn find_and_eval_first_mod_call<EvalFn>(
|
|
97
|
+
s: &str,
|
|
98
|
+
eval: EvalFn,
|
|
99
|
+
vars: &VariableTable,
|
|
100
|
+
bpm: f32,
|
|
101
|
+
beat: f32,
|
|
102
|
+
) -> Option<String>
|
|
103
|
+
where
|
|
104
|
+
EvalFn: Fn(&str, &VariableTable, f32, f32) -> Option<f32>,
|
|
105
|
+
{
|
|
106
|
+
let start = s.find("$mod.")?;
|
|
107
|
+
let open_rel = s[start..].find('(')?;
|
|
108
|
+
let open = start + open_rel;
|
|
109
|
+
let func = &s[start + 5..open];
|
|
110
|
+
|
|
111
|
+
// matching close
|
|
112
|
+
let mut depth: i32 = 0;
|
|
113
|
+
let mut close_abs: Option<usize> = None;
|
|
114
|
+
for (i, ch) in s[open..].char_indices() {
|
|
115
|
+
match ch {
|
|
116
|
+
'(' => depth += 1,
|
|
117
|
+
')' => {
|
|
118
|
+
depth -= 1;
|
|
119
|
+
if depth == 0 {
|
|
120
|
+
close_abs = Some(open + i);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
_ => {}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
let close = close_abs?;
|
|
128
|
+
|
|
129
|
+
let inner = &s[open + 1..close];
|
|
130
|
+
let raw_args = parse_top_level_args(inner);
|
|
131
|
+
let mut args: Vec<f32> = Vec::with_capacity(raw_args.len());
|
|
132
|
+
for a in raw_args {
|
|
133
|
+
args.push(eval(a, vars, bpm, beat)?);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let result = eval_mod_func(func, &args, beat)?;
|
|
137
|
+
|
|
138
|
+
let mut replaced = String::new();
|
|
139
|
+
replaced.push_str(&s[..start]);
|
|
140
|
+
replaced.push_str(&result.to_string());
|
|
141
|
+
replaced.push_str(&s[close + 1..]);
|
|
142
|
+
Some(replaced)
|
|
143
|
+
}
|
package/rust/core/builder/mod.rs
CHANGED
|
@@ -1,85 +1,80 @@
|
|
|
1
|
-
use crate::core::audio::renderer::render_audio_with_modules;
|
|
2
|
-
use crate::core::parser::statement::Statement;
|
|
3
|
-
use crate::core::store::global::GlobalStore;
|
|
4
|
-
use
|
|
5
|
-
use std::io::Write;
|
|
6
|
-
use
|
|
7
|
-
|
|
8
|
-
pub struct Builder {}
|
|
9
|
-
|
|
10
|
-
impl Builder {
|
|
11
|
-
pub fn new() -> Self {
|
|
12
|
-
Builder {}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
pub fn build_ast(
|
|
16
|
-
&self,
|
|
17
|
-
modules: &HashMap<String, Vec<Statement>>,
|
|
18
|
-
out_dir: &str,
|
|
19
|
-
compress: bool
|
|
20
|
-
) {
|
|
21
|
-
for (name, statements) in modules {
|
|
22
|
-
let formatted_name = name.split("/").last().unwrap_or(name);
|
|
23
|
-
let formatted_name = formatted_name.replace(".deva", "");
|
|
24
|
-
|
|
25
|
-
create_dir_all(format!("{}/ast", out_dir)).expect("Failed to create AST directory");
|
|
26
|
-
|
|
27
|
-
let file_path = format!("{}/ast/{}.json", out_dir, formatted_name);
|
|
28
|
-
let mut file = std::fs::File::create(file_path).expect("Failed to create AST file");
|
|
29
|
-
let content = if compress {
|
|
30
|
-
serde_json::to_string(&statements).expect("Failed to serialize AST")
|
|
31
|
-
} else {
|
|
32
|
-
serde_json::to_string_pretty(&statements).expect("Failed to serialize AST")
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
file.write_all(content.as_bytes())
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
&normalized_output_dir,
|
|
50
|
-
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
&
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
1
|
+
use crate::core::audio::renderer::render_audio_with_modules;
|
|
2
|
+
use crate::core::parser::statement::Statement;
|
|
3
|
+
use crate::core::store::global::GlobalStore;
|
|
4
|
+
use crate::utils::logger::Logger;
|
|
5
|
+
use std::io::Write;
|
|
6
|
+
use std::{collections::HashMap, fs::create_dir_all};
|
|
7
|
+
|
|
8
|
+
pub struct Builder {}
|
|
9
|
+
|
|
10
|
+
impl Builder {
|
|
11
|
+
pub fn new() -> Self {
|
|
12
|
+
Builder {}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
pub fn build_ast(
|
|
16
|
+
&self,
|
|
17
|
+
modules: &HashMap<String, Vec<Statement>>,
|
|
18
|
+
out_dir: &str,
|
|
19
|
+
compress: bool,
|
|
20
|
+
) {
|
|
21
|
+
for (name, statements) in modules {
|
|
22
|
+
let formatted_name = name.split("/").last().unwrap_or(name);
|
|
23
|
+
let formatted_name = formatted_name.replace(".deva", "");
|
|
24
|
+
|
|
25
|
+
create_dir_all(format!("{}/ast", out_dir)).expect("Failed to create AST directory");
|
|
26
|
+
|
|
27
|
+
let file_path = format!("{}/ast/{}.json", out_dir, formatted_name);
|
|
28
|
+
let mut file = std::fs::File::create(file_path).expect("Failed to create AST file");
|
|
29
|
+
let content = if compress {
|
|
30
|
+
serde_json::to_string(&statements).expect("Failed to serialize AST")
|
|
31
|
+
} else {
|
|
32
|
+
serde_json::to_string_pretty(&statements).expect("Failed to serialize AST")
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
file.write_all(content.as_bytes())
|
|
36
|
+
.expect("Failed to write AST to file");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
pub fn build_audio(
|
|
41
|
+
&self,
|
|
42
|
+
modules: &HashMap<String, Vec<Statement>>,
|
|
43
|
+
normalized_output_dir: &str,
|
|
44
|
+
global_store: &mut GlobalStore,
|
|
45
|
+
) {
|
|
46
|
+
let logger = Logger::new();
|
|
47
|
+
|
|
48
|
+
let audio_engines =
|
|
49
|
+
render_audio_with_modules(modules.clone(), &normalized_output_dir, global_store);
|
|
50
|
+
|
|
51
|
+
create_dir_all(format!("{}/audio", normalized_output_dir))
|
|
52
|
+
.expect("Failed to create audio directory");
|
|
53
|
+
|
|
54
|
+
for (module_name, mut audio_engine) in audio_engines {
|
|
55
|
+
let formatted_module_name = module_name
|
|
56
|
+
.split('/')
|
|
57
|
+
.last()
|
|
58
|
+
.unwrap_or(&module_name)
|
|
59
|
+
.replace(".deva", "");
|
|
60
|
+
|
|
61
|
+
let output_path = format!(
|
|
62
|
+
"{}/audio/{}.wav",
|
|
63
|
+
normalized_output_dir, formatted_module_name
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
match audio_engine.generate_wav_file(&output_path) {
|
|
67
|
+
Ok(_) => {}
|
|
68
|
+
Err(msg) => {
|
|
69
|
+
logger.log_error_with_stacktrace(
|
|
70
|
+
&format!(
|
|
71
|
+
"Unable to generate WAV file for module '{}': {}",
|
|
72
|
+
formatted_module_name, msg
|
|
73
|
+
),
|
|
74
|
+
&module_name,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
use
|
|
2
|
-
use
|
|
3
|
-
|
|
4
|
-
pub fn write_lexer_log_file(
|
|
5
|
-
output_dir: &str,
|
|
6
|
-
file_name: &str,
|
|
7
|
-
modules: HashMap<String, Vec<Token
|
|
8
|
-
) {
|
|
9
|
-
let debugger = Debugger::new();
|
|
10
|
-
let mut content = String::new();
|
|
11
|
-
|
|
12
|
-
let log_directory = format!("{}/logs", output_dir);
|
|
13
|
-
|
|
14
|
-
create_dir_all(&log_directory).expect("Failed to create log directory");
|
|
15
|
-
|
|
16
|
-
for (path, tokens) in modules {
|
|
17
|
-
content.push_str(&format!("--- Resolved Tokens for {} ---\n", path));
|
|
18
|
-
|
|
19
|
-
for token in tokens {
|
|
20
|
-
content.push_str(&format!("{:?}\n", token));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
content.push_str("\n");
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
debugger.write_log_file(&log_directory, file_name, &content);
|
|
27
|
-
}
|
|
1
|
+
use crate::core::{debugger::Debugger, lexer::token::Token};
|
|
2
|
+
use std::{collections::HashMap, fs::create_dir_all};
|
|
3
|
+
|
|
4
|
+
pub fn write_lexer_log_file(
|
|
5
|
+
output_dir: &str,
|
|
6
|
+
file_name: &str,
|
|
7
|
+
modules: HashMap<String, Vec<Token>>,
|
|
8
|
+
) {
|
|
9
|
+
let debugger = Debugger::new();
|
|
10
|
+
let mut content = String::new();
|
|
11
|
+
|
|
12
|
+
let log_directory = format!("{}/logs", output_dir);
|
|
13
|
+
|
|
14
|
+
create_dir_all(&log_directory).expect("Failed to create log directory");
|
|
15
|
+
|
|
16
|
+
for (path, tokens) in modules {
|
|
17
|
+
content.push_str(&format!("--- Resolved Tokens for {} ---\n", path));
|
|
18
|
+
|
|
19
|
+
for token in tokens {
|
|
20
|
+
content.push_str(&format!("{:?}\n", token));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
content.push_str("\n");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
debugger.write_log_file(&log_directory, file_name, &content);
|
|
27
|
+
}
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
pub mod
|
|
2
|
-
pub mod
|
|
3
|
-
pub mod
|
|
4
|
-
pub mod
|
|
5
|
-
|
|
6
|
-
use std::io::Write;
|
|
7
|
-
|
|
8
|
-
pub struct Debugger {}
|
|
9
|
-
|
|
10
|
-
impl Debugger {
|
|
11
|
-
pub fn new() -> Self {
|
|
12
|
-
Debugger {}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
pub fn write_log_file(&self, path: &str, filename: &str, content: &str) {
|
|
16
|
-
std::fs::create_dir_all(path).expect("Failed to create directory");
|
|
17
|
-
|
|
18
|
-
let file_path = format!("{}/{}", path, filename);
|
|
19
|
-
let mut file = std::fs::File::create(file_path).expect("Failed to create file");
|
|
20
|
-
|
|
21
|
-
file.write_all(content.as_bytes())
|
|
22
|
-
|
|
23
|
-
}
|
|
1
|
+
pub mod lexer;
|
|
2
|
+
pub mod module;
|
|
3
|
+
pub mod preprocessor;
|
|
4
|
+
pub mod store;
|
|
5
|
+
|
|
6
|
+
use std::io::Write;
|
|
7
|
+
|
|
8
|
+
pub struct Debugger {}
|
|
9
|
+
|
|
10
|
+
impl Debugger {
|
|
11
|
+
pub fn new() -> Self {
|
|
12
|
+
Debugger {}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
pub fn write_log_file(&self, path: &str, filename: &str, content: &str) {
|
|
16
|
+
std::fs::create_dir_all(path).expect("Failed to create directory");
|
|
17
|
+
|
|
18
|
+
let file_path = format!("{}/{}", path, filename);
|
|
19
|
+
let mut file = std::fs::File::create(file_path).expect("Failed to create file");
|
|
20
|
+
|
|
21
|
+
file.write_all(content.as_bytes())
|
|
22
|
+
.expect("Failed to write to file");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,47 +1,55 @@
|
|
|
1
|
-
use
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
pub fn write_module_variable_log_file(
|
|
8
|
-
output_dir: &str,
|
|
9
|
-
module_path: &str,
|
|
10
|
-
variable_table: &VariableTable
|
|
11
|
-
) {
|
|
12
|
-
let debugger = Debugger::new();
|
|
13
|
-
let mut content = String::new();
|
|
14
|
-
let module_name = module_path
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
let
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
1
|
+
use crate::core::{
|
|
2
|
+
debugger::Debugger,
|
|
3
|
+
store::{function::FunctionTable, variable::VariableTable},
|
|
4
|
+
};
|
|
5
|
+
use std::fs::create_dir_all;
|
|
6
|
+
|
|
7
|
+
pub fn write_module_variable_log_file(
|
|
8
|
+
output_dir: &str,
|
|
9
|
+
module_path: &str,
|
|
10
|
+
variable_table: &VariableTable,
|
|
11
|
+
) {
|
|
12
|
+
let debugger = Debugger::new();
|
|
13
|
+
let mut content = String::new();
|
|
14
|
+
let module_name = module_path
|
|
15
|
+
.split('/')
|
|
16
|
+
.last()
|
|
17
|
+
.unwrap_or("index")
|
|
18
|
+
.replace(".deva", "");
|
|
19
|
+
|
|
20
|
+
let log_directory = format!("{}/logs/modules/{}", output_dir, module_name);
|
|
21
|
+
create_dir_all(&log_directory).expect("Failed to create log directory");
|
|
22
|
+
|
|
23
|
+
for (var_name, var_data) in &variable_table.variables {
|
|
24
|
+
content.push_str(&format!("{:?} = {:?}\n", var_name, var_data));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
content.push_str("\n");
|
|
28
|
+
|
|
29
|
+
debugger.write_log_file(&log_directory, "variables.log", &content);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
pub fn write_module_function_log_file(
|
|
33
|
+
output_dir: &str,
|
|
34
|
+
module_path: &str,
|
|
35
|
+
function_table: &FunctionTable,
|
|
36
|
+
) {
|
|
37
|
+
let debugger = Debugger::new();
|
|
38
|
+
let mut content = String::new();
|
|
39
|
+
let module_name = module_path
|
|
40
|
+
.split('/')
|
|
41
|
+
.last()
|
|
42
|
+
.unwrap_or("index")
|
|
43
|
+
.replace(".deva", "");
|
|
44
|
+
|
|
45
|
+
let log_directory = format!("{}/logs/modules/{}", output_dir, module_name);
|
|
46
|
+
create_dir_all(&log_directory).expect("Failed to create log directory");
|
|
47
|
+
|
|
48
|
+
for (func_name, func_data) in &function_table.functions {
|
|
49
|
+
content.push_str(&format!("{:?} = {:?}\n", func_name, func_data));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
content.push_str("\n");
|
|
53
|
+
|
|
54
|
+
debugger.write_log_file(&log_directory, "functions.log", &content);
|
|
55
|
+
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
use
|
|
2
|
-
use
|
|
3
|
-
|
|
4
|
-
pub fn write_preprocessor_log_file(
|
|
5
|
-
output_dir: &str,
|
|
6
|
-
file_name: &str,
|
|
7
|
-
modules: HashMap<String, Vec<Statement
|
|
8
|
-
) {
|
|
9
|
-
let debugger = Debugger::new();
|
|
10
|
-
let mut content = String::new();
|
|
11
|
-
|
|
12
|
-
let log_directory = format!("{}/logs", output_dir);
|
|
13
|
-
|
|
14
|
-
create_dir_all(&log_directory).expect("Failed to create log directory");
|
|
15
|
-
|
|
16
|
-
for (path, stmts) in modules {
|
|
17
|
-
content.push_str(&format!("--- Resolved Statements for {} ---\n", path));
|
|
18
|
-
|
|
19
|
-
for stmt in stmts {
|
|
20
|
-
content.push_str(&format!("{:?}\n", stmt));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
content.push_str("\n");
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
debugger.write_log_file(&log_directory, file_name, &content);
|
|
27
|
-
}
|
|
1
|
+
use crate::core::{debugger::Debugger, parser::statement::Statement};
|
|
2
|
+
use std::{collections::HashMap, fs::create_dir_all};
|
|
3
|
+
|
|
4
|
+
pub fn write_preprocessor_log_file(
|
|
5
|
+
output_dir: &str,
|
|
6
|
+
file_name: &str,
|
|
7
|
+
modules: HashMap<String, Vec<Statement>>,
|
|
8
|
+
) {
|
|
9
|
+
let debugger = Debugger::new();
|
|
10
|
+
let mut content = String::new();
|
|
11
|
+
|
|
12
|
+
let log_directory = format!("{}/logs", output_dir);
|
|
13
|
+
|
|
14
|
+
create_dir_all(&log_directory).expect("Failed to create log directory");
|
|
15
|
+
|
|
16
|
+
for (path, stmts) in modules {
|
|
17
|
+
content.push_str(&format!("--- Resolved Statements for {} ---\n", path));
|
|
18
|
+
|
|
19
|
+
for stmt in stmts {
|
|
20
|
+
content.push_str(&format!("{:?}\n", stmt));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
content.push_str("\n");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
debugger.write_log_file(&log_directory, file_name, &content);
|
|
27
|
+
}
|
|
@@ -1,39 +1,40 @@
|
|
|
1
|
-
use
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
pub fn write_variables_log_file(output_dir: &str, file_name: &str, variables: VariableTable) {
|
|
8
|
-
let debugger = Debugger::new();
|
|
9
|
-
let mut content = String::new();
|
|
10
|
-
|
|
11
|
-
let log_directory = format!("{}/logs", output_dir);
|
|
12
|
-
create_dir_all(&log_directory).expect("Failed to create log directory");
|
|
13
|
-
|
|
14
|
-
for (var_name, var_data) in variables.variables {
|
|
15
|
-
content.push_str(&format!("{:?} = {:?}\n", var_name, var_data));
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
content.push_str("\n");
|
|
19
|
-
|
|
20
|
-
debugger.write_log_file(&log_directory, file_name, &content);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
pub fn write_function_log_file(output_dir: &str, file_name: &str, functions: FunctionTable) {
|
|
24
|
-
let debugger = Debugger::new();
|
|
25
|
-
let mut content = String::new();
|
|
26
|
-
|
|
27
|
-
let log_directory = format!("{}/logs", output_dir);
|
|
28
|
-
create_dir_all(&log_directory).expect("Failed to create log directory");
|
|
29
|
-
|
|
30
|
-
for (
|
|
31
|
-
content.push_str(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
1
|
+
use crate::core::{
|
|
2
|
+
debugger::Debugger,
|
|
3
|
+
store::{function::FunctionTable, variable::VariableTable},
|
|
4
|
+
};
|
|
5
|
+
use std::fs::create_dir_all;
|
|
6
|
+
|
|
7
|
+
pub fn write_variables_log_file(output_dir: &str, file_name: &str, variables: VariableTable) {
|
|
8
|
+
let debugger = Debugger::new();
|
|
9
|
+
let mut content = String::new();
|
|
10
|
+
|
|
11
|
+
let log_directory = format!("{}/logs", output_dir);
|
|
12
|
+
create_dir_all(&log_directory).expect("Failed to create log directory");
|
|
13
|
+
|
|
14
|
+
for (var_name, var_data) in variables.variables {
|
|
15
|
+
content.push_str(&format!("{:?} = {:?}\n", var_name, var_data));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
content.push_str("\n");
|
|
19
|
+
|
|
20
|
+
debugger.write_log_file(&log_directory, file_name, &content);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
pub fn write_function_log_file(output_dir: &str, file_name: &str, functions: FunctionTable) {
|
|
24
|
+
let debugger = Debugger::new();
|
|
25
|
+
let mut content = String::new();
|
|
26
|
+
|
|
27
|
+
let log_directory = format!("{}/logs", output_dir);
|
|
28
|
+
create_dir_all(&log_directory).expect("Failed to create log directory");
|
|
29
|
+
|
|
30
|
+
for (_index, function) in functions.functions {
|
|
31
|
+
content.push_str(&format!(
|
|
32
|
+
"'{}' = [{:?}] => {:?}\n",
|
|
33
|
+
function.name, function.parameters, function.body
|
|
34
|
+
));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
content.push_str("\n");
|
|
38
|
+
|
|
39
|
+
debugger.write_log_file(&log_directory, file_name, &content);
|
|
40
|
+
}
|