aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGen.cc
diff options
context:
space:
mode:
author_ov4 <hausemasterstream@gmail.com>2026-02-02 08:45:01 +0000
committer_ov4 <hausemasterstream@gmail.com>2026-02-02 08:45:01 +0000
commit419420770c4545ea4010047ef2153004d4700eed (patch)
treebd19eed681dbb68ecb501b6cfc220c42a9803ef3 /lib/CodeGen/CodeGen.cc
parentecc0fc463ba54dd0cbe33bc14415f432eaa959de (diff)
Added REAL and BOOLEAN types, DIV and MOD operators
Diffstat (limited to 'lib/CodeGen/CodeGen.cc')
-rw-r--r--lib/CodeGen/CodeGen.cc110
1 files changed, 79 insertions, 31 deletions
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc
index bfbd8e0..da6b005 100644
--- a/lib/CodeGen/CodeGen.cc
+++ b/lib/CodeGen/CodeGen.cc
@@ -1,6 +1,7 @@
#include "cps/CodeGen.h"
#include "cps/ArrayHandler.h"
#include "llvm/IR/Verifier.h"
+#include "llvm/IR/Instructions.h"
#include "cps/Lexer.h"
using namespace llvm;
@@ -19,6 +20,11 @@ CodeGen::CodeGen() {
FuncGen = std::make_unique<FunctionGen>(*TheContext, *TheModule, *Builder, NamedValues);
+ IntHandler = std::make_unique<IntegerHandler>(*TheContext, *Builder, *TheModule, NamedValues);
+ RealHelper = std::make_unique<RealHandler>(*TheContext, *Builder, *TheModule, NamedValues);
+ BoolHandler = std::make_unique<BooleanHandler>(*TheContext, *Builder, *TheModule, NamedValues);
+ ArithHandler = std::make_unique<ArithmeticHandler>(*TheContext, *Builder);
+
SetupExternalFunctions();
}
@@ -32,7 +38,14 @@ void CodeGen::SetupExternalFunctions() {
ScanfFunc = TheModule->getOrInsertFunction("scanf", ScanfType);
PrintfFormatStr = Builder->CreateGlobalStringPtr("%lld\n", "fmt_nl", 0, TheModule.get());
+ PrintfFloatFormatStr = Builder->CreateGlobalStringPtr("%f\n", "fmt_flt", 0, TheModule.get());
+ PrintfStringFormatStr = Builder->CreateGlobalStringPtr("%s\n", "fmt_str", 0, TheModule.get());
+
ScanfFormatStr = Builder->CreateGlobalStringPtr("%lld", "fmt_in", 0, TheModule.get());
+ ScanfFloatFormatStr = Builder->CreateGlobalStringPtr("%lf", "fmt_in_flt", 0, TheModule.get());
+
+ TrueStr = Builder->CreateGlobalStringPtr("TRUE", "str_true", 0, TheModule.get());
+ FalseStr = Builder->CreateGlobalStringPtr("FALSE", "str_false", 0, TheModule.get());
Arrays->setupExternalFunctions();
}
@@ -65,8 +78,16 @@ void CodeGen::print() {
Value *CodeGen::emitExpr(ExprAST *Expr) {
if (!Expr) return nullptr;
- if (auto *Num = dynamic_cast<NumberExprAST*>(Expr)) {
- return ConstantInt::get(*TheContext, APInt(64, Num->getVal(), true));
+ if (auto *Num = dynamic_cast<IntegerExprAST*>(Expr)) {
+ return IntHandler->createLiteral(Num->getVal());
+ }
+
+ if (auto *Real = dynamic_cast<RealExprAST*>(Expr)) {
+ return RealHelper->createLiteral(Real->getVal());
+ }
+
+ if (auto *Bool = dynamic_cast<BooleanExprAST*>(Expr)) {
+ return BoolHandler->createLiteral(Bool->getVal());
}
if (auto *Var = dynamic_cast<VariableExprAST*>(Expr)) {
@@ -76,9 +97,9 @@ Value *CodeGen::emitExpr(ExprAST *Expr) {
return nullptr;
}
- return Builder->CreateLoad(Type::getInt64Ty(*TheContext), A, Var->getName().c_str());
+ Type *AllocType = cast<AllocaInst>(A)->getAllocatedType();
+ return Builder->CreateLoad(AllocType, A, Var->getName().c_str());
}
-
if (auto *ArrAcc = dynamic_cast<ArrayAccessExprAST*>(Expr)) {
return Arrays->emitArrayAccess(ArrAcc, *this);
@@ -89,23 +110,7 @@ Value *CodeGen::emitExpr(ExprAST *Expr) {
Value *R = emitExpr(Bin->getRHS());
if (!L || !R) return nullptr;
- switch (Bin->getOp()) {
- case '+': return Builder->CreateAdd(L, R, "addtmp");
- case '-': return Builder->CreateSub(L, R, "subtmp");
- case '*': return Builder->CreateMul(L, R, "multmp");
- case '/':
- RuntimeChecker->emitDivZeroCheck(R, Bin->getLine());
- 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;
- }
+ return ArithHandler->emitBinaryOp(Bin->getOp(), L, R, Bin->getLine());
}
if (auto *Call = dynamic_cast<CallExprAST*>(Expr)) {
@@ -150,6 +155,8 @@ void CodeGen::emitIfStmt(IfStmtAST *Stmt) {
if (CondV->getType()->isIntegerTy(64))
CondV = Builder->CreateICmpNE(CondV, ConstantInt::get(*TheContext, APInt(64, 0)), "ifcond");
+ if (CondV->getType()->isIntegerTy(1))
+ CondV = Builder->CreateICmpNE(CondV, ConstantInt::get(*TheContext, APInt(1, 0)), "ifcond");
Function *TheFunction = Builder->GetInsertBlock()->getParent();
BasicBlock *ThenBB = BasicBlock::Create(*TheContext, "then", TheFunction);
@@ -183,6 +190,8 @@ void CodeGen::emitWhileStmt(WhileStmtAST *Stmt) {
if (!CondV) return;
if (CondV->getType()->isIntegerTy(64))
CondV = Builder->CreateICmpNE(CondV, ConstantInt::get(*TheContext, APInt(64, 0)), "loopcond");
+ if (CondV->getType()->isIntegerTy(1))
+ CondV = Builder->CreateICmpNE(CondV, ConstantInt::get(*TheContext, APInt(1, 0)), "loopcond");
Builder->CreateCondBr(CondV, LoopBB, AfterBB);
@@ -215,6 +224,8 @@ void CodeGen::emitRepeatStmt(RepeatStmtAST *Stmt) {
if (CondV->getType()->isIntegerTy(64))
CondV = Builder->CreateICmpNE(CondV, ConstantInt::get(*TheContext, APInt(64, 0)), "untilcond");
+ if (CondV->getType()->isIntegerTy(1))
+ CondV = Builder->CreateICmpNE(CondV, ConstantInt::get(*TheContext, APInt(1, 0)), "untilcond");
Builder->CreateCondBr(CondV, AfterBB, LoopBB);
@@ -249,7 +260,7 @@ void CodeGen::emitForStmt(ForStmtAST *Stmt) {
bool isNegativeStep = false;
if (Stmt->getStep()) {
- if (auto *Num = dynamic_cast<NumberExprAST*>(Stmt->getStep())) {
+ if (auto *Num = dynamic_cast<IntegerExprAST*>(Stmt->getStep())) {
if (Num->getVal() < 0) isNegativeStep = true;
}
}
@@ -353,10 +364,12 @@ void CodeGen::emitStmt(StmtAST *Stmt) {
}
if (auto *Decl = dynamic_cast<DeclareStmtAST*>(Stmt)) {
- Function *TheFunction = Builder->GetInsertBlock()->getParent();
- AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Decl->getName());
- NamedValues[Decl->getName()] = Alloca;
- Builder->CreateStore(ConstantInt::get(*TheContext, APInt(64, 0)), Alloca);
+ if (Decl->getType() == "INTEGER") IntHandler->emitDeclare(Decl->getName());
+ else if (Decl->getType() == "REAL") RealHelper->emitDeclare(Decl->getName());
+ else if (Decl->getType() == "BOOLEAN") BoolHandler->emitDeclare(Decl->getName());
+ else {
+ fprintf(stderr, "Unknown type %s\n", Decl->getType().c_str());
+ }
}
else if (auto *Assign = dynamic_cast<AssignStmtAST*>(Stmt)) {
Value *Val = emitExpr(Assign->getExpr());
@@ -366,16 +379,41 @@ void CodeGen::emitStmt(StmtAST *Stmt) {
fprintf(stderr, "Error: Unknown variable name %s\n", Assign->getName().c_str());
return;
}
+
+ AllocaInst *AI = cast<AllocaInst>(Alloca);
+
+ if (AI->getAllocatedType() == Type::getDoubleTy(*TheContext) && Val->getType()->isIntegerTy(64)) {
+ Val = Builder->CreateSIToFP(Val, Type::getDoubleTy(*TheContext));
+ }
Builder->CreateStore(Val, Alloca);
}
}
else if (auto *In = dynamic_cast<InputStmtAST*>(Stmt)) {
Value *Alloca = NamedValues[In->getName()];
if (Alloca) {
+ AllocaInst *AI = cast<AllocaInst>(Alloca);
std::vector<Value*> Args;
- Args.push_back(ScanfFormatStr);
- Args.push_back(Alloca);
- Builder->CreateCall(ScanfFunc, Args);
+
+ if (AI->getAllocatedType()->isDoubleTy()) {
+ Args.push_back(ScanfFloatFormatStr);
+ Args.push_back(Alloca);
+ Builder->CreateCall(ScanfFunc, Args);
+ } else if (AI->getAllocatedType()->isIntegerTy(1)) {
+ AllocaInst *TempInt = CreateEntryBlockAlloca(Builder->GetInsertBlock()->getParent(), "tmp_bool_input");
+
+ Args.push_back(ScanfFormatStr);
+ Args.push_back(TempInt);
+ Builder->CreateCall(ScanfFunc, Args);
+
+ Value *Val = Builder->CreateLoad(Type::getInt64Ty(*TheContext), TempInt);
+ Value *BoolVal = Builder->CreateICmpNE(Val, ConstantInt::get(*TheContext, APInt(64, 0)), "bool_cast");
+
+ Builder->CreateStore(BoolVal, Alloca);
+ } else {
+ Args.push_back(ScanfFormatStr);
+ Args.push_back(Alloca);
+ Builder->CreateCall(ScanfFunc, Args);
+ }
}
}
else if (auto *Out = dynamic_cast<OutputStmtAST*>(Stmt)) {
@@ -385,8 +423,18 @@ void CodeGen::emitStmt(StmtAST *Stmt) {
Value *Val = emitExpr(Out->getExpr());
if (Val) {
std::vector<Value*> Args;
- Args.push_back(PrintfFormatStr);
- Args.push_back(Val);
+ if (Val->getType()->isDoubleTy()) {
+ Args.push_back(PrintfFloatFormatStr);
+ Args.push_back(Val);
+ } else if (Val->getType()->isIntegerTy(1)) {
+ Args.push_back(PrintfStringFormatStr);
+ Value *StrPtr = Builder->CreateSelect(Val, TrueStr, FalseStr);
+ Args.push_back(StrPtr);
+ } else {
+ Args.push_back(PrintfFormatStr);
+ Args.push_back(Val);
+ }
+
Builder->CreateCall(PrintfFunc, Args);
}
}