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