From 4de029c7a653edcb09191ba77b114ae706c5a5b5 Mon Sep 17 00:00:00 2001
From: Peter Matta <mattapet@fit.cvut.cz>
Date: Mon, 23 Apr 2018 20:42:30 +0200
Subject: [PATCH] Fully working if-else flow control

---
 lib/IRGen/GenExpr.cpp | 74 ++++++++++++++++++++++++-------------------
 lib/IRGen/GenStmt.cpp |  1 +
 2 files changed, 42 insertions(+), 33 deletions(-)

diff --git a/lib/IRGen/GenExpr.cpp b/lib/IRGen/GenExpr.cpp
index c5ebced..8847f24 100644
--- a/lib/IRGen/GenExpr.cpp
+++ b/lib/IRGen/GenExpr.cpp
@@ -16,13 +16,17 @@
 using namespace dusk;
 using namespace irgen;
 
+llvm::Value *cast(llvm::Value *V, llvm::IRBuilder<> &B, llvm::Type *Ty) {
+  return B.CreateBitCast(V, Ty);
+}
+
 GenExpr::GenExpr(Expr *R, Context &C) : Root(R), Ctx(C) {}
 
 llvm::Value *GenExpr::gen() { return codegen(Root); }
 
 llvm::Value *GenExpr::codegen(NumberLiteralExpr *E) {
-  auto Value = llvm::APSInt::get(E->getValue());
-  return llvm::ConstantInt::get(Ctx, Value);
+  auto Ty = llvm::Type::getInt64Ty(Ctx);
+  return llvm::ConstantInt::get(Ty, E->getValue());
 }
 
 llvm::Value *GenExpr::codegen(IdentifierExpr *E) {
@@ -33,6 +37,7 @@ llvm::Value *GenExpr::codegen(IdentifierExpr *E) {
 llvm::Value *GenExpr::codegen(InfixExpr *E) {
   auto LHS = codegen(E->getLHS());
   auto RHS = codegen(E->getRHS());
+  auto Ty = llvm::Type::getInt64Ty(Ctx);
   if (!LHS || !RHS)
     return nullptr;
 
@@ -46,20 +51,22 @@ llvm::Value *GenExpr::codegen(InfixExpr *E) {
     return Ctx.Builder.CreateMul(LHS, RHS, "multmp");
   case tok::divide:
     return Ctx.Builder.CreateSDiv(LHS, RHS, "divtmp");
+  case tok::mod:
+    return Ctx.Builder.CreateSRem(LHS, RHS, "modtmp");
 
   // Logical operations
   case tok::equals:
-    return Ctx.Builder.CreateICmpEQ(LHS, RHS, "eqtmp");
+    return cast(Ctx.Builder.CreateICmpEQ(LHS, RHS, "eqtmp"), Ctx.Builder, Ty);
   case tok::nequals:
-    return Ctx.Builder.CreateICmpNE(LHS, RHS, "neqtmp");
+    return cast(Ctx.Builder.CreateICmpNE(LHS, RHS, "neqtmp"), Ctx.Builder, Ty);
   case tok::greater:
-    return Ctx.Builder.CreateICmpSGT(LHS, RHS, "gttmp");
+    return cast(Ctx.Builder.CreateICmpSGT(LHS, RHS, "gttmp"), Ctx.Builder, Ty);
   case tok::greater_eq:
-    return Ctx.Builder.CreateICmpSGE(LHS, RHS, "getmp");
+    return cast(Ctx.Builder.CreateICmpSGE(LHS, RHS, "getmp"), Ctx.Builder, Ty);
   case tok::less:
-    return Ctx.Builder.CreateICmpSLT(LHS, RHS, "lttmp");
+    return cast(Ctx.Builder.CreateICmpSLT(LHS, RHS, "lttmp"), Ctx.Builder, Ty);
   case tok::less_eq:
-    return Ctx.Builder.CreateICmpSLE(LHS, RHS, "letmp");
+    return cast(Ctx.Builder.CreateICmpSLE(LHS, RHS, "letmp"), Ctx.Builder, Ty);
 
   default:
     llvm_unreachable("Invalid infix operand");
@@ -68,17 +75,21 @@ llvm::Value *GenExpr::codegen(InfixExpr *E) {
 
 llvm::Value *GenExpr::codegen(PrefixExpr *E) {
   auto Val = codegen(E->getDest());
+  auto Ty = llvm::Type::getInt64Ty(Ctx);
   if (!Val)
     return nullptr;
 
   switch (E->getOp().getKind()) {
-    case tok::neg:
-      return Ctx.Builder.CreateNot(Val);
+  case tok::neg:
+    return cast(Ctx.Builder.CreateNot(Val), Ctx.Builder, Ty);
 
-      // TODO: fix unary minus
-    case tok::minus:
-    default:
-      llvm_unreachable("Invalid prefix operand");
+  case tok::minus: {
+    auto Ty = llvm::Type::getInt64Ty(Ctx);
+    auto Zero = llvm::ConstantInt::get(Ty, 0);
+    return Ctx.Builder.CreateSub(Zero, Val, "unary-subtmp");
+  }
+  default:
+    llvm_unreachable("Invalid prefix operand");
   }
 }
 
@@ -121,26 +132,23 @@ llvm::Value *GenExpr::codegen(CallExpr *E) {
   return Ctx.Builder.CreateCall(Fn, Args);
 }
 
-
 llvm::Value *GenExpr::codegen(Expr *E) {
   switch (E->getKind()) {
-    case ExprKind::NumberLiteral:
-      return codegen(static_cast<NumberLiteralExpr *>(E));
-    case ExprKind::Identifier:
-      return codegen(static_cast<IdentifierExpr *>(E));
-    case ExprKind::Paren:
-      return codegen(static_cast<ParenExpr *>(E)->getExpr());
-    case ExprKind::Assign:
-      return codegen(static_cast<AssignExpr *>(E));
-    case ExprKind::Infix:
-      return codegen(static_cast<InfixExpr *>(E));
-    case ExprKind::Prefix:
-      return codegen(static_cast<PrefixExpr *>(E));
-    case ExprKind::Call:
-      return codegen(static_cast<CallExpr *>(E));
-    case ExprKind::Subscript:
-      return codegen(static_cast<SubscriptExpr *>(E));
+  case ExprKind::NumberLiteral:
+    return codegen(static_cast<NumberLiteralExpr *>(E));
+  case ExprKind::Identifier:
+    return codegen(static_cast<IdentifierExpr *>(E));
+  case ExprKind::Paren:
+    return codegen(static_cast<ParenExpr *>(E)->getExpr());
+  case ExprKind::Assign:
+    return codegen(static_cast<AssignExpr *>(E));
+  case ExprKind::Infix:
+    return codegen(static_cast<InfixExpr *>(E));
+  case ExprKind::Prefix:
+    return codegen(static_cast<PrefixExpr *>(E));
+  case ExprKind::Call:
+    return codegen(static_cast<CallExpr *>(E));
+  case ExprKind::Subscript:
+    return codegen(static_cast<SubscriptExpr *>(E));
   }
 }
-
-
diff --git a/lib/IRGen/GenStmt.cpp b/lib/IRGen/GenStmt.cpp
index e1d0b03..f19b5c4 100644
--- a/lib/IRGen/GenStmt.cpp
+++ b/lib/IRGen/GenStmt.cpp
@@ -10,6 +10,7 @@
 #include "GenStmt.h"
 #include "GenDecl.h"
 #include "GenExpr.h"
+#include <iostream>
 
 using namespace dusk;
 using namespace irgen;
-- 
GitLab