Compilation sequence

-move all steps of the llvm IR compilation process into the binary
This commit is contained in:
greg 2016-12-25 22:37:46 -08:00
parent c032da712f
commit 95b773de7f
3 changed files with 47 additions and 15 deletions

View File

@ -1,5 +1,5 @@
fn main() fn main()
25 89
end end

View File

@ -114,7 +114,39 @@ mod LLVMWrap {
} }
} }
pub fn compile_ast(ast: AST) { pub fn compilation_sequence(ast: AST, sourcefile: &str) {
use std::process::Command;
let ll_filename = "out.ll";
let obj_filename = "out.o";
let q: Vec<&str> = sourcefile.split('.').collect();
let bin_filename = match &q[..] {
&[name, "schala"] => name,
_ => panic!("Bad filename {}", sourcefile),
};
compile_ast(ast, ll_filename);
Command::new("llc")
.arg("-filetype=obj")
.arg(ll_filename)
.output()
.expect("Failed to run llc");
Command::new("gcc")
.arg(format!("-o{}", bin_filename))
.arg(obj_filename)
.output()
.expect("failed to run gcc");
for filename in [ll_filename, obj_filename].iter() {
Command::new("rm")
.arg(ll_filename)
.output()
.expect(&format!("failed to run rm {}", filename));
}
}
fn compile_ast(ast: AST, filename: &str) {
println!("Compiling!"); println!("Compiling!");
println!("AST is {:?}", ast); println!("AST is {:?}", ast);
@ -136,12 +168,12 @@ pub fn compile_ast(ast: AST) {
let int_value = LLVMWrap::ConstInt(int_type, int_value, false); let int_value = LLVMWrap::ConstInt(int_type, int_value, false);
*/ */
let value = ast.codegen(context); let value = ast.codegen(context, builder);
LLVMWrap::BuildRet(builder, value); LLVMWrap::BuildRet(builder, value);
unsafe { unsafe {
let out_file = CString::new("out.ll").unwrap(); let out_file = CString::new(filename).unwrap();
core::LLVMPrintModuleToFile(module, out_file.as_ptr(), ptr::null_mut()); core::LLVMPrintModuleToFile(module, out_file.as_ptr(), ptr::null_mut());
} }
@ -152,37 +184,37 @@ pub fn compile_ast(ast: AST) {
} }
trait CodeGen { trait CodeGen {
fn codegen(&self, LLVMContextRef) -> LLVMValueRef; fn codegen(&self, LLVMContextRef, LLVMBuilderRef) -> LLVMValueRef;
} }
impl CodeGen for AST { impl CodeGen for AST {
fn codegen(&self, context: LLVMContextRef) -> LLVMValueRef { fn codegen(&self, context: LLVMContextRef, builder: LLVMBuilderRef) -> LLVMValueRef {
let first = self.get(0).unwrap(); let first = self.get(0).unwrap();
first.codegen(context) first.codegen(context, builder)
} }
} }
impl CodeGen for ASTNode { impl CodeGen for ASTNode {
fn codegen(&self, context: LLVMContextRef) -> LLVMValueRef { fn codegen(&self, context: LLVMContextRef, builder: LLVMBuilderRef) -> LLVMValueRef {
use self::ASTNode::*; use self::ASTNode::*;
match self { match self {
&ExprNode(ref expr) => expr.codegen(context), &ExprNode(ref expr) => expr.codegen(context, builder),
&FuncNode(ref func) => func.codegen(context), &FuncNode(ref func) => func.codegen(context, builder),
} }
} }
} }
impl CodeGen for Function { impl CodeGen for Function {
fn codegen(&self, context: LLVMContextRef) -> LLVMValueRef { fn codegen(&self, context: LLVMContextRef, builder: LLVMBuilderRef) -> LLVMValueRef {
let ref body = self.body; let ref body = self.body;
let first = body.get(0).unwrap(); let first = body.get(0).unwrap();
first.codegen(context) first.codegen(context, builder)
} }
} }
impl CodeGen for Expression { impl CodeGen for Expression {
fn codegen(&self, context: LLVMContextRef) -> LLVMValueRef { fn codegen(&self, context: LLVMContextRef, builder: LLVMBuilderRef) -> LLVMValueRef {
use self::Expression::*; use self::Expression::*;
let int_type = LLVMWrap::Int64TypeInContext(context); let int_type = LLVMWrap::Int64TypeInContext(context);

View File

@ -17,7 +17,7 @@ mod parser;
use eval::{Evaluator}; use eval::{Evaluator};
mod eval; mod eval;
use compilation::{compile_ast}; use compilation::{compilation_sequence};
mod compilation; mod compilation;
fn main() { fn main() {
@ -47,7 +47,7 @@ fn run_noninteractive(filename: &String) {
let compile = true; let compile = true;
if compile { if compile {
compile_ast(ast); compilation_sequence(ast, filename);
} else { } else {
let mut evaluator = Evaluator::new(); let mut evaluator = Evaluator::new();
let results = evaluator.run(ast); let results = evaluator.run(ast);