From 0b9dc113d1147c9aebd9387563019f8d93c9e7eb Mon Sep 17 00:00:00 2001
From: greg <greg.shuflin@protonmail.com>
Date: Tue, 10 Jan 2017 18:07:16 -0800
Subject: [PATCH] CLoser to working now

---
 compile.schala     | 10 +++++++---
 src/compilation.rs | 30 +++++++++++++++++++++++-------
 src/llvm_wrap.rs   |  5 +++++
 3 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/compile.schala b/compile.schala
index 42db015..9530579 100644
--- a/compile.schala
+++ b/compile.schala
@@ -1,5 +1,9 @@
-が = 80
 a = 1
-b = 2
-a + b + が
+if a {
+ a = 40
+} else {
+ a = 2
+}
 
+a = a - 1
+a
diff --git a/src/compilation.rs b/src/compilation.rs
index 99a9ba0..e2490a4 100644
--- a/src/compilation.rs
+++ b/src/compilation.rs
@@ -19,6 +19,7 @@ pub fn compilation_sequence(ast: AST, sourcefile: &str) {
     };
 
     compile_ast(ast, ll_filename);
+    println!("YOLO");
     Command::new("llc")
         .arg("-filetype=obj")
         .arg(ll_filename)
@@ -31,6 +32,7 @@ pub fn compilation_sequence(ast: AST, sourcefile: &str) {
         .output()
         .expect("failed to run gcc");
 
+    println!("ai");
     for filename in [obj_filename].iter() {
         Command::new("rm")
             .arg(filename)
@@ -46,6 +48,7 @@ struct CompilationData {
     module: LLVMModuleRef,
     builder: LLVMBuilderRef,
     variables: VariableMap,
+    func: Option<LLVMValueRef>,
 }
 
 fn compile_ast(ast: AST, filename: &str) {
@@ -61,12 +64,15 @@ fn compile_ast(ast: AST, filename: &str) {
         module: module,
         builder: builder,
         variables: names,
+        func: None,
     };
 
     let int_type = LLVMWrap::Int64TypeInContext(data.context);
     let function_type = LLVMWrap::FunctionType(int_type, &Vec::new(), false);
     let function = LLVMWrap::AddFunction(data.module, "main", function_type);
 
+    data.func = Some(function);
+
     let bb = LLVMWrap::AppendBasicBlockInContext(data.context, function, "entry");
     LLVMWrap::PositionBuilderAtEnd(builder, bb);
 
@@ -74,6 +80,7 @@ fn compile_ast(ast: AST, filename: &str) {
 
     LLVMWrap::BuildRet(builder, value);
 
+    println!("Printing {} to file", filename);
     LLVMWrap::PrintModuleToFile(module, filename);
 
     // Clean up. Values created in the context mostly get cleaned up there.
@@ -123,10 +130,10 @@ impl CodeGen for Function {
 
 impl CodeGen for Expression {
     fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
-        println!("Running codegen on: {:?}", self);
         use self::Expression::*;
 
         let int_type = LLVMWrap::Int64TypeInContext(data.context);
+        let zero = LLVMWrap::ConstInt(int_type, 0, false);
 
         match *self {
             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) => {
                 let condition_value = test.codegen(data);
-                let zero = LLVMWrap::ConstInt(int_type, 0, false);
                 let is_nonzero =
                     LLVMWrap::BuildICmp(data.builder,
                                         llvm_sys::LLVMIntPredicate::LLVMIntNE,
@@ -168,7 +174,7 @@ impl CodeGen for Expression {
                                         zero,
                                         "is_nonzero");
 
-                let func: LLVMValueRef = zero;
+                let func: LLVMValueRef = data.func.expect("lol no function here");
                 let then_block =
                     LLVMWrap::AppendBasicBlockInContext(data.context, func, "entry");
                 let else_block =
@@ -179,15 +185,25 @@ impl CodeGen for Expression {
                 LLVMWrap::PositionBuilderAtEnd(data.builder, then_block);
                 let then_return = then_expr.codegen(data);
                 LLVMWrap::BuildBr(data.builder, merge_block);
-                let else_return = match else_expr {
-                    &Some(e) => e.codegen(data),
-                    &None => zero,
+                let else_return = match *else_expr {
+                    Some(ref e) => e.codegen(data),
+                    None => zero,
                 };
                 LLVMWrap::BuildBr(data.builder, merge_block);
                 LLVMWrap::PositionBuilderAtEnd(data.builder, else_block);
                 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!()
+            }
         }
     }
 }
diff --git a/src/llvm_wrap.rs b/src/llvm_wrap.rs
index ec15f21..5438fd5 100644
--- a/src/llvm_wrap.rs
+++ b/src/llvm_wrap.rs
@@ -142,6 +142,11 @@ pub fn BuildCondBr(builder: LLVMBuilderRef,
     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,
                  op: LLVMIntPredicate,
                  lhs: LLVMValueRef,
