1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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//! # VirtuC Compiler CLI
//!
//! This module provides the command-line interface for the `virtuc` compiler.
//! It handles parsing command-line arguments and orchestrating the compilation
//! process from source files to executable binaries.
//!
//! ## Usage
//!
//! ```bash
//! virtuc input.c -o output
//! ```
//!
//! ## Features
//!
//! - Compile C subset source files to native executables via LLVM
//! - Optional output file specification
use clap::{Parser, Subcommand};
use std::fs;
use std::path::Path;
use virtuc::compile;
#[derive(Parser)]
#[command(name = "virtuc")]
#[command(about = "A Rust-based subset C compiler")]
struct Args {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Compile C source to executable
Compile {
/// Input C source file
input: String,
/// Output executable file
#[arg(short, long)]
output: Option<String>,
},
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
match args.command {
Commands::Compile { input, output } => {
// Read input file
let source = fs::read_to_string(&input)?;
// Determine output file
// Note: Defaulting to ".out" extension is tailored towards macOS and Linux systems.
// Windows users should explicitly specify an output file with ".exe" extension.
let output_str =
output.unwrap_or_else(|| input.trim_end_matches(".c").to_string() + ".out");
let output_path = Path::new(&output_str);
// Compile
match compile(&source, output_path) {
Ok(_) => {
println!("Compiled {} to {}", input, output_str);
Ok(())
}
Err(e) => {
eprintln!("{}", e);
std::process::exit(1);
}
}
}
}
}