From 05c19789d5e1b5edd050ee97c19a8ab86ec9e0f6 Mon Sep 17 00:00:00 2001 From: ov-4 Date: Thu, 29 Jan 2026 11:13:05 +0000 Subject: Added half way of IF statement --- lib/CodeGen/CodeGen.cc | 132 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 94 insertions(+), 38 deletions(-) (limited to 'lib/CodeGen') diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc index 91339e0..0a946bf 100644 --- a/lib/CodeGen/CodeGen.cc +++ b/lib/CodeGen/CodeGen.cc @@ -1,5 +1,6 @@ #include "cps/CodeGen.h" #include "llvm/IR/Verifier.h" +#include "cps/Lexer.h" using namespace llvm; using namespace cps; @@ -40,47 +41,13 @@ void CodeGen::compile(const std::vector> &Statements) { Builder->SetInsertPoint(BB); for (const auto &Stmt : Statements) { - // DECLARE - if (auto *Decl = dynamic_cast(Stmt.get())) { - AllocaInst *Alloca = CreateEntryBlockAlloca(F, Decl->getName()); - NamedValues[Decl->getName()] = Alloca; - // 0 - Builder->CreateStore(ConstantInt::get(*TheContext, APInt(32, 0)), Alloca); - } - // ASSIGNMENT (x <- expr) - else if (auto *Assign = dynamic_cast(Stmt.get())) { - Value *Val = emitExpr(Assign->getExpr()); - if (Val) { - AllocaInst *Alloca = NamedValues[Assign->getName()]; - if (Alloca) Builder->CreateStore(Val, Alloca); - } - } - // INPUT - else if (auto *In = dynamic_cast(Stmt.get())) { - AllocaInst *Alloca = NamedValues[In->getName()]; - if (Alloca) { - std::vector Args; - Args.push_back(ScanfFormatStr); - Args.push_back(Alloca); - Builder->CreateCall(ScanfFunc, Args); - } - } - // OUTPUT - else if (auto *Out = dynamic_cast(Stmt.get())) { - Value *Val = emitExpr(Out->getExpr()); - - if (Val) { - // printf("%d\n", val) - std::vector Args; - Args.push_back(PrintfFormatStr); - Args.push_back(Val); - Builder->CreateCall(PrintfFunc, Args); - } - } + emitStmt(Stmt.get()); } // main return 0 - Builder->CreateRet(ConstantInt::get(*TheContext, APInt(32, 0))); + if (!Builder->GetInsertBlock()->getTerminator()) + Builder->CreateRet(ConstantInt::get(*TheContext, APInt(32, 0))); + verifyFunction(*F); } @@ -114,6 +81,12 @@ Value *CodeGen::emitExpr(ExprAST *Expr) { case '-': return Builder->CreateSub(L, R, "subtmp"); case '*': return Builder->CreateMul(L, R, "multmp"); case '/': return Builder->CreateSDiv(L, R, "divtmp"); + case tok_eq: return Builder->CreateICmpEQ(L, R, "eqtmp"); + case tok_ne: return Builder->CreateICmpNE(L, R, "netmp"); + case '<': return Builder->CreateICmpSLT(L, R, "slttmp"); + case '>': return Builder->CreateICmpSGT(L, R, "sgttmp"); + case tok_le: return Builder->CreateICmpSLE(L, R, "sletmp"); + case tok_ge: return Builder->CreateICmpSGE(L, R, "sgetmp"); default: fprintf(stderr, "Error: Invalid binary operator\n"); return nullptr; @@ -122,3 +95,86 @@ Value *CodeGen::emitExpr(ExprAST *Expr) { return nullptr; } + +void CodeGen::emitIfStmt(IfStmtAST *Stmt) { + Value *CondV = emitExpr(Stmt->getCond()); + if (!CondV) return; + + if (CondV->getType()->isIntegerTy(32)) { + CondV = Builder->CreateICmpNE(CondV, ConstantInt::get(*TheContext, APInt(32, 0)), "ifcond"); + } + + Function *TheFunction = Builder->GetInsertBlock()->getParent(); + + BasicBlock *ThenBB = BasicBlock::Create(*TheContext, "then", TheFunction); + BasicBlock *ElseBB = BasicBlock::Create(*TheContext, "else", TheFunction); + BasicBlock *MergeBB = BasicBlock::Create(*TheContext, "ifcont", TheFunction); + + Builder->CreateCondBr(CondV, ThenBB, ElseBB); + + Builder->SetInsertPoint(ThenBB); + for (const auto &S : Stmt->getThenStmts()) { + emitStmt(S.get()); + } + if (!Builder->GetInsertBlock()->getTerminator()) + Builder->CreateBr(MergeBB); + + Builder->SetInsertPoint(ElseBB); + + for (const auto &S : Stmt->getElseStmts()) { + emitStmt(S.get()); + } + if (!Builder->GetInsertBlock()->getTerminator()) + Builder->CreateBr(MergeBB); + + Builder->SetInsertPoint(MergeBB); +} + + +void CodeGen::emitStmt(StmtAST *Stmt) { + if (!Stmt) return; + + // DECLARE + if (auto *Decl = dynamic_cast(Stmt)) { + Function *TheFunction = Builder->GetInsertBlock()->getParent(); + AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Decl->getName()); + NamedValues[Decl->getName()] = Alloca; + Builder->CreateStore(ConstantInt::get(*TheContext, APInt(32, 0)), Alloca); + } + // ASSIGNMENT + else if (auto *Assign = dynamic_cast(Stmt)) { + Value *Val = emitExpr(Assign->getExpr()); + if (Val) { + AllocaInst *Alloca = NamedValues[Assign->getName()]; + if (!Alloca) { + fprintf(stderr, "Error: Unknown variable name %s\n", Assign->getName().c_str()); + return; + } + Builder->CreateStore(Val, Alloca); + } + } + // INPUT + else if (auto *In = dynamic_cast(Stmt)) { + AllocaInst *Alloca = NamedValues[In->getName()]; + if (Alloca) { + std::vector Args; + Args.push_back(ScanfFormatStr); + Args.push_back(Alloca); + Builder->CreateCall(ScanfFunc, Args); + } + } + // OUTPUT + else if (auto *Out = dynamic_cast(Stmt)) { + Value *Val = emitExpr(Out->getExpr()); + if (Val) { + std::vector Args; + Args.push_back(PrintfFormatStr); + Args.push_back(Val); + Builder->CreateCall(PrintfFunc, Args); + } + } + // IF + else if (auto *IfStmt = dynamic_cast(Stmt)) { + emitIfStmt(IfStmt); + } +} -- cgit v1.3.1-4-g156e