commit 9e4d4085ba5587c0ef7681d9ccafdc24aadc66a8 Author: Jooris Hadeler Date: Wed Mar 11 21:43:19 2026 +0100 init: This is the initial commit. This commit marks the start of the project. This adds a simple command line interface which can be found in `src/cli.rs`. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..57aee68 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "buckyc" +version = "0.1.0" +dependencies = [ + "yansi", +] + +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e185849 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "buckyc" +version = "0.1.0" +edition = "2024" + +[dependencies] +yansi = "1.0.1" diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..0c0187a --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,114 @@ +use std::path::PathBuf; + +use yansi::Paint; + +pub fn print_help() { + println!( + "{} {} - the bucky language compiler", + "buckyc".bold(), + env!("CARGO_PKG_VERSION").dim() + ); + + println!(); + println!("{}", "USAGE:".bold().yellow()); + println!(" fluxc [OPTIONS] [ ...]"); + + println!(); + println!("{}", "OPTIONS:".bold().yellow()); + println!( + " {}, {} Print this help message", + "-h".bold(), + "--help".bold() + ); + println!( + " {}, {} Print version information", + "-V".bold(), + "--version".bold() + ); + println!( + " {} Emit IR and stop (implies `-c`)", + "-S".bold() + ); + println!( + " {} Compile to object file (no linking)", + "-c".bold() + ); + println!( + " {} {} Write output to ", + "-o".bold(), + "".bold(), + ); + + println!(); + println!("{}", "ARGS:".bold().yellow()); + println!( + " {} One or more Flux source files to compile", + "".bold(), + ); +} + +pub fn print_version() { + println!("buckyc {}", env!("CARGO_PKG_VERSION")); +} + +pub fn fatal(message: impl ToString) -> ! { + eprintln!("{}: {}", "error".bold().red(), message.to_string().bold()); + std::process::exit(1); +} + +#[derive(Debug)] +pub struct Opts { + /// The list of files passed to the compiler. + pub files: Vec, + /// `-S`: emit IR and stop (implies `-c`). + pub emit_ir: bool, + /// `-c`: compile source to object file without linking. + pub no_link: bool, + /// `-o `: write final output to this path. + pub output: Option, +} + +pub fn parse_args() -> Opts { + let mut files = Vec::new(); + let mut no_link = false; + let mut emit_ir = false; + let mut output = None; + + let mut args = std::env::args().skip(1).peekable(); + while let Some(arg) = args.next() { + match arg.as_str() { + "-h" | "--help" => { + print_help(); + std::process::exit(0); + } + "-V" | "--version" => { + print_version(); + std::process::exit(0); + } + "-c" => no_link = true, + "-S" => { + emit_ir = true; + no_link = true + } + "-o" => match args.next() { + Some(path) => output = Some(path.into()), + None => fatal("option `-o` requires an argument"), + }, + flag if flag.starts_with('-') => { + fatal(format!("unknown option `{flag}`")); + } + path => files.push(path.into()), + } + } + + if files.is_empty() { + fatal("no input files - at least one source file is required"); + } + + Opts { + files, + emit_ir, + no_link, + output, + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..c50cc74 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,9 @@ +use crate::cli::parse_args; + +mod cli; + +fn main() { + let opts = parse_args(); + + println!("{opts:#?}"); +}