CLoser to working now

This commit is contained in:
greg 2017-01-10 18:07:16 -08:00
parent d6fc13f08d
commit 0b9dc113d1
3 changed files with 35 additions and 10 deletions

View File

@ -1,5 +1,9 @@
が = 80
a = 1 a = 1
b = 2 if a {
a + b + が a = 40
} else {
a = 2
}
a = a - 1
a

View File

@ -19,6 +19,7 @@ pub fn compilation_sequence(ast: AST, sourcefile: &str) {
}; };
compile_ast(ast, ll_filename); compile_ast(ast, ll_filename);
println!("YOLO");
Command::new("llc") Command::new("llc")
.arg("-filetype=obj") .arg("-filetype=obj")
.arg(ll_filename) .arg(ll_filename)
@ -31,6 +32,7 @@ pub fn compilation_sequence(ast: AST, sourcefile: &str) {
.output() .output()
.expect("failed to run gcc"); .expect("failed to run gcc");
println!("ai");
for filename in [obj_filename].iter() { for filename in [obj_filename].iter() {
Command::new("rm") Command::new("rm")
.arg(filename) .arg(filename)
@ -46,6 +48,7 @@ struct CompilationData {
module: LLVMModuleRef, module: LLVMModuleRef,
builder: LLVMBuilderRef, builder: LLVMBuilderRef,
variables: VariableMap, variables: VariableMap,
func: Option<LLVMValueRef>,
} }
fn compile_ast(ast: AST, filename: &str) { fn compile_ast(ast: AST, filename: &str) {
@ -61,12 +64,15 @@ fn compile_ast(ast: AST, filename: &str) {
module: module, module: module,
builder: builder, builder: builder,
variables: names, variables: names,
func: None,
}; };
let int_type = LLVMWrap::Int64TypeInContext(data.context); let int_type = LLVMWrap::Int64TypeInContext(data.context);
let function_type = LLVMWrap::FunctionType(int_type, &Vec::new(), false); let function_type = LLVMWrap::FunctionType(int_type, &Vec::new(), false);
let function = LLVMWrap::AddFunction(data.module, "main", function_type); let function = LLVMWrap::AddFunction(data.module, "main", function_type);
data.func = Some(function);
let bb = LLVMWrap::AppendBasicBlockInContext(data.context, function, "entry"); let bb = LLVMWrap::AppendBasicBlockInContext(data.context, function, "entry");
LLVMWrap::PositionBuilderAtEnd(builder, bb); LLVMWrap::PositionBuilderAtEnd(builder, bb);
@ -74,6 +80,7 @@ fn compile_ast(ast: AST, filename: &str) {
LLVMWrap::BuildRet(builder, value); LLVMWrap::BuildRet(builder, value);
println!("Printing {} to file", filename);
LLVMWrap::PrintModuleToFile(module, filename); LLVMWrap::PrintModuleToFile(module, filename);
// Clean up. Values created in the context mostly get cleaned up there. // Clean up. Values created in the context mostly get cleaned up there.
@ -123,10 +130,10 @@ impl CodeGen for Function {
impl CodeGen for Expression { impl CodeGen for Expression {
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef { fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
println!("Running codegen on: {:?}", self);
use self::Expression::*; use self::Expression::*;
let int_type = LLVMWrap::Int64TypeInContext(data.context); let int_type = LLVMWrap::Int64TypeInContext(data.context);
let zero = LLVMWrap::ConstInt(int_type, 0, false);
match *self { match *self {
Variable(ref name) => *data.variables.get(&**name).unwrap(), Variable(ref name) => *data.variables.get(&**name).unwrap(),
@ -160,7 +167,6 @@ impl CodeGen for Expression {
} }
Conditional(ref test, ref then_expr, ref else_expr) => { Conditional(ref test, ref then_expr, ref else_expr) => {
let condition_value = test.codegen(data); let condition_value = test.codegen(data);
let zero = LLVMWrap::ConstInt(int_type, 0, false);
let is_nonzero = let is_nonzero =
LLVMWrap::BuildICmp(data.builder, LLVMWrap::BuildICmp(data.builder,
llvm_sys::LLVMIntPredicate::LLVMIntNE, llvm_sys::LLVMIntPredicate::LLVMIntNE,
@ -168,7 +174,7 @@ impl CodeGen for Expression {
zero, zero,
"is_nonzero"); "is_nonzero");
let func: LLVMValueRef = zero; let func: LLVMValueRef = data.func.expect("lol no function here");
let then_block = let then_block =
LLVMWrap::AppendBasicBlockInContext(data.context, func, "entry"); LLVMWrap::AppendBasicBlockInContext(data.context, func, "entry");
let else_block = let else_block =
@ -179,15 +185,25 @@ impl CodeGen for Expression {
LLVMWrap::PositionBuilderAtEnd(data.builder, then_block); LLVMWrap::PositionBuilderAtEnd(data.builder, then_block);
let then_return = then_expr.codegen(data); let then_return = then_expr.codegen(data);
LLVMWrap::BuildBr(data.builder, merge_block); LLVMWrap::BuildBr(data.builder, merge_block);
let else_return = match else_expr { let else_return = match *else_expr {
&Some(e) => e.codegen(data), Some(ref e) => e.codegen(data),
&None => zero, None => zero,
}; };
LLVMWrap::BuildBr(data.builder, merge_block); LLVMWrap::BuildBr(data.builder, merge_block);
LLVMWrap::PositionBuilderAtEnd(data.builder, else_block); LLVMWrap::PositionBuilderAtEnd(data.builder, else_block);
zero zero
} }
_ => unimplemented!(), Block(ref exprs) => {
let mut ret = zero;
for e in exprs.iter() {
ret = e.codegen(data);
}
ret
}
ref e => {
println!("Unimplemented {:?}", e);
unimplemented!()
}
} }
} }
} }

View File

@ -142,6 +142,11 @@ pub fn BuildCondBr(builder: LLVMBuilderRef,
unsafe { core::LLVMBuildCondBr(builder, if_expr, then_expr, else_expr) } unsafe { core::LLVMBuildCondBr(builder, if_expr, then_expr, else_expr) }
} }
pub fn BuildBr(builder: LLVMBuilderRef,
dest: LLVMBasicBlockRef) -> LLVMValueRef {
unsafe { core::LLVMBuildBr(builder, dest) }
}
pub fn BuildICmp(builder: LLVMBuilderRef, pub fn BuildICmp(builder: LLVMBuilderRef,
op: LLVMIntPredicate, op: LLVMIntPredicate,
lhs: LLVMValueRef, lhs: LLVMValueRef,