Compilation sequence
-move all steps of the llvm IR compilation process into the binary
This commit is contained in:
parent
c032da712f
commit
95b773de7f
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
fn main()
|
fn main()
|
||||||
25
|
89
|
||||||
end
|
end
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user