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`.
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
16
Cargo.lock
generated
Normal file
16
Cargo.lock
generated
Normal file
@@ -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"
|
||||||
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "buckyc"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
yansi = "1.0.1"
|
||||||
114
src/cli.rs
Normal file
114
src/cli.rs
Normal file
@@ -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] <file> [<file> ...]");
|
||||||
|
|
||||||
|
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 <file>",
|
||||||
|
"-o".bold(),
|
||||||
|
"<file>".bold(),
|
||||||
|
);
|
||||||
|
|
||||||
|
println!();
|
||||||
|
println!("{}", "ARGS:".bold().yellow());
|
||||||
|
println!(
|
||||||
|
" {} One or more Flux source files to compile",
|
||||||
|
"<file>".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<PathBuf>,
|
||||||
|
/// `-S`: emit IR and stop (implies `-c`).
|
||||||
|
pub emit_ir: bool,
|
||||||
|
/// `-c`: compile source to object file without linking.
|
||||||
|
pub no_link: bool,
|
||||||
|
/// `-o <file>`: write final output to this path.
|
||||||
|
pub output: Option<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/main.rs
Normal file
9
src/main.rs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
use crate::cli::parse_args;
|
||||||
|
|
||||||
|
mod cli;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let opts = parse_args();
|
||||||
|
|
||||||
|
println!("{opts:#?}");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user