Phase 5: Editor und inkrementellen Compiler implementieren und archivieren

This commit is contained in:
2026-09-06 17:58:26 +02:00
parent df85a4b7b2
commit 9c85349a4d
36 changed files with 2993 additions and 247 deletions

View File

@@ -44,7 +44,59 @@ fn compile_all(sources: &[(String, String)]) -> usize {
project.procs.iter().map(|p| p.code.len()).sum()
}
fn incremental(sources: &[(String, String)], budget: f64) {
let mut units: Vec<_> = sources
.iter()
.map(|(n, s)| tb_frontend::source::SourceUnit::new(n, &format!("{n}.bas"), s))
.collect();
let mut compiler = tb_vm::project::ProjectCompiler::default();
compiler
.compile("BENCH", &units, &Default::default(), &[])
.unwrap();
let mut times = Vec::new();
for i in 0..7 {
// Private Rumpfänderung mit unverändertem öffentlichen Vertrag.
units[0].segments[0].text = sources[0]
.1
.replace("a% * 2 + b#", &format!("a% * {} + b#", 3 + i));
let start = Instant::now();
let code = compiler
.compile("BENCH", &units, &Default::default(), &[])
.unwrap();
std::hint::black_box(&code);
times.push(start.elapsed().as_secs_f64());
assert_eq!(compiler.stats.compiled, 1);
assert_eq!(compiler.stats.reused, units.len() - 1);
}
times.sort_by(f64::total_cmp);
let median = times[times.len() / 2];
println!(" Cacheänderung: {} Module, Median {:.2} ms (7 Läufe; Invalidierung + Link), {} neu / {} wiederverwendet; Budget {:.0} ms {}",units.len(),median*1000.0,compiler.stats.compiled,compiler.stats.reused,budget*1000.0,if median<budget {"OK"}else{"VERFEHLT"});
assert!(median < budget, "Cachebudget verfehlt");
}
fn main() {
println!(
"Hardware: {} / {} / {}",
std::env::consts::OS,
std::env::consts::ARCH,
std::process::Command::new(if cfg!(target_os = "macos") {
"sysctl"
} else {
"uname"
})
.args(if cfg!(target_os = "macos") {
vec!["-n", "machdep.cpu.brand_string"]
} else {
vec!["-m"]
})
.output()
.ok()
.map(|o| String::from_utf8_lossy(&o.stdout).trim().to_owned())
.unwrap_or_default()
);
println!(
"Profil: Release / opt-level=3, eigener Harness; cargo bench -p tb-vm --bench compile"
);
// Einzelnes Modul: ~500 Zeilen (Budget < 50 ms).
let single = generate_module(50, 0);
let single_lines = single.lines().count();
@@ -90,4 +142,6 @@ fn main() {
println!(" Durchsatz: {:.0} Zeilen/s", lps);
assert!(best_single < 0.050, "Einzelmodul-Budget verfehlt");
assert!(project_secs < 1.0, "Projekt-Budget verfehlt");
incremental(&[("EINZEL".into(), single)], 0.050);
incremental(&modules, 1.0);
}