Feat: add LLVM IR backend with opt/llc pipeline
Implements a full LLVM IR text emitter and three-step toolchain:
1. Emit LLVM IR (.ll) via alloca-based codegen (mem2reg-friendly)
2. `opt -O2` → optimised IR (override with FLUXC_OPT)
3. `llc -filetype=obj` → object file (override with FLUXC_LLC)
4. `cc` → link into executable (override with FLUXC_CC)
(step 4 skipped in -c mode)
Emitter supports all Flux types, operators, control flow (if/else,
while, loop, break, continue), structs, arrays, pointer operations,
function calls, string literals, and integer literal type inference
via UnboundInt → concrete-type coercion.
Also adds -o <file> CLI flag, exposes CheckResult from the checker
(sigma + phi tables reused by codegen), and updates main.rs to run
the full parse → check → codegen pipeline.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -24,9 +24,14 @@ pub fn print_help() {
|
||||
"--version".bold(),
|
||||
);
|
||||
println!(
|
||||
" {} Compile without requiring a `main` entry point",
|
||||
" {} Compile to object file (no `main` required, no linking)",
|
||||
"-c".bold(),
|
||||
);
|
||||
println!(
|
||||
" {} {} Write output to <file>",
|
||||
"-o".bold(),
|
||||
"<file>".bold(),
|
||||
);
|
||||
println!();
|
||||
println!("{}", "ARGS:".bold().yellow());
|
||||
println!(
|
||||
@@ -61,15 +66,19 @@ pub fn io_error(path: &str, err: std::io::Error) -> ! {
|
||||
|
||||
pub struct Opts {
|
||||
pub files: Vec<String>,
|
||||
/// `-c`: compile without requiring a `main` entry point.
|
||||
/// `-c`: compile to object file without requiring a `main` entry point.
|
||||
pub no_main: bool,
|
||||
/// `-o <file>`: write final output to this path.
|
||||
pub output: Option<String>,
|
||||
}
|
||||
|
||||
pub fn parse_args() -> Opts {
|
||||
let mut files = Vec::new();
|
||||
let mut no_main = false;
|
||||
let mut output: Option<String> = None;
|
||||
let mut args = std::env::args().skip(1).peekable();
|
||||
|
||||
for arg in std::env::args().skip(1) {
|
||||
while let Some(arg) = args.next() {
|
||||
match arg.as_str() {
|
||||
"-h" | "--help" => {
|
||||
print_help();
|
||||
@@ -80,6 +89,10 @@ pub fn parse_args() -> Opts {
|
||||
process::exit(0);
|
||||
}
|
||||
"-c" => no_main = true,
|
||||
"-o" => match args.next() {
|
||||
Some(path) => output = Some(path),
|
||||
None => fatal("option `-o` requires an argument"),
|
||||
},
|
||||
flag if flag.starts_with('-') => {
|
||||
fatal(&format!("unknown option `{flag}`"));
|
||||
}
|
||||
@@ -91,5 +104,9 @@ pub fn parse_args() -> Opts {
|
||||
fatal("no input files — at least one source file is required");
|
||||
}
|
||||
|
||||
Opts { files, no_main }
|
||||
Opts {
|
||||
files,
|
||||
no_main,
|
||||
output,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user