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()
25
89
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!("AST is {:?}", ast);
@ -136,12 +168,12 @@ pub fn compile_ast(ast: AST) {
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);
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());
}
@ -152,37 +184,37 @@ pub fn compile_ast(ast: AST) {
}
trait CodeGen {
fn codegen(&self, LLVMContextRef) -> LLVMValueRef;
fn codegen(&self, LLVMContextRef, LLVMBuilderRef) -> LLVMValueRef;
}
impl CodeGen for AST {
fn codegen(&self, context: LLVMContextRef) -> LLVMValueRef {
fn codegen(&self, context: LLVMContextRef, builder: LLVMBuilderRef) -> LLVMValueRef {
let first = self.get(0).unwrap();
first.codegen(context)
first.codegen(context, builder)
}
}
impl CodeGen for ASTNode {
fn codegen(&self, context: LLVMContextRef) -> LLVMValueRef {
fn codegen(&self, context: LLVMContextRef, builder: LLVMBuilderRef) -> LLVMValueRef {
use self::ASTNode::*;
match self {
&ExprNode(ref expr) => expr.codegen(context),
&FuncNode(ref func) => func.codegen(context),
&ExprNode(ref expr) => expr.codegen(context, builder),
&FuncNode(ref func) => func.codegen(context, builder),
}
}
}
impl CodeGen for Function {
fn codegen(&self, context: LLVMContextRef) -> LLVMValueRef {
fn codegen(&self, context: LLVMContextRef, builder: LLVMBuilderRef) -> LLVMValueRef {
let ref body = self.body;
let first = body.get(0).unwrap();
first.codegen(context)
first.codegen(context, builder)
}
}
impl CodeGen for Expression {
fn codegen(&self, context: LLVMContextRef) -> LLVMValueRef {
fn codegen(&self, context: LLVMContextRef, builder: LLVMBuilderRef) -> LLVMValueRef {
use self::Expression::*;
let int_type = LLVMWrap::Int64TypeInContext(context);

View File

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