From 419420770c4545ea4010047ef2153004d4700eed Mon Sep 17 00:00:00 2001 From: _ov4 Date: Mon, 2 Feb 2026 08:45:01 +0000 Subject: Added REAL and BOOLEAN types, DIV and MOD operators --- lib/CodeGen/ArithmeticHandler.cc | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 lib/CodeGen/ArithmeticHandler.cc (limited to 'lib/CodeGen/ArithmeticHandler.cc') diff --git a/lib/CodeGen/ArithmeticHandler.cc b/lib/CodeGen/ArithmeticHandler.cc new file mode 100644 index 0000000..762f0a3 --- /dev/null +++ b/lib/CodeGen/ArithmeticHandler.cc @@ -0,0 +1,67 @@ +#include "cps/ArithmeticHandler.h" +#include + +using namespace llvm; +using namespace cps; + +Value *ArithmeticHandler::emitBinaryOp(int Op, Value *LHS, Value *RHS, int Line) { + bool LIsInt = LHS->getType()->isIntegerTy(64); + bool RIsInt = RHS->getType()->isIntegerTy(64); + bool LIsDouble = LHS->getType()->isDoubleTy(); + bool RIsDouble = RHS->getType()->isDoubleTy(); + + if (Op == '/') { + Value *LVal = LHS; + Value *RVal = RHS; + if (LIsInt) LVal = Builder.CreateSIToFP(LHS, Type::getDoubleTy(Context)); + if (RIsInt) RVal = Builder.CreateSIToFP(RHS, Type::getDoubleTy(Context)); + + // TODO: DIV divide by 0 runtime check + return Builder.CreateFDiv(LVal, RVal, "divtmp"); + } + + // DIV / MOD : Only Integer. + if (Op == tok_div || Op == tok_mod) { + if (!LIsInt || !RIsInt) { + fprintf(stderr, "Error: DIV and MOD operators require INTEGER operands.\n"); + return nullptr; + } + if (Op == tok_div) return Builder.CreateSDiv(LHS, RHS, "div_int_tmp"); + if (Op == tok_mod) return Builder.CreateSRem(LHS, RHS, "mod_tmp"); + } + + if (LIsDouble || RIsDouble) { + Value *LVal = LHS; + Value *RVal = RHS; + if (LIsInt) LVal = Builder.CreateSIToFP(LHS, Type::getDoubleTy(Context)); + if (RIsInt) RVal = Builder.CreateSIToFP(RHS, Type::getDoubleTy(Context)); + + switch (Op) { + case '+': return Builder.CreateFAdd(LVal, RVal, "addtmp"); + case '-': return Builder.CreateFSub(LVal, RVal, "subtmp"); + case '*': return Builder.CreateFMul(LVal, RVal, "multmp"); + + case tok_eq: return Builder.CreateFCmpOEQ(LVal, RVal, "eqtmp"); + case tok_ne: return Builder.CreateFCmpONE(LVal, RVal, "netmp"); + case '<': return Builder.CreateFCmpOLT(LVal, RVal, "slttmp"); + case '>': return Builder.CreateFCmpOGT(LVal, RVal, "sgttmp"); + case tok_le: return Builder.CreateFCmpOLE(LVal, RVal, "sletmp"); + case tok_ge: return Builder.CreateFCmpOGE(LVal, RVal, "sgetmp"); + } + } else { + switch (Op) { + case '+': return Builder.CreateAdd(LHS, RHS, "addtmp"); + case '-': return Builder.CreateSub(LHS, RHS, "subtmp"); + case '*': return Builder.CreateMul(LHS, RHS, "multmp"); + + case tok_eq: return Builder.CreateICmpEQ(LHS, RHS, "eqtmp"); + case tok_ne: return Builder.CreateICmpNE(LHS, RHS, "netmp"); + case '<': return Builder.CreateICmpSLT(LHS, RHS, "slttmp"); + case '>': return Builder.CreateICmpSGT(LHS, RHS, "sgttmp"); + case tok_le: return Builder.CreateICmpSLE(LHS, RHS, "sletmp"); + case tok_ge: return Builder.CreateICmpSGE(LHS, RHS, "sgetmp"); + } + } + + return nullptr; +} -- cgit v1.3.1-4-g156e