Formatting

This commit is contained in:
Michael Schimmel
2026-02-22 02:35:06 +01:00
parent 2123f1d279
commit 329b885c4b
25 changed files with 8053 additions and 6400 deletions
+134 -132
View File
@@ -1,132 +1,134 @@
use myc::ast::environment::Environment;
use myc::utils::tester;
use clap::Parser;
use std::fs;
use std::path::PathBuf;
#[derive(Parser)]
#[command(author, version, about = "MYC AST Compiler & Benchmarker", long_about = None)]
struct Cli {
/// The script file to run or benchmark
#[arg(value_name = "FILE")]
file: Option<PathBuf>,
/// Run a script string directly
#[arg(short, long)]
eval: Option<String>,
/// Run benchmarks (Only allowed in Release mode)
#[arg(short, long)]
bench: bool,
/// Update the benchmark baseline (Only allowed in Release mode)
#[arg(short, long)]
update_bench: bool,
/// Dump the compiled AST
#[arg(short, long)]
dump: bool,
/// Run with TracingObserver enabled
#[arg(short, long)]
trace: bool,
/// Disable optimization
#[arg(long)]
no_opt: bool,
}
fn main() {
let cli = Cli::parse();
let mut env = Environment::new();
env.optimization = !cli.no_opt;
if cli.bench || cli.update_bench {
if cfg!(debug_assertions) {
eprintln!("❌ ERROR: Benchmarks must be run in Release mode!");
eprintln!(" Use: cargo run --release --bin ast -- --bench");
std::process::exit(1);
}
println!("🚀 Running benchmarks in RELEASE mode...\n");
let results = tester::run_benchmarks(cli.update_bench);
for res in results {
let diff = res.diff_pct.map_or(String::new(), |d| format!(" ({:+.1}%)", d));
println!("{}: {} - {:?}{}", res.status, res.name, res.median, diff);
}
return;
}
if let Some(script_str) = cli.eval {
if cli.dump {
match env.dump_ast(&script_str) {
Ok(dump) => println!("{}", dump),
Err(e) => eprintln!("Error dumping AST: {}", e),
}
} else if cli.trace {
execute_trace(&mut env, &script_str);
} else {
execute(&env, &script_str);
}
} else if let Some(file_path) = cli.file {
match fs::read_to_string(&file_path) {
Ok(content) => {
if cli.dump {
match env.dump_ast(&content) {
Ok(dump) => println!("{}", dump),
Err(e) => eprintln!("Error dumping AST: {}", e),
}
} else if cli.trace {
execute_trace(&mut env, &content);
} else {
execute(&env, &content);
}
},
Err(e) => {
eprintln!("Error reading file {:?}: {}", file_path, e);
std::process::exit(1);
}
}
} else {
println!("MYC AST Compiler CLI. Use --help for usage.");
}
}
fn execute(env: &Environment, source: &str) {
match env.run_script(source) {
Ok(result) => println!("{}", result),
Err(e) => {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
}
fn execute_trace(env: &mut Environment, source: &str) {
match env.compile(source) {
Ok(compiled) => {
let linked = env.link(compiled);
let mut vm = myc::ast::vm::VM::new(env.global_values.clone());
let mut observer = myc::ast::vm::TracingObserver::new();
match vm.run_with_observer(&mut observer, &linked) {
Ok(result) => {
for line in observer.logs {
println!("{}", line);
}
println!("Result: {}", result);
}
Err(e) => {
for line in observer.logs {
println!("{}", line);
}
eprintln!("Runtime Error: {}", e);
std::process::exit(1);
}
}
}
Err(e) => {
eprintln!("Compilation Error: {}", e);
std::process::exit(1);
}
}
}
use clap::Parser;
use myc::ast::environment::Environment;
use myc::utils::tester;
use std::fs;
use std::path::PathBuf;
#[derive(Parser)]
#[command(author, version, about = "MYC AST Compiler & Benchmarker", long_about = None)]
struct Cli {
/// The script file to run or benchmark
#[arg(value_name = "FILE")]
file: Option<PathBuf>,
/// Run a script string directly
#[arg(short, long)]
eval: Option<String>,
/// Run benchmarks (Only allowed in Release mode)
#[arg(short, long)]
bench: bool,
/// Update the benchmark baseline (Only allowed in Release mode)
#[arg(short, long)]
update_bench: bool,
/// Dump the compiled AST
#[arg(short, long)]
dump: bool,
/// Run with TracingObserver enabled
#[arg(short, long)]
trace: bool,
/// Disable optimization
#[arg(long)]
no_opt: bool,
}
fn main() {
let cli = Cli::parse();
let mut env = Environment::new();
env.optimization = !cli.no_opt;
if cli.bench || cli.update_bench {
if cfg!(debug_assertions) {
eprintln!("❌ ERROR: Benchmarks must be run in Release mode!");
eprintln!(" Use: cargo run --release --bin ast -- --bench");
std::process::exit(1);
}
println!("🚀 Running benchmarks in RELEASE mode...\n");
let results = tester::run_benchmarks(cli.update_bench);
for res in results {
let diff = res
.diff_pct
.map_or(String::new(), |d| format!(" ({:+.1}%)", d));
println!("{}: {} - {:?}{}", res.status, res.name, res.median, diff);
}
return;
}
if let Some(script_str) = cli.eval {
if cli.dump {
match env.dump_ast(&script_str) {
Ok(dump) => println!("{}", dump),
Err(e) => eprintln!("Error dumping AST: {}", e),
}
} else if cli.trace {
execute_trace(&mut env, &script_str);
} else {
execute(&env, &script_str);
}
} else if let Some(file_path) = cli.file {
match fs::read_to_string(&file_path) {
Ok(content) => {
if cli.dump {
match env.dump_ast(&content) {
Ok(dump) => println!("{}", dump),
Err(e) => eprintln!("Error dumping AST: {}", e),
}
} else if cli.trace {
execute_trace(&mut env, &content);
} else {
execute(&env, &content);
}
}
Err(e) => {
eprintln!("Error reading file {:?}: {}", file_path, e);
std::process::exit(1);
}
}
} else {
println!("MYC AST Compiler CLI. Use --help for usage.");
}
}
fn execute(env: &Environment, source: &str) {
match env.run_script(source) {
Ok(result) => println!("{}", result),
Err(e) => {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
}
fn execute_trace(env: &mut Environment, source: &str) {
match env.compile(source) {
Ok(compiled) => {
let linked = env.link(compiled);
let mut vm = myc::ast::vm::VM::new(env.global_values.clone());
let mut observer = myc::ast::vm::TracingObserver::new();
match vm.run_with_observer(&mut observer, &linked) {
Ok(result) => {
for line in observer.logs {
println!("{}", line);
}
println!("Result: {}", result);
}
Err(e) => {
for line in observer.logs {
println!("{}", line);
}
eprintln!("Runtime Error: {}", e);
std::process::exit(1);
}
}
}
Err(e) => {
eprintln!("Compilation Error: {}", e);
std::process::exit(1);
}
}
}