feat: replace Cranelift JIT with C backend
Remove Cranelift JIT compiler and expose the existing C backend as the compilation target. Generated C code can be compiled with GCC/Clang. Changes: - Remove cranelift-* dependencies from Cargo.toml - Delete src/compiler.rs (565 lines of Cranelift code) - Add compile_to_c() function with -o and --run flags - Fix C backend name mangling (main -> main_lux) to avoid conflicts - Update CLI help text and documentation Usage: lux compile <file.lux> # Output C to stdout lux compile <file.lux> -o out.c # Write to file lux compile <file.lux> --run # Compile and execute C backend supports: functions, basic types, operators, if/then/else, records, enums, Console.print. Future work: closures, lists, patterns. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -82,7 +82,10 @@ impl CBackend {
|
||||
self.emit_function(f)?;
|
||||
}
|
||||
Declaration::Let(let_decl) => {
|
||||
self.emit_global_let(&let_decl.name, &let_decl.value)?;
|
||||
// Skip run expressions - they're handled in the main wrapper
|
||||
if !matches!(&let_decl.value, Expr::Run { .. }) {
|
||||
self.emit_global_let(&let_decl.name, &let_decl.value)?;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -245,12 +248,18 @@ impl CBackend {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mangle_name(&self, name: &str) -> String {
|
||||
// Add suffix to avoid conflicts with C keywords and standard library
|
||||
format!("{}_lux", name)
|
||||
}
|
||||
|
||||
fn emit_forward_declarations(&mut self, program: &Program) -> Result<(), CGenError> {
|
||||
for decl in &program.declarations {
|
||||
if let Declaration::Function(f) = decl {
|
||||
let ret_type = self.type_expr_to_c(&f.return_type)?;
|
||||
let params = self.emit_params(&f.params)?;
|
||||
self.writeln(&format!("{} {}({});", ret_type, f.name.name, params));
|
||||
let mangled = self.mangle_name(&f.name.name);
|
||||
self.writeln(&format!("{} {}({});", ret_type, mangled, params));
|
||||
}
|
||||
}
|
||||
self.writeln("");
|
||||
@@ -260,8 +269,9 @@ impl CBackend {
|
||||
fn emit_function(&mut self, func: &FunctionDecl) -> Result<(), CGenError> {
|
||||
let ret_type = self.type_expr_to_c(&func.return_type)?;
|
||||
let params = self.emit_params(&func.params)?;
|
||||
let mangled = self.mangle_name(&func.name.name);
|
||||
|
||||
self.writeln(&format!("{} {}({}) {{", ret_type, func.name.name, params));
|
||||
self.writeln(&format!("{} {}({}) {{", ret_type, mangled, params));
|
||||
self.indent += 1;
|
||||
|
||||
// Emit function body
|
||||
@@ -365,7 +375,14 @@ impl CBackend {
|
||||
let arg_strs: Result<Vec<_>, _> = args.iter().map(|a| self.emit_expr(a)).collect();
|
||||
let args_str = arg_strs?.join(", ");
|
||||
|
||||
Ok(format!("{}({})", func_name, args_str))
|
||||
// Mangle user-defined function names
|
||||
let c_func_name = if self.functions.contains(&func_name) {
|
||||
self.mangle_name(&func_name)
|
||||
} else {
|
||||
func_name
|
||||
};
|
||||
|
||||
Ok(format!("{}({})", c_func_name, args_str))
|
||||
}
|
||||
|
||||
Expr::Block { statements, result, .. } => {
|
||||
@@ -517,7 +534,8 @@ impl CBackend {
|
||||
if let Expr::Run { expr, .. } = &let_decl.value {
|
||||
if let Expr::Call { func, .. } = expr.as_ref() {
|
||||
if let Expr::Var(fn_name) = func.as_ref() {
|
||||
self.writeln(&format!("{}();", fn_name.name));
|
||||
let mangled = self.mangle_name(&fn_name.name);
|
||||
self.writeln(&format!("{}();", mangled));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -602,7 +620,7 @@ mod tests {
|
||||
fn add(a: Int, b: Int): Int = a + b
|
||||
"#;
|
||||
let c_code = generate(source).unwrap();
|
||||
assert!(c_code.contains("LuxInt add(LuxInt a, LuxInt b)"));
|
||||
assert!(c_code.contains("LuxInt add_lux(LuxInt a, LuxInt b)"));
|
||||
assert!(c_code.contains("return (a + b)"));
|
||||
}
|
||||
|
||||
@@ -613,8 +631,8 @@ mod tests {
|
||||
if n <= 1 then 1 else n * factorial(n - 1)
|
||||
"#;
|
||||
let c_code = generate(source).unwrap();
|
||||
assert!(c_code.contains("LuxInt factorial(LuxInt n)"));
|
||||
assert!(c_code.contains("factorial((n - 1))"));
|
||||
assert!(c_code.contains("LuxInt factorial_lux(LuxInt n)"));
|
||||
assert!(c_code.contains("factorial_lux((n - 1))"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user